test: reformat tests to use double quotes and improve style

This commit is contained in:
2026-04-20 15:16:03 +08:00
parent d5ec099540
commit 0c94e6923a
5 changed files with 1561 additions and 1449 deletions
File diff suppressed because it is too large Load Diff
+185 -163
View File
@@ -1,193 +1,215 @@
import { describe, it, expect } from 'vitest';
import { createGameContext, createGameCommandRegistry, createPromptDef, IGameContext, PromptDef } from '@/core/game';
import type { PromptEvent, Command } from '@/utils/command';
import { describe, it, expect } from "vitest";
import {
createGameContext,
createGameCommandRegistry,
createPromptDef,
IGameContext,
PromptDef,
} from "@/core/game";
import type {
PromptEvent,
Command,
CommandRunnerContext,
} from "@/utils/command";
type MyState = {
score: number;
round: number;
score: number;
round: number;
};
describe('createGameContext', () => {
it('should create a game context with state', () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
describe("createGameContext", () => {
it("should create a game context with state", () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
expect(ctx._state).not.toBeNull();
expect(ctx._state.value).toBeDefined();
expect(ctx._state).not.toBeNull();
expect(ctx._state.value).toBeDefined();
});
it("should wire commands to the context", () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
expect(ctx._commands).not.toBeNull();
expect(ctx._commands.registry).toBe(registry);
});
it("should accept initial state as an object", () => {
const registry = createGameCommandRegistry<MyState>();
const ctx = createGameContext<MyState>(registry, {
score: 0,
round: 1,
});
it('should wire commands to the context', () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
expect(ctx._state.value.score).toBe(0);
expect(ctx._state.value.round).toBe(1);
});
expect(ctx._commands).not.toBeNull();
expect(ctx._commands.registry).toBe(registry);
it("should accept initial state as a factory function", () => {
const registry = createGameCommandRegistry<MyState>();
const ctx = createGameContext<MyState>(registry, () => ({
score: 10,
round: 3,
}));
expect(ctx._state.value.score).toBe(10);
expect(ctx._state.value.round).toBe(3);
});
it("should forward prompt events via listener", async () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
registry.register(
"test <value>",
async function (this: CommandRunnerContext<IGameContext>, _ctx, value) {
return this.prompt(createPromptDef("prompt <answer>"), () => "ok");
},
);
const promptPromise = new Promise<PromptEvent>((resolve) => {
ctx._commands.on("prompt", resolve);
});
const runPromise = ctx.run("test hello");
it('should accept initial state as an object', () => {
const registry = createGameCommandRegistry<MyState>();
const ctx = createGameContext<MyState>(registry, {
score: 0,
round: 1,
});
const promptEvent = await promptPromise;
expect(promptEvent).not.toBeNull();
expect(promptEvent.schema.name).toBe("prompt");
expect(ctx._state.value.score).toBe(0);
expect(ctx._state.value.round).toBe(1);
const error = promptEvent.tryCommit({
name: "prompt",
params: ["yes"],
options: {},
flags: {},
});
expect(error).toBeNull();
it('should accept initial state as a factory function', () => {
const registry = createGameCommandRegistry<MyState>();
const ctx = createGameContext<MyState>(registry, () => ({
score: 10,
round: 3,
}));
expect(ctx._state.value.score).toBe(10);
expect(ctx._state.value.round).toBe(3);
});
it('should forward prompt events via listener', async () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
registry.register('test <value>', async function (_ctx, value) {
return this.prompt({schema: 'prompt <answer>'}, () => 'ok');
});
const promptPromise = new Promise<PromptEvent>(resolve => {
ctx._commands.on('prompt', resolve);
});
const runPromise = ctx.run('test hello');
const promptEvent = await promptPromise;
expect(promptEvent).not.toBeNull();
expect(promptEvent.schema.name).toBe('prompt');
const error = promptEvent.tryCommit({ name: 'prompt', params: ['yes'], options: {}, flags: {} });
expect(error).toBeNull();
const result = await runPromise;
expect(result.success).toBe(true);
});
const result = await runPromise;
expect(result.success).toBe(true);
});
});
describe('createGameCommand', () => {
it('should run a command with access to game context', async () => {
const registry = createGameCommandRegistry<{ marker: string }>();
registry.register('set-marker <id>', async function (ctx, id) {
ctx.produce(state => {
state.marker = id;
});
return id;
describe("createGameCommand", () => {
it("should run a command with access to game context", async () => {
const registry = createGameCommandRegistry<{ marker: string }>();
registry.register("set-marker <id>", async function (ctx, id) {
ctx.produce((state) => {
state.marker = id;
});
return id;
});
const ctx = createGameContext(registry, { marker: "" });
const result = await ctx.run("set-marker board");
if (!result.success) {
console.error("Error:", result.error);
}
expect(result.success).toBe(true);
if (result.success) {
expect(result.result).toBe("board");
}
expect(ctx._state.value.marker).toBe("board");
});
it("should run a typed command with extended context", async () => {
const registry = createGameCommandRegistry<MyState>();
registry.register(
"add-score <amount:number>",
async function (ctx, amount) {
ctx.produce((state) => {
state.score += amount;
});
return ctx.value.score;
},
);
const ctx = createGameContext(registry, { marker: '' });
const ctx = createGameContext<MyState>(registry, () => ({
score: 0,
round: 1,
}));
const result = await ctx.run('set-marker board');
if (!result.success) {
console.error('Error:', result.error);
}
expect(result.success).toBe(true);
if (result.success) {
expect(result.result).toBe('board');
}
expect(ctx._state.value.marker).toBe('board');
});
const result = await ctx.run("add-score 5");
expect(result.success).toBe(true);
if (result.success) {
expect(result.result).toBe(5);
}
expect(ctx._state.value.score).toBe(5);
});
it('should run a typed command with extended context', async () => {
const registry = createGameCommandRegistry<MyState>();
it("should return error for unknown command", async () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
registry.register(
'add-score <amount:number>',
async function (ctx, amount) {
ctx.produce(state => {
state.score += amount;
});
return ctx.value.score;
}
);
const ctx = createGameContext<MyState>(registry, () => ({
score: 0,
round: 1,
}));
const result = await ctx.run('add-score 5');
expect(result.success).toBe(true);
if (result.success) {
expect(result.result).toBe(5);
}
expect(ctx._state.value.score).toBe(5);
});
it('should return error for unknown command', async () => {
const registry = createGameCommandRegistry();
const ctx = createGameContext(registry);
const result = await ctx.run('nonexistent');
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error).toContain('nonexistent');
}
});
const result = await ctx.run("nonexistent");
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error).toContain("nonexistent");
}
});
});
describe('createPromptDef', () => {
it('should create a PromptDef with string schema', () => {
const promptDef = createPromptDef<[string, number]>('play <player> <score:number>');
describe("createPromptDef", () => {
it("should create a PromptDef with string schema", () => {
const promptDef = createPromptDef<[string, number]>(
"play <player> <score:number>",
);
expect(promptDef).toBeDefined();
expect(promptDef.schema.name).toBe('play');
expect(promptDef.schema.params).toHaveLength(2);
expect(promptDef.schema.params[0].name).toBe('player');
expect(promptDef.schema.params[1].name).toBe('score');
expect(promptDef).toBeDefined();
expect(promptDef.schema.name).toBe("play");
expect(promptDef.schema.params).toHaveLength(2);
expect(promptDef.schema.params[0].name).toBe("player");
expect(promptDef.schema.params[1].name).toBe("score");
});
it("should create a PromptDef with CommandSchema object", () => {
const schemaObj = {
name: "test",
params: [],
options: {},
flags: {},
};
const promptDef = createPromptDef<[]>(schemaObj);
expect(promptDef.schema).toEqual(schemaObj);
});
it("should be usable with game.prompt", async () => {
const registry = createGameCommandRegistry<{ score: number }>();
registry.register("test-prompt", async function (ctx) {
const promptDef = createPromptDef<[number]>("input <value:number>");
const result = await ctx.prompt(promptDef, (value) => {
if (value < 0) throw "Value must be positive";
return value;
});
return result;
});
it('should create a PromptDef with CommandSchema object', () => {
const schemaObj = {
name: 'test',
params: [],
options: {},
flags: {}
};
const promptDef = createPromptDef<[]>(schemaObj);
expect(promptDef.schema).toEqual(schemaObj);
const ctx = createGameContext(registry, { score: 0 });
const promptPromise = new Promise<PromptEvent>((resolve) => {
ctx._commands.on("prompt", resolve);
});
const runPromise = ctx.run("test-prompt");
it('should be usable with game.prompt', async () => {
const registry = createGameCommandRegistry<{ score: number }>();
registry.register('test-prompt', async function(ctx) {
const promptDef = createPromptDef<[number]>('input <value:number>');
const result = await ctx.prompt(
promptDef,
(value) => {
if (value < 0) throw 'Value must be positive';
return value;
}
);
return result;
});
const promptEvent = await promptPromise;
expect(promptEvent.schema.name).toBe("input");
const ctx = createGameContext(registry, { score: 0 });
const promptPromise = new Promise<PromptEvent>(resolve => {
ctx._commands.on('prompt', resolve);
});
const runPromise = ctx.run('test-prompt');
const promptEvent = await promptPromise;
expect(promptEvent.schema.name).toBe('input');
const error = promptEvent.tryCommit({ name: 'input', params: [42], options: {}, flags: {} });
expect(error).toBeNull();
const result = await runPromise;
expect(result.success).toBe(true);
if (result.success) {
expect(result.result).toBe(42);
}
const error = promptEvent.tryCommit({
name: "input",
params: [42],
options: {},
flags: {},
});
expect(error).toBeNull();
const result = await runPromise;
expect(result.success).toBe(true);
if (result.success) {
expect(result.result).toBe(42);
}
});
});