Skip to content

Commit 126aa83

Browse files
authored
feat(adapter): add addAnswers support (#96)
1 parent 7eeb28a commit 126aa83

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

workspaces/adapter/src/testing/test-adapter.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const isValueSet = (type: string, answer: any) => {
4848
};
4949

5050
const createDummyPrompt = (options: DummyPromptOptions = {}) => {
51+
const { mockedAnswers = {}, callback = answer => answer, throwOnMissingAnswer = false } = options;
5152
return createPrompt<any, TestQuestion>((config, done) => {
52-
const { mockedAnswers = {}, callback = answer => answer, throwOnMissingAnswer = false } = options;
5353
let answer = mockedAnswers[config.name!];
5454

5555
if (!isValueSet(config.type, answer)) {
@@ -68,7 +68,7 @@ const createDummyPrompt = (options: DummyPromptOptions = {}) => {
6868
answer = true;
6969
}
7070
}
71-
done(callback(answer, { question: config, answers: { ...mockedAnswers, [config.name]: answer } }));
71+
done(callback(answer, { question: config, answers: { [config.name]: answer } }));
7272

7373
return config.message;
7474
});
@@ -86,14 +86,18 @@ export class TestAdapter<LogType extends Logger = Logger, SpyType = any> impleme
8686
diff: any & SpyType;
8787
log: LogType & SpyType;
8888
registerDummyPrompt: (promptName: string, customPromptOptions?: DummyPromptOptions) => PromptModule;
89+
readonly mockedAnswers: PromptAnswers;
90+
8991
private abortController = new AbortController();
9092
private readonly spyFactory: SpyFactory<SpyType>;
9193

9294
constructor(options: TestAdapterOptions<SpyType> = {}) {
9395
const {
9496
spyFactory = defaultConfig.spyFactory ?? (spyOptions => () => spyOptions.returns),
9597
log = defaultConfig.log ?? createLogger(),
96-
...promptOptions
98+
mockedAnswers,
99+
callback,
100+
throwOnMissingAnswer,
97101
} = options;
98102

99103
this.spyFactory = spyFactory;
@@ -104,10 +108,16 @@ export class TestAdapter<LogType extends Logger = Logger, SpyType = any> impleme
104108
signal: this.abortController.signal,
105109
});
106110

111+
this.mockedAnswers = {};
112+
this.addAnswers(mockedAnswers ?? {});
113+
107114
const actualRegisterPrompt = this.promptModule.registerPrompt.bind(this.promptModule);
108115

109116
this.registerDummyPrompt = (promptModuleName: string, customPromptOptions?: DummyPromptOptions) =>
110-
actualRegisterPrompt(promptModuleName, createDummyPrompt(customPromptOptions ?? promptOptions));
117+
actualRegisterPrompt(
118+
promptModuleName,
119+
createDummyPrompt({ callback, mockedAnswers: this.mockedAnswers, throwOnMissingAnswer, ...customPromptOptions }),
120+
);
111121

112122
this.promptModule.registerPrompt = (name: string) => this.registerDummyPrompt(name);
113123

@@ -151,4 +161,17 @@ export class TestAdapter<LogType extends Logger = Logger, SpyType = any> impleme
151161
): Promise<A> {
152162
return this.promptModule(questions, initialAnswers);
153163
}
164+
165+
/**
166+
* Add answers to the mocked answers.
167+
*/
168+
addAnswers(answers: PromptAnswers): void {
169+
// Copy properties using Object.getOwnPropertyDescriptor to preserve getters and setters
170+
for (const key in answers) {
171+
const descriptors = Object.getOwnPropertyDescriptor(answers, key);
172+
if (descriptors) {
173+
Object.defineProperty(this.mockedAnswers, key, descriptors);
174+
}
175+
}
176+
}
154177
}

workspaces/adapter/test/test-adapter.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ describe('TestAdapter', () => {
7070
respuesta: null,
7171
});
7272
});
73+
it('addAnswers adds answers to mockedAnswers', async () => {
74+
const adapter = new TestAdapter();
75+
76+
adapter.addAnswers({ respuesta: 'foo' });
77+
78+
await expect(adapter.prompt([{ name: 'respuesta', message: 'foo', type: 'list' }])).resolves.toMatchObject({ respuesta: 'foo' });
79+
expect(adapter.mockedAnswers).toMatchObject(expect.objectContaining({ respuesta: 'foo' }));
80+
});
81+
it('addAnswers supports getters', async () => {
82+
const adapter = new TestAdapter();
83+
84+
adapter.addAnswers({
85+
_orderedRespuestas: ['foo', 'bar'],
86+
get respuesta() {
87+
return this._orderedRespuestas.shift();
88+
},
89+
});
90+
91+
await expect(adapter.prompt([{ name: 'respuesta', message: 'foo', type: 'list' }])).resolves.toMatchObject({ respuesta: 'foo' });
92+
await expect(adapter.prompt([{ name: 'respuesta', message: 'foo', type: 'list' }])).resolves.toMatchObject({ respuesta: 'bar' });
93+
await expect(adapter.prompt([{ name: 'respuesta', message: 'foo', type: 'list' }])).resolves.toMatchObject({ respuesta: undefined });
94+
});
7395
});
7496
describe('#queue()', () => {
7597
it('should execute the callback', async () => {

0 commit comments

Comments
 (0)