refactor: change PromptEvent reject/resolve to cancel/tryCommit
This commit is contained in:
@@ -296,7 +296,8 @@ describe('prompt', () => {
|
||||
expect(promptEvent).not.toBeNull();
|
||||
|
||||
const parsed = { name: 'select', params: ['Ace'], options: {}, flags: {} };
|
||||
promptEvent!.resolve(parsed);
|
||||
const error = promptEvent!.tryCommit(parsed);
|
||||
expect(error).toBeNull();
|
||||
|
||||
const result = await runPromise;
|
||||
expect(result.success).toBe(true);
|
||||
@@ -336,7 +337,7 @@ describe('prompt', () => {
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
expect(promptEvent).not.toBeNull();
|
||||
|
||||
promptEvent!.reject(new Error('user cancelled'));
|
||||
promptEvent!.cancel('user cancelled');
|
||||
|
||||
const result = await runPromise;
|
||||
expect(result.success).toBe(true);
|
||||
@@ -373,7 +374,8 @@ describe('prompt', () => {
|
||||
expect(promptEvent).not.toBeNull();
|
||||
expect(promptEvent!.schema.name).toBe('pick');
|
||||
|
||||
promptEvent!.resolve({ name: 'pick', params: ['sword'], options: {}, flags: {} });
|
||||
const error = promptEvent!.tryCommit({ name: 'pick', params: ['sword'], options: {}, flags: {} });
|
||||
expect(error).toBeNull();
|
||||
|
||||
const result = await runPromise;
|
||||
expect(result.success).toBe(true);
|
||||
@@ -410,13 +412,15 @@ describe('prompt', () => {
|
||||
expect(promptEvents.length).toBe(1);
|
||||
expect(promptEvents[0].schema.name).toBe('first');
|
||||
|
||||
promptEvents[0].resolve({ name: 'first', params: ['one'], options: {}, flags: {} });
|
||||
const error1 = promptEvents[0].tryCommit({ name: 'first', params: ['one'], options: {}, flags: {} });
|
||||
expect(error1).toBeNull();
|
||||
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
expect(promptEvents.length).toBe(2);
|
||||
expect(promptEvents[1].schema.name).toBe('second');
|
||||
|
||||
promptEvents[1].resolve({ name: 'second', params: ['two'], options: {}, flags: {} });
|
||||
const error2 = promptEvents[1].tryCommit({ name: 'second', params: ['two'], options: {}, flags: {} });
|
||||
expect(error2).toBeNull();
|
||||
|
||||
const result = await runPromise;
|
||||
expect(result.success).toBe(true);
|
||||
@@ -424,4 +428,93 @@ describe('prompt', () => {
|
||||
expect(result.result).toEqual(['one', 'two']);
|
||||
}
|
||||
});
|
||||
|
||||
it('should validate input with validator function', async () => {
|
||||
const registry = createCommandRegistry<TestContext>();
|
||||
|
||||
const chooseRunner: CommandRunner<TestContext, string> = {
|
||||
schema: parseCommandSchema('choose'),
|
||||
run: async function () {
|
||||
const result = await this.prompt(
|
||||
'select <card>',
|
||||
(cmd) => {
|
||||
const card = cmd.params[0] as string;
|
||||
if (!['Ace', 'King', 'Queen'].includes(card)) {
|
||||
return `Invalid card: ${card}. Must be Ace, King, or Queen.`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
return result.params[0] as string;
|
||||
},
|
||||
};
|
||||
|
||||
registerCommand(registry, chooseRunner);
|
||||
|
||||
const ctx = { counter: 0, log: [] };
|
||||
let promptEvent: PromptEvent | null = null;
|
||||
|
||||
const runnerCtx = createCommandRunnerContext(registry, ctx);
|
||||
runnerCtx.on('prompt', (e) => {
|
||||
promptEvent = e;
|
||||
});
|
||||
|
||||
const runPromise = runnerCtx.run('choose');
|
||||
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
expect(promptEvent).not.toBeNull();
|
||||
|
||||
// Try invalid input
|
||||
const invalidError = promptEvent!.tryCommit({ name: 'select', params: ['Jack'], options: {}, flags: {} });
|
||||
expect(invalidError).toContain('Invalid card: Jack');
|
||||
|
||||
// Try valid input
|
||||
const validError = promptEvent!.tryCommit({ name: 'select', params: ['Ace'], options: {}, flags: {} });
|
||||
expect(validError).toBeNull();
|
||||
|
||||
const result = await runPromise;
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.result).toBe('Ace');
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow cancel with custom reason', async () => {
|
||||
const registry = createCommandRegistry<TestContext>();
|
||||
|
||||
const chooseRunner: CommandRunner<TestContext, string> = {
|
||||
schema: parseCommandSchema('choose'),
|
||||
run: async function () {
|
||||
try {
|
||||
await this.prompt('select <card>');
|
||||
return 'unexpected success';
|
||||
} catch (e) {
|
||||
return (e as Error).message;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
registerCommand(registry, chooseRunner);
|
||||
|
||||
const ctx = { counter: 0, log: [] };
|
||||
let promptEvent: PromptEvent | null = null;
|
||||
|
||||
const runnerCtx = createCommandRunnerContext(registry, ctx);
|
||||
runnerCtx.on('prompt', (e) => {
|
||||
promptEvent = e;
|
||||
});
|
||||
|
||||
const runPromise = runnerCtx.run('choose');
|
||||
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
expect(promptEvent).not.toBeNull();
|
||||
|
||||
promptEvent!.cancel('custom cancellation reason');
|
||||
|
||||
const result = await runPromise;
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.result).toBe('custom cancellation reason');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user