Test utilities for Yeoman generators providing a fluent API for setting up test environments and asserting generated content
npx @tessl/cli install tessl/npm-yeoman-test@10.1.0Yeoman Test provides comprehensive test utilities specifically designed for testing Yeoman generators. It offers a fluent, chainable API through RunContext for setting up test environments with customizable options, temporary directories, mocked generators, file system states, and simulated user inputs. The library includes powerful assertion methods through RunResult for verifying file creation, content validation, JSON structure testing, and generator behavior verification.
npm install --save-dev yeoman-testPeer Dependencies:
npm install --save-dev yeoman-generator@xxx yeoman-environment@xxximport helpers, { result } from "yeoman-test";For specific components:
import {
YeomanTest,
RunContext,
RunContextBase,
RunResult,
TestAdapter,
createHelpers,
context,
result
} from "yeoman-test";CommonJS:
const helpers = require("yeoman-test");
const { result, context, TestAdapter } = require("yeoman-test");Simple Generator Test:
import helpers, { result } from "yeoman-test";
describe("my-generator", () => {
beforeEach(async () => {
await helpers
.run("my-generator") // Generator namespace or path
.withOptions({ skipInstall: true })
.withAnswers({ projectName: "test-app" });
});
it("creates expected files", () => {
result.assertFile("package.json");
result.assertFileContent("package.json", '"name": "test-app"');
});
});Advanced Test Configuration:
import helpers, { result } from "yeoman-test";
describe("complex generator test", () => {
beforeEach(async () => {
await helpers
.run("my-generator")
.withFiles({
"existing.json": '{ "config": true }',
"templates/base.hbs": "Hello {{name}}"
})
.withYoRcConfig("my-generator", { theme: "dark" })
.withMockedGenerators(["sub-generator"])
.withSpawnMock();
});
it("composes with sub-generator", () => {
result.assertGeneratorComposed("sub-generator");
});
});Yeoman Test is built around several key components:
Core functionality for setting up and executing generator tests with a fluent, chainable API that supports configuration, mocking, and lifecycle management.
function run<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(
GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>,
settings?: RunContextSettings,
environmentOptions?: BaseEnvironmentOptions
): RunContext<GeneratorType>;
function create<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(
GeneratorOrNamespace: string | GetGeneratorConstructor<GeneratorType>,
settings?: RunContextSettings,
environmentOptions?: BaseEnvironmentOptions
): RunContext<GeneratorType>;
function prepareTemporaryDir(settings?: RunContextSettings): BasicRunContext;
interface RunContextSettings {
tmpdir?: boolean;
cwd?: string;
forwardCwd?: boolean;
autoCleanup?: boolean;
memFs?: Store<MemFsEditorFile>;
resolved?: string;
namespace?: string;
}Comprehensive assertion utilities for verifying file creation, content validation, JSON structure testing, and generator behavior with support for both individual and batch operations.
class RunResult<GeneratorType extends BaseGenerator = BaseGenerator> {
assertFile(path: string | string[]): void;
assertFileContent(file: string, reg: string | RegExp): void;
assertJsonFileContent(filename: string, content: Record<string, any>): void;
assertGeneratorComposed(generator: string): void;
getSnapshot(filter?: Function): Record<string, { contents: string; stateCleared: string }>;
}Utility functions for creating, mocking, and managing generators and test environments with support for dummy generators, mocked interactions, and environment configuration.
class YeomanTest {
createGenerator<GeneratorType>(name: string, options?: {
dependencies?: Dependency[];
localConfigOnly?: boolean;
}): Promise<GeneratorType>;
createDummyGenerator<GenParameter>(
Generator?: GetGeneratorConstructor<GenParameter>,
contents?: Record<string, Function>
): new (...args: any[]) => GenParameter;
createMockedGenerator(GeneratorClass?: any): ReturnType<typeof mock.fn>;
}
type Dependency = string | Parameters<DefaultEnvironmentApi['register']>;Functionality for creating and configuring Yeoman test environments with custom adapters, shared file systems, and environment-specific options.
class YeomanTest {
createEnv(options: BaseEnvironmentOptions): Promise<DefaultEnvironmentApi>;
createTestEnv(
environmentContructor?: CreateEnv,
options?: BaseEnvironmentOptions
): Promise<DefaultEnvironmentApi>;
createTestAdapter(options?: TestAdapterOptions): TestAdapter;
}
type CreateEnv = (options: BaseEnvironmentOptions) => Promise<BaseEnvironment>;Mock adapter for simulating user prompts and interactions with full control over question responses and prompt behavior.
class TestAdapter {
constructor(options?: TestAdapterOptions);
// Inherits from @yeoman/adapter TestAdapter
prompt<T extends PromptAnswers = PromptAnswers>(
questions: PromptQuestions<T>
): Promise<T>;
}
interface TestAdapterOptions {
mockedAnswers?: PromptAnswers;
callback?: DummyPromptCallback;
}
type DummyPromptCallback = (prompt: any) => any;Specialized hooks and utilities for seamless integration with Mocha test framework, providing automatic cleanup and context management.
export const mochaHooks: {
afterAll(): void;
};
// Import as:
import "yeoman-test/mocha-cleanup";The mocha-cleanup export provides automatic test cleanup when used with Mocha's global hooks feature.
Global context and result instances for simplified test access and state management.
// Global test context with manual control
const context: {
startNewContext(): void;
};
// Global result proxy for accessing the last RunResult
const result: RunResult;Usage Examples:
import { context, result } from "yeoman-test";
describe("sequential tests", () => {
beforeEach(() => {
context.startNewContext(); // Start fresh context
});
it("can access results globally", async () => {
await helpers.run("my-generator");
// result automatically refers to the last execution
result.assertFile("package.json");
});
});interface RunContextSettings {
/** Automatically run this generator in a tmp dir (default: true) */
tmpdir?: boolean;
/** Working directory for the test */
cwd?: string;
/** Original working directory before test */
oldCwd?: string;
/** Forward cwd to environment */
forwardCwd?: boolean;
/** Automatically cleanup after test */
autoCleanup?: boolean;
/** Memory file system instance */
memFs?: Store<MemFsEditorFile>;
/** 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;
}
interface RunResultOptions<GeneratorType extends BaseGenerator> {
generator: GeneratorType;
env: DefaultEnvironmentApi;
envOptions: BaseEnvironmentOptions;
cwd: string;
oldCwd: string;
memFs: Store<MemFsEditorFile>;
mockedGenerators: Record<string, BaseGenerator>;
spawnStub?: any;
settings: RunContextSettings;
helpers: YeomanTest;
askedQuestions: AskedQuestions;
}
type Dependency = string | Parameters<DefaultEnvironmentApi['register']>;
type AskedQuestions = Array<{ name: string; answer: any }>;
interface TestAdapterOptions {
mockedAnswers?: PromptAnswers;
callback?: DummyPromptCallback;
}
type DummyPromptCallback = (prompt: any) => any;
type MockedGeneratorFactory<GenParameter extends BaseGenerator = DefaultGeneratorApi> = (
GeneratorClass?: GetGeneratorConstructor<GenParameter>
) => GetGeneratorConstructor<GenParameter>;