CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-yeoman-test

Test utilities for Yeoman generators providing a fluent API for setting up test environments and asserting generated content

Overview
Eval results
Files

generator-helpers.mddocs/

Generator Testing Helpers

The YeomanTest class provides utility functions for creating, mocking, and managing generators and test environments. It supports dummy generators, mocked interactions, environment configuration, and both functional and class-based testing approaches.

Capabilities

Helper Instance Creation

Create customized helper instances with specific configurations.

/**
 * Create a customized YeomanTest instance with specific options
 * @param options - Configuration options to apply to the helper instance
 * @returns New YeomanTest instance with applied options
 */
function createHelpers(options: Partial<YeomanTest>): YeomanTest;

/**
 * Default YeomanTest instance available as default export
 */
const defaultHelpers: YeomanTest;

Usage Examples:

import { createHelpers } from "yeoman-test";

// Create helper with custom settings
const helpers = createHelpers({
  settings: { tmpdir: false },
  environmentOptions: { localConfigOnly: false },
  generatorOptions: { skipInstall: true }
});

// Use custom helper
await helpers.run("my-generator");

Generator Creation

Create generator instances with dependencies and configuration for testing.

/**
 * Create a generator instance with dependencies and options
 * @param name - Generator name or constructor
 * @param options - Configuration including dependencies and instantiation options
 * @returns Promise resolving to generator instance
 */
async createGenerator<GeneratorType extends BaseGenerator = DefaultGeneratorApi>(
  name: string | GetGeneratorConstructor<GeneratorType>,
  options?: {
    dependencies?: Dependency[];
    localConfigOnly?: boolean;
  } & InstantiateOptions<GeneratorType>
): Promise<GeneratorType>;

type Dependency = string | Parameters<DefaultEnvironmentApi['register']>;

Usage Examples:

import helpers from "yeoman-test";

// Create generator with dependencies
const generator = await helpers.createGenerator("my-generator", {
  dependencies: [
    "./path/to/dep-generator",
    ["./other-generator", { namespace: "other:gen" }]
  ],
  localConfigOnly: true,
  generatorArgs: ["init"],
  generatorOptions: { force: true }
});

// Use the generator instance
await generator.run();

Dummy Generator Creation

Create simple, customizable generators for testing scenarios.

/**
 * Create a simple, dummy generator for testing
 * @param Generator - Base generator class (defaults to yeoman-generator)
 * @param contents - Object defining methods and properties for the dummy generator
 * @returns Generator constructor that can be instantiated
 */
createDummyGenerator<GenParameter extends BaseGenerator = DefaultGeneratorApi>(
  Generator?: GetGeneratorConstructor<GenParameter>,
  contents?: Record<string, (...args: any[]) => void>
): new (...args: any[]) => GenParameter;

Usage Examples:

import helpers from "yeoman-test";

// Basic dummy generator
const DummyGen = helpers.createDummyGenerator();

// Custom dummy generator with methods
const CustomDummyGen = helpers.createDummyGenerator(undefined, {
  writing(this: any) {
    this.fs.write("output.txt", "Hello World");
  },
  
  install(this: any) {
    this.spawnCommand("npm", ["install"]);
  }
});

// Use in tests
await helpers.run(CustomDummyGen)
  .withSpawnMock();

result.assertFile("output.txt");

Mocked Generator Creation

Create fully mocked generators for testing generator composition.

/**
 * Create a mocked generator with stubbed methods
 * @param GeneratorClass - Base generator class to mock
 * @returns Mocked generator constructor with stubbed methods
 */
createMockedGenerator(GeneratorClass?: any): ReturnType<typeof mock.fn>;

Usage Examples:

import helpers from "yeoman-test";

// Create mocked generator
const MockedGen = helpers.createMockedGenerator();

// Use in test environment
const env = await helpers.createTestEnv();
env.register(MockedGen, { namespace: "mocked:gen" });

// Verify mock was called
expect(MockedGen.mock.callCount()).toBeGreaterThan(0);

Legacy Helper Methods (Deprecated)

Legacy methods maintained for backward compatibility.

/**
 * @deprecated Use inTmpDir from RunContext instead
 * Create a function that will clean up the test directory
 * @param dir - Path to the test directory
 * @returns Mocha callback function
 */
setUpTestDirectory(dir: string): () => void;

/**
 * @deprecated Use inTmpDir from RunContext instead
 * Clean-up the test directory and cd into it
 * @param dir - Path to the test directory
 * @param cb - Callback executed after setting working directory
 */
testDirectory(dir: string, callback?: (error?: any) => unknown): void;

/**
 * @deprecated Use withAnswers from RunContext instead
 * Answer prompt questions for the passed-in generator
 * @param generator - Yeoman generator or environment
 * @param answers - Object mapping prompt names to answers
 * @param options - Prompt options
 */
mockPrompt(
  environmentOrGenerator: BaseGenerator | DefaultEnvironmentApi,
  mockedAnswers?: PromptAnswers,
  options?: DummyPromptOptions
): void;

/**
 * @deprecated Use test cleanup methods instead
 * Restore defaults prompts on a generator
 * @param generator - Generator or environment instance
 */
restorePrompt(environmentOrGenerator: BaseGenerator | DefaultEnvironmentApi): void;

/**
 * @deprecated Use withLocalConfig from RunContext instead
 * Provide mocked values to the config
 * @param generator - Yeoman generator instance
 * @param localConfig - Configuration object
 */
mockLocalConfig(generator: BaseGenerator, localConfig: any): void;

YeomanTest Class Configuration

The YeomanTest class can be configured with default settings that apply to all test contexts created from that instance.

Instance Properties

class YeomanTest {
  /** Default settings for RunContext creation */
  settings?: RunContextSettings;
  
  /** Default environment options */
  environmentOptions?: BaseEnvironmentOptions;
  
  /** Default generator options */
  generatorOptions?: BaseGeneratorOptions;
  
  /** Default adapter options */
  adapterOptions?: Omit<TestAdapterOptions, 'mockedAnswers'>;
}

Usage Examples:

import { createHelpers } from "yeoman-test";

// Create configured helper instance
const helpers = createHelpers({
  settings: {
    tmpdir: true,
    autoCleanup: true
  },
  environmentOptions: {
    localConfigOnly: true,
    skipCache: true
  },
  generatorOptions: {
    skipInstall: true,
    force: true
  }
});

// All run contexts from this helper will use these defaults
await helpers.run("my-generator"); // Uses configured defaults

Method Override Pattern

YeomanTest methods can be overridden for custom behavior:

/**
 * Get RunContext constructor - can be overridden for custom context types
 * @returns RunContext constructor function
 */
getRunContextType(): typeof RunContext;

Usage Examples:

import { createHelpers, RunContext } from "yeoman-test";

// Custom RunContext with additional methods
class CustomRunContext extends RunContext {
  withCustomFeature() {
    // Add custom functionality
    return this;
  }
}

// Create helper with custom context type
const helpers = createHelpers({});
helpers.getRunContextType = () => CustomRunContext;

// Now all contexts will be CustomRunContext instances
const context = helpers.run("my-generator") as CustomRunContext;
context.withCustomFeature();

Advanced Usage Patterns

Generator Factory Pattern

// Create reusable generator factory
function createTestGenerator(options = {}) {
  return helpers.createDummyGenerator(undefined, {
    writing(this: any) {
      this.fs.writeJSON("package.json", {
        name: options.name || "test-app",
        version: options.version || "1.0.0"
      });
    }
  });
}

// Use in multiple tests
const TestGen = createTestGenerator({ name: "my-app" });
await helpers.run(TestGen);

Composition Testing Pattern

// Test generator that composes with others
await helpers.run("main-generator")
  .withMockedGenerators([
    "sub:component",
    "sub:service", 
    "common:utils"
  ]);

// Verify composition behavior
result.assertGeneratorComposed("sub:component");
result.assertGeneratorComposedOnce("common:utils");

const composedGens = result.getComposedGenerators();
expect(composedGens).toHaveLength(2);

Multi-Stage Testing Pattern

// Run initial generator
await helpers.run("init-generator")
  .withAnswers({ projectType: "library" });

// Run follow-up generator in same directory
await result.create("feature-generator")
  .withAnswers({ featureName: "auth" })
  .withLocalConfig({ initialized: true });

// Verify combined result
result.assertFile(["package.json", "src/auth.ts"]);

Install with Tessl CLI

npx tessl i tessl/npm-yeoman-test

docs

generator-helpers.md

index.md

run-context.md

run-result.md

test-adapter.md

test-environment.md

tile.json