import { EventEmitter } from 'node:events'; import { mock } from 'node:test'; import { type Store } from 'mem-fs'; import type { BaseEnvironmentOptions, BaseGenerator, GetGeneratorConstructor, GetGeneratorOptions, LookupOptions, PromptAnswers } from '@yeoman/types'; import { type MemFsEditor, type MemFsEditorFile } from 'mem-fs-editor'; import type { DefaultEnvironmentApi, DefaultGeneratorApi } from '../types/type-helpers.js'; import RunResult, { type RunResultOptions } from './run-result.js'; import { type CreateEnv as CreateEnvironment, type Dependency, type YeomanTest } from './helpers.js'; import { type AskedQuestions, type DummyPromptOptions, type TestAdapterOptions } from './adapter.js'; /** * Provides settings for creating a `RunContext`. */ export type RunContextSettings = { /** * Automatically run this generator in a tmp dir * @default true */ tmpdir?: boolean; cwd?: string; oldCwd?: string; forwardCwd?: boolean; autoCleanup?: boolean; memFs?: Store; /** * File path to the generator (only used if Generator is a constructor) */ resolved?: string; /** * Namespace (only used if Generator is a constructor) * @default 'gen:test' */ namespace?: string; }; type PromiseRunResult = Promise>; type MockedGeneratorFactory = (GeneratorClass?: GetGeneratorConstructor) => GetGeneratorConstructor; type EnvironmentOptions = BaseEnvironmentOptions & { createEnv?: CreateEnvironment; }; export declare class RunContextBase extends EventEmitter { readonly mockedGenerators: Record; env: DefaultEnvironmentApi; generator: GeneratorType; readonly settings: RunContextSettings; readonly envOptions: EnvironmentOptions; completed: boolean; targetDirectory?: string; editor: MemFsEditor; memFs: Store; spawnStub?: any; mockedGeneratorFactory: MockedGeneratorFactory; readonly askedQuestions: AskedQuestions; protected environmentPromise?: PromiseRunResult; private args; private options; private answers?; private readonly adapterOptions?; private keepFsState?; private readonly onGeneratorCallbacks; private readonly onTargetDirectoryCallbacks; private readonly onEnvironmentCallbacks; private readonly inDirCallbacks; private readonly Generator?; private readonly helpers; private readonly temporaryDir; private oldCwd?; private eventListenersSet; private envCB; private built; private ran; private errored; private readonly beforePrepareCallbacks; private environmentRun?; /** * This class provide a run context object to façade the complexity involved in setting * up a generator for testing * @constructor * @param Generator - Namespace or generator constructor. If the later * is provided, then namespace is assumed to be * 'gen:test' in all cases * @param settings * @return {this} */ constructor(generatorType?: string | GetGeneratorConstructor, settings?: RunContextSettings, environmentOptions?: EnvironmentOptions, helpers?: YeomanTest); /** * Run the generator on the environment and promises a RunResult instance. * @return {PromiseRunResult} Promise a RunResult instance. */ run(): PromiseRunResult; on(eventName: string | symbol, listener: (...arguments_: any[]) => void): this; /** * @deprecated * Clean the provided directory, then change directory into it * @param dirPath - Directory path (relative to CWD). Prefer passing an absolute * file path for predictable results * @param [cb] - callback who'll receive the folder path as argument * @return run context instance */ inDir(dirPath: string, callback?: (folderPath: string) => void): this; /** * Register an callback to prepare the destination folder. * @param [cb] - callback who'll receive the folder path as argument * @return this - run context instance */ doInDir(callback: (folderPath: string) => void): this; /** * @deprecated * Change directory without deleting directory content. * @param dirPath - Directory path (relative to CWD). Prefer passing an absolute * file path for predictable results * @return run context instance */ cd(dirPath: string): this; /** * Cleanup a temporary directory and change the CWD into it * * This method is called automatically when creating a RunContext. Only use it if you need * to use the callback. * * @param [cb] - callback who'll receive the folder path as argument * @return this - run context instance */ inTmpDir(callback?: (folderPath: string) => void): this; /** * Restore cwd to initial cwd. * @return {this} run context instance */ restore(): this; /** * Clean the directory used for tests inside inDir/inTmpDir * @param {Boolean} force - force directory cleanup for not tmpdir */ cleanup(): void; /** * Clean the directory used for tests inside inDir/inTmpDir * @param {Boolean} force - force directory cleanup for not tmpdir */ cleanupTemporaryDir(): void; /** * Clean the directory used for tests inside inDir/inTmpDir * @param force - force directory cleanup for not tmpdir */ cleanTestDirectory(force?: boolean): void; /** * TestAdapter options. */ withAdapterOptions(options: Omit): this; /** * Create an environment * * This method is called automatically when creating a RunContext. Only use it if you need * to use the callback. * * @param {Function} [cb] - callback who'll receive the folder path as argument * @return {this} run context instance */ withEnvironment(callback: any): this; /** * Customize enviroment run method. * * @param callback * @return {this} run context instance */ withEnvironmentRun(callback: (this: this, env: DefaultEnvironmentApi, gen: GeneratorType) => void): this; /** * Run lookup on the environment. * * @param lookups - lookup to run. */ withLookups(lookups: LookupOptions | LookupOptions[]): this; /** * Provide arguments to the run context * @param args - command line arguments as Array or space separated string */ withArguments(arguments_: string | string[]): this; /** * Provide options to the run context * @param {Object} options - command line options (e.g. `--opt-one=foo`) * @return {this} */ withOptions(options: Partial, 'env' | 'namespace' | 'resolved'>>): this; /** * @deprecated * Mock the prompt with dummy answers * @param answers - Answers to the prompt questions * @param options - Options or callback. * @param {Function} [options.callback] - Callback. * @param {Boolean} [options.throwOnMissingAnswer] - Throw if a answer is missing. * @return {this} */ withPrompts(answers: PromptAnswers, options?: Omit): this; /** * Mock answers for prompts * @param answers - Answers to the prompt questions * @param options - Options or callback. * @return {this} */ withAnswers(answers: PromptAnswers, options?: Omit): this; /** * Provide dependent generators * @param {Array} dependencies - paths to the generators dependencies * @return {this} * @example * var angular = new RunContext('../../app'); * angular.withGenerators([ * '../../common', * '../../controller', * '../../main', * [helpers.createDummyGenerator(), 'testacular:app'] * ]); * angular.on('end', function () { * // assert something * }); */ withGenerators(dependencies: Dependency[]): this; withSpawnMock>(options?: ((...arguments_: any[]) => any) | { stub?: (...arguments_: any[]) => any; registerNodeMockDefaults?: boolean; callback?: ({ stub, implementation }: { stub: StubType; implementation: any; }) => void | Promise; }): this; withMockedGeneratorFactory(mockedGeneratorFactory: MockedGeneratorFactory): this; /** * Create mocked generators * @param namespaces - namespaces of mocked generators * @return this * @example * var angular = helpers * .create('../../app') * .withMockedGenerators([ * 'foo:app', * 'foo:bar', * ]) * .run() * .then(runResult => assert(runResult * .mockedGenerators['foo:app'] .calledOnce)); */ withMockedGenerators(namespaces: string[]): this; /** * Mock the local configuration with the provided config * @param localConfig - should look just like if called config.getAll() */ withLocalConfig(localConfig: any): this; /** * Don't reset mem-fs state cleared to aggregate snapshots from multiple runs. */ withKeepFsState(): this; /** * Add files to mem-fs. * Files will be resolved relative to targetDir. * * Files with Object content will be merged to existing content. * To avoid merging, `JSON.stringify` the content. */ withFiles(files: Record>): this; withFiles(relativePath: string, files: Record>): this; /** * Add .yo-rc.json to mem-fs. * * @param content * @returns */ withYoRc(content: string | Record): this; /** * Add a generator config to .yo-rc.json */ withYoRcConfig(key: string, content: Record): this; /** * Commit mem-fs files. */ commitFiles(): this; /** * Execute callback after targetDirectory is set * @param callback * @returns */ onTargetDirectory(callback: (this: this, targetDirectory: string) => any): this; /** * Execute callback after generator is ready * @param callback * @returns */ onGenerator(callback: (this: this, generator: GeneratorType) => any): this; /** * Execute callback prefore parepare * @param callback * @returns */ onBeforePrepare(callback: (this: this) => void | Promise): this; /** * Execute callback after environment is ready * @param callback * @returns */ onEnvironment(callback: (this: this, environment: DefaultEnvironmentApi) => any): this; prepare(): Promise; protected assertNotBuild(): void; /** * Build the generator and the environment. * @return {RunContext|false} this */ build(): Promise; /** * Return a promise representing the generator run process * @return Promise resolved on end or rejected on error */ protected toPromise(): PromiseRunResult; protected _createRunResultOptions(): RunResultOptions; /** * Keeps compatibility with events */ private setupEventListeners; /** * Set the target directory. * @private * @param {String} dirPath - Directory path (relative to CWD). Prefer passing an absolute * file path for predictable results * @return {this} run context instance */ private setDir; } export default class RunContext extends RunContextBase implements Promise> { then, TResult2 = never>(onfulfilled?: ((value: RunResult) => TResult1 | PromiseLike) | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined): Promise; catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined): Promise | TResult>; finally(onfinally?: (() => void) | undefined): Promise>; get [Symbol.toStringTag](): string; } export declare class BasicRunContext extends RunContext { run(): PromiseRunResult; } export {};