mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
feat: add run command
This commit is contained in:
1 parent
e622011b21
commit
dae9e841ca
3 files changed
+77
-9
No files matched your search
@@ -1,11 +1,16 @@
|
|||||||
|
/* eslint-disable no-await-in-loop */
|
||||||
import { IQuest, IStage } from './schema'
|
import { IQuest, IStage } 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[]
|
||||||
private quest: IQuest
|
private quest: IQuest
|
||||||
|
|
||||||
constructor(quest: IQuest) {
|
constructor(
|
||||||
|
quest: IQuest,
|
||||||
|
private checker: IFileExistenceChecker
|
||||||
|
) {
|
||||||
this.quest = quest
|
this.quest = quest
|
||||||
this.stages = quest.stages.map((stage: IStage) => new Stage(stage))
|
this.stages = quest.stages.map((stage: IStage) => new Stage(stage))
|
||||||
}
|
}
|
||||||
@@ -13,4 +18,18 @@ export class Quest {
|
|||||||
getActiveStages(completed: string[]) {
|
getActiveStages(completed: string[]) {
|
||||||
return this.stages.filter((stage) => stage.active(completed))
|
return this.stages.filter((stage) => stage.active(completed))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findSatisfiedStage(
|
||||||
|
command: ICommand,
|
||||||
|
completed: string[]
|
||||||
|
): Promise<string | null> {
|
||||||
|
const stages = this.getActiveStages(completed)
|
||||||
|
for (const stage of stages) {
|
||||||
|
const satisfies = await stage.satisfies(command, this.checker)
|
||||||
|
if (satisfies) {
|
||||||
|
return stage.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
import { Quest } from './Quest'
|
import { Quest } from './Quest'
|
||||||
import { IQuest } from './schema'
|
import { IQuest } from './schema'
|
||||||
import { ISession } from './types'
|
import { ICommand, ISession, IFileExistenceChecker } from './types'
|
||||||
|
|
||||||
export class Session implements ISession {
|
export class Session implements ISession {
|
||||||
private completed: string[] = []
|
private completed: string[] = []
|
||||||
private quest: Quest
|
private quest: Quest
|
||||||
|
|
||||||
constructor({ completedStages }: ISession, quest: IQuest) {
|
constructor(
|
||||||
|
{ completedStages }: ISession,
|
||||||
|
quest: IQuest,
|
||||||
|
checker: IFileExistenceChecker
|
||||||
|
) {
|
||||||
this.completed = completedStages
|
this.completed = completedStages
|
||||||
this.quest = new Quest(quest)
|
this.quest = new Quest(quest, checker)
|
||||||
}
|
}
|
||||||
|
|
||||||
get completedStages() {
|
get completedStages() {
|
||||||
@@ -22,4 +26,12 @@ export class Session implements ISession {
|
|||||||
getActiveStages(): string[] {
|
getActiveStages(): string[] {
|
||||||
return this.quest.getActiveStages(this.completed).map((stage) => stage.id)
|
return this.quest.getActiveStages(this.completed).map((stage) => stage.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async runCommand(command: ICommand) {
|
||||||
|
const stageId = await this.quest.findSatisfiedStage(command, this.completed)
|
||||||
|
if (stageId) {
|
||||||
|
this.complete(stageId)
|
||||||
|
}
|
||||||
|
return stageId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { expect, describe, it } from '@jest/globals'
|
import { expect, describe, it } from '@jest/globals'
|
||||||
import { IQuest } from '../src/schema'
|
import { IQuest } from '../src/schema'
|
||||||
import { Session } from '../src/Session'
|
import { Session } from '../src/Session'
|
||||||
|
import { MockFileChecker } from './asyncCondition.test'
|
||||||
|
|
||||||
const quest: IQuest = {
|
const quest: IQuest = {
|
||||||
id: 'quest1',
|
id: 'quest1',
|
||||||
@@ -12,25 +13,33 @@ const quest: IQuest = {
|
|||||||
{
|
{
|
||||||
id: 'stage1',
|
id: 'stage1',
|
||||||
requirements: [],
|
requirements: [],
|
||||||
condition: {},
|
condition: {
|
||||||
|
command: 'echo start',
|
||||||
|
},
|
||||||
response: { type: 'narrative', content: 'Narrative 1' },
|
response: { type: 'narrative', content: 'Narrative 1' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'stage2',
|
id: 'stage2',
|
||||||
requirements: ['stage1'],
|
requirements: ['stage1'],
|
||||||
condition: {},
|
condition: {
|
||||||
|
command: 'ls',
|
||||||
|
},
|
||||||
response: { type: 'narrative', content: 'Narrative 2' },
|
response: { type: 'narrative', content: 'Narrative 2' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'stage3',
|
id: 'stage3',
|
||||||
requirements: ['stage1'],
|
requirements: ['stage1'],
|
||||||
condition: {},
|
condition: {
|
||||||
|
command: 'mkdir hello',
|
||||||
|
},
|
||||||
response: { type: 'narrative', content: 'Narrative 3' },
|
response: { type: 'narrative', content: 'Narrative 3' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'stage4',
|
id: 'stage4',
|
||||||
requirements: ['stage2', 'stage3'],
|
requirements: ['stage2', 'stage3'],
|
||||||
condition: {},
|
condition: {
|
||||||
|
command: 'echo finish',
|
||||||
|
},
|
||||||
response: { type: 'narrative', content: 'Narrative 4' },
|
response: { type: 'narrative', content: 'Narrative 4' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -42,7 +51,8 @@ describe('Session', () => {
|
|||||||
{
|
{
|
||||||
completedStages: [],
|
completedStages: [],
|
||||||
},
|
},
|
||||||
quest
|
quest,
|
||||||
|
new MockFileChecker()
|
||||||
)
|
)
|
||||||
expect(session.getActiveStages()).toEqual(['stage1'])
|
expect(session.getActiveStages()).toEqual(['stage1'])
|
||||||
|
|
||||||
@@ -55,4 +65,31 @@ describe('Session', () => {
|
|||||||
session.complete('stage3')
|
session.complete('stage3')
|
||||||
expect(session.getActiveStages()).toEqual(['stage4'])
|
expect(session.getActiveStages()).toEqual(['stage4'])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should run command', async () => {
|
||||||
|
const session = new Session(
|
||||||
|
{
|
||||||
|
completedStages: [],
|
||||||
|
},
|
||||||
|
quest,
|
||||||
|
new MockFileChecker()
|
||||||
|
)
|
||||||
|
expect(await session.runCommand({ command: 'hi' })).toBeNull()
|
||||||
|
expect(await session.runCommand({ command: 'echo start' })).toEqual(
|
||||||
|
'stage1'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(await session.runCommand({ command: 'echo start' })).toBeNull()
|
||||||
|
expect(await session.runCommand({ command: 'ls' })).toEqual('stage2')
|
||||||
|
|
||||||
|
expect(await session.runCommand({ command: 'echo finish' })).toBeNull()
|
||||||
|
|
||||||
|
expect(await session.runCommand({ command: 'mkdir hello' })).toEqual(
|
||||||
|
'stage3'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(await session.runCommand({ command: 'echo finish' })).toEqual(
|
||||||
|
'stage4'
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
Reference in new issue
Block a user