diff --git a/src/run-result.ts b/src/run-result.ts index f48538d..50c9596 100644 --- a/src/run-result.ts +++ b/src/run-result.ts @@ -6,7 +6,7 @@ import { type mock } from 'node:test'; import type { Store } from 'mem-fs'; import { type MemFsEditor, type MemFsEditorFile, create as createMemFsEditor } from 'mem-fs-editor'; import type { BaseEnvironmentOptions, BaseGenerator, GetGeneratorConstructor } from '@yeoman/types'; -import type { DefaultEnvironmentApi, DefaultGeneratorApi } from '../types/type-helpers.js'; +import type { DefaultEnvironmentApi } from '../types/type-helpers.js'; import { type RunContextSettings } from './run-context.js'; import { type YeomanTest } from './helpers.js'; import { type AskedQuestions } from './adapter.js'; @@ -103,8 +103,8 @@ export default class RunResult<GeneratorType extends BaseGenerator = BaseGenerat * Create another RunContext reusing the settings. * See helpers.create api */ - create<GeneratorType extends BaseGenerator = DefaultGeneratorApi>( - GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>, + create<G extends BaseGenerator = GeneratorType>( + GeneratorOrNamespace: string | GetGeneratorConstructor<G>, settings?: RunContextSettings, environmentOptions?: BaseEnvironmentOptions, ) { @@ -429,4 +429,61 @@ export default class RunResult<GeneratorType extends BaseGenerator = BaseGenerat assertNoJsonFileContent(filename: string, content: Record<string, any>): void { this.assertNoObjectContent(this._readFile(filename, true), content); } + + /** + * Get the generator mock + * @param generator - the namespace of the mocked generator + * @returns the generator mock + */ + getGeneratorMock(generator: string): ReturnType<typeof mock.fn>['mock'] { + const mockedGenerator: ReturnType<typeof mock.fn> = this.mockedGenerators[generator]; + if (!mockedGenerator) { + throw new Error(`Generator ${generator} is not mocked`); + } + return mockedGenerator.mock; + } + + /** + * Get the number of times a mocked generator was composed + * @param generator - the namespace of the mocked generator + * @returns the number of times the generator was composed + */ + getGeneratorComposeCount(generator: string): number { + return this.getGeneratorMock(generator).callCount(); + } + + /** + * Assert that a generator was composed + * @param generator - the namespace of the mocked generator + */ + assertGeneratorComposed(generator: string): void { + assert.ok(this.getGeneratorComposeCount(generator) > 0, `Generator ${generator} is not composed`); + } + + /** + * Assert that a generator was composed + * @param generator - the namespace of the mocked generator + */ + assertGeneratorNotComposed(generator: string): void { + const composeCount = this.getGeneratorComposeCount(generator); + assert.ok(composeCount === 0, `Generator ${generator} is composed ${composeCount}`); + } + + /** + * Assert that a generator was composed only once + * @param generator - the namespace of the mocked generator + */ + assertGeneratorComposedOnce(generator: string): void { + assert.ok(this.getGeneratorComposeCount(generator) === 1, `Generator ${generator} is not composed`); + } + + /** + * Assert that a generator was composed multiple times + * @returns an array of the names of the mocked generators that were composed + */ + getComposedGenerators(): string[] { + return Object.entries(this.mockedGenerators) + .filter(([_generator, mockedGenerator]) => (mockedGenerator as any).mock.callCount() > 0) + .map(([generator]) => generator); + } } diff --git a/test/run-result.spec.ts b/test/run-result.spec.ts index da10e9b..ab41ac4 100644 --- a/test/run-result.spec.ts +++ b/test/run-result.spec.ts @@ -266,4 +266,25 @@ describe('run-result', () => { } }); }); + + it('provides mocked generators check helpers', async () => { + const mockedNamespace = 'mocked:gen'; + const result = await helpers + .run( + helpers.createDummyGenerator(undefined, { + async default() { + await this.composeWith(mockedNamespace); + }, + }), + ) + .withMockedGenerators([mockedNamespace, 'another:gen']); + + result.assertGeneratorComposedOnce(mockedNamespace); + result.assertGeneratorComposed(mockedNamespace); + assert(result.getGeneratorComposeCount(mockedNamespace) === 1); + assert.equal(result.getComposedGenerators().length, 1); + assert(result.getComposedGenerators()[0] === mockedNamespace); + + result.assertGeneratorNotComposed('another:gen'); + }); });