feat: add get responses

This commit is contained in:
Justin Lin committed 2025-04-18 15:17:25 +08:00
1 parent dae9e841ca
commit f7780c3d98
9 files changed
+94 -54

No files matched your search

+13 -2
View File
@@ -1,7 +1,12 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
import { IQuest, IStage } from './schema' import {
IQuest,
IStage,
IFileExistenceChecker,
ICommand,
IResponse,
} from './schema'
import { Stage } from './Stage' import { Stage } from './Stage'
import { ICommand, IFileExistenceChecker } from './types'
export class Quest { export class Quest {
private stages: Stage[] private stages: Stage[]
@@ -32,4 +37,10 @@ export class Quest {
} }
return null return null
} }
getResponses(completed: string[]): IResponse[] {
return this.quest.stages
.filter((stage) => completed.includes(stage.id))
.map((stage) => stage.response)
}
} }
+11 -2
View File
@@ -1,6 +1,11 @@
import { Quest } from './Quest' import { Quest } from './Quest'
import { IQuest } from './schema' import {
import { ICommand, ISession, IFileExistenceChecker } from './types' IQuest,
ICommand,
ISession,
IFileExistenceChecker,
IResponse,
} from './schema'
export class Session implements ISession { export class Session implements ISession {
private completed: string[] = [] private completed: string[] = []
@@ -34,4 +39,8 @@ export class Session implements ISession {
} }
return stageId return stageId
} }
getResponses(): IResponse[] {
return this.quest.getResponses(this.completed)
}
} }
+1 -1
View File
@@ -1,4 +1,4 @@
import { IStage, ICommand, IFileExistenceChecker } from './types' import { IStage, ICommand, IFileExistenceChecker } from './schema'
import { Condition } from './condition/Condition' import { Condition } from './condition/Condition'
export class Stage { export class Stage {
+1 -2
View File
@@ -1,9 +1,8 @@
import { z } from 'zod' import { z } from 'zod'
import { FileType } from '../types.js'
export const fileInputSchema = z.object({ export const fileInputSchema = z.object({
path: z.string(), path: z.string(),
type: z.nativeEnum(FileType), type: z.enum(['file', 'folder']),
}) })
export type IFileInput = z.infer<typeof fileInputSchema> export type IFileInput = z.infer<typeof fileInputSchema>
+29
View File
@@ -3,3 +3,32 @@ export { stageSchema, IStage } from './stage.js'
export { requirementsSchema, IRequirements } from './requirements.js' export { requirementsSchema, IRequirements } from './requirements.js'
export { responseSchema, IResponse } from './response.js' export { responseSchema, IResponse } from './response.js'
export { questSchema, IQuest } from './quest.js' export { questSchema, IQuest } from './quest.js'
export interface ICommand {
command?: string
output?: string
error?: string
pwd?: string
}
export enum FileType {
FILE = 'file',
FOLDER = 'folder',
}
export interface FileInput {
path: string
type: FileType
}
export interface FileExistenceInput extends FileInput {
exists: boolean
}
export interface IFileExistenceChecker {
exists(file: FileInput): Promise<boolean>
}
export interface ISession {
completedStages: string[]
}
-45
View File
@@ -1,45 +0,0 @@
export interface ICommand {
command?: string
output?: string
error?: string
pwd?: string
}
export interface ICondition {
command?: string
output?: string
error?: string
pwd?: string
or?: ICondition[]
not?: ICondition
files?: FileExistenceInput[]
}
export enum FileType {
FILE = 'file',
FOLDER = 'folder',
}
export interface FileInput {
path: string
type: FileType
}
export interface FileExistenceInput extends FileInput {
exists: boolean
}
export interface IFileExistenceChecker {
exists(file: FileInput): Promise<boolean>
}
export interface IStage {
id: string
name?: string
requirements?: string[]
condition: ICondition
}
export interface ISession {
completedStages: string[]
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { test, expect } from '@jest/globals' import { test, expect } from '@jest/globals'
import { IFileExistenceChecker, FileType, FileInput } from '../src/types.js' import { IFileExistenceChecker, FileType, FileInput } from '../src/schema'
import { checkFiles } from '../src/condition/FileMatcher.js' import { checkFiles } from '../src/condition/FileMatcher.js'
import { Condition } from '../src/condition/Condition.js' import { Condition } from '../src/condition/Condition.js'
+22
View File
@@ -92,4 +92,26 @@ describe('Session', () => {
'stage4' 'stage4'
) )
}) })
it('should return responses', () => {
const session = new Session(
{
completedStages: ['stage1'],
},
quest,
new MockFileChecker()
)
expect(session.getResponses()).toEqual([
{
type: 'narrative',
content: 'Narrative 1',
},
])
session.complete('stage2')
expect(session.getResponses()).toEqual([
{ type: 'narrative', content: 'Narrative 1' },
{ type: 'narrative', content: 'Narrative 2' },
])
})
}) })
+16 -1
View File
@@ -1,6 +1,6 @@
import { test, expect } from '@jest/globals' import { test, expect } from '@jest/globals'
import { Stage } from '../src/Stage' import { Stage } from '../src/Stage'
import { FileType } from '../src/types' import { FileType } from '../src/schema'
import { MockFileChecker } from './asyncCondition.test' import { MockFileChecker } from './asyncCondition.test'
const checker = new MockFileChecker() const checker = new MockFileChecker()
@@ -13,6 +13,11 @@ test('check stage condition', async () => {
command: 'ls', command: 'ls',
pwd: '/home/user', pwd: '/home/user',
}, },
requirements: [],
response: {
type: 'narrative',
content: 'Narrative 1',
},
}) })
expect( expect(
await stage.satisfies( await stage.satisfies(
@@ -47,6 +52,11 @@ test('check stage with async condition truthy', async () => {
}, },
], ],
}, },
requirements: [],
response: {
type: 'narrative',
content: 'Narrative 1',
},
}) })
expect(await stage.satisfies({}, checker)).toBe(true) expect(await stage.satisfies({}, checker)).toBe(true)
}) })
@@ -64,6 +74,11 @@ test('check stage with async condition falsy', async () => {
}, },
], ],
}, },
requirements: [],
response: {
type: 'narrative',
content: 'Narrative 1',
},
}) })
expect(await stage.satisfies({}, checker)).toBe(false) expect(await stage.satisfies({}, checker)).toBe(false)
}) })