CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-stryker-mutator--jest-runner

A plugin to use the jest test runner and framework in Stryker, the JavaScript mutation testing framework

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities

Core utility functions and wrapper classes for Jest integration, version handling, coverage validation, and configuration enhancement.

Capabilities

Jest Configuration Enhancement Functions

Functions that modify Jest configuration for Stryker-specific functionality including coverage analysis and hit limiting.

/**
 * Configures Jest config with coverage analysis support
 * Overrides test environment with Stryker-enhanced environment for coverage tracking
 * @param jestConfig - Base Jest configuration
 * @param coverageAnalysis - Coverage analysis mode ('off', 'all', or 'perTest')
 * @param jestWrapper - Jest wrapper for version detection
 * @returns Enhanced Jest configuration with coverage analysis setup
 */
export function withCoverageAnalysis(
  jestConfig: Config.InitialOptions,
  coverageAnalysis: CoverageAnalysis,
  jestWrapper: JestWrapper
): Config.InitialOptions;

/**
 * Configures Jest config with hit limit functionality
 * Prevents infinite loops during mutation testing by limiting execution counts
 * @param jestConfig - Base Jest configuration
 * @param hitLimit - Maximum number of hits before timeout (undefined disables)
 * @param jestWrapper - Jest wrapper for version detection
 * @returns Enhanced Jest configuration with hit limiting support
 */
export function withHitLimit(
  jestConfig: Config.InitialOptions,
  hitLimit: number | undefined,
  jestWrapper: JestWrapper
): Config.InitialOptions;

Usage Examples:

import { withCoverageAnalysis, withHitLimit } from "@stryker-mutator/jest-runner";

// Enable per-test coverage analysis
const configWithCoverage = withCoverageAnalysis(
  baseJestConfig,
  'perTest',
  jestWrapper
);

// Apply hit limit for mutation testing
const configWithHitLimit = withHitLimit(
  baseJestConfig,
  1000,
  jestWrapper
);

// Chain configuration enhancements
const enhancedConfig = withHitLimit(
  withCoverageAnalysis(baseJestConfig, 'perTest', jestWrapper),
  500,
  jestWrapper
);

Coverage Validation

Function that validates test coverage completeness for Stryker integration.

/**
 * Validates that all test files have coverage data from Stryker environment
 * Used to ensure proper integration between Jest and Stryker instrumenter
 * @param jestResult - Jest test execution results
 * @param testFilesWithStrykerEnvironment - Set of files that have Stryker integration
 * @returns Error message if validation fails, undefined if successful
 */
export function verifyAllTestFilesHaveCoverage(
  jestResult: AggregatedResult,
  testFilesWithStrykerEnvironment: Set<string>
): string | undefined;

Usage Example:

import { verifyAllTestFilesHaveCoverage } from "@stryker-mutator/jest-runner";

// Validate coverage after test execution
const errorMessage = verifyAllTestFilesHaveCoverage(
  jestExecutionResult,
  filesWithStrykerEnv
);

if (errorMessage) {
  // Handle coverage validation failure
  throw new Error(errorMessage);
}

Jest Wrapper Classes

Wrapper classes for Jest operations and configuration management.

/**
 * Wrapper for Jest operations and version detection
 * Provides abstraction over different Jest versions and capabilities
 */
export class JestWrapper {
  /**
   * Get the current Jest version
   * @returns Jest version string (e.g., "29.5.0")
   */
  getVersion(): string;
}

/**
 * Wrapper for Jest configuration loading and manipulation
 * Handles configuration resolution and merging
 */
export class JestConfigWrapper {
  // Implementation details depend on internal Jest configuration handling
}

Usage Examples:

import { JestWrapper, JestConfigWrapper } from "@stryker-mutator/jest-runner";

// Check Jest version for compatibility
const jestWrapper = new JestWrapper();
const version = jestWrapper.getVersion();
const isModern = semver.gte(version, '27.0.0');

// Use config wrapper for configuration handling  
const configWrapper = new JestConfigWrapper();
// Configuration operations handled internally

Jest Override Options

Constant defining default Jest configuration overrides applied by Stryker for optimal mutation testing performance.

/**
 * Default Jest configuration overrides for Stryker integration
 * Disables Jest features that interfere with or slow down mutation testing
 */
export const JEST_OVERRIDE_OPTIONS: Readonly<Config.InitialOptions>;

The override options include:

const JEST_OVERRIDE_OPTIONS = {
  // Prevent conflicts with Stryker's result processing
  testResultsProcessor: undefined,
  
  // Disable Jest's built-in coverage (Stryker handles coverage)
  collectCoverage: false,
  
  // Reduce output noise during mutation testing
  verbose: false,
  
  // Disable desktop notifications during testing
  notify: false,
  
  // Ensure all tests run (bail not supported programmatically)
  bail: false,
  
  // Disable default reporters for cleaner output
  reporters: [],
};

Dependency Injection Tokens

Token definitions for Stryker's dependency injection system used by the Jest runner.

/**
 * Dependency injection tokens for Jest runner components
 * Used by Stryker's plugin system for dependency resolution
 */
export const pluginTokens: {
  readonly requireFromCwd: 'requireFromCwd';
  readonly resolve: 'resolve';
  readonly resolveFromDirectory: 'resolveFromDirectory';
  readonly configLoader: 'configLoader';
  readonly processEnv: 'processEnv';
  readonly jestTestAdapter: 'jestTestAdapter';
  readonly globalNamespace: 'globalNamespace';
  readonly jestWrapper: 'jestWrapper';
  readonly jestConfigWrapper: 'jestConfigWrapper';
};

/**
 * Plugin context interface for dependency injection
 * Defines available dependencies for Jest runner components
 */
export interface JestPluginContext extends PluginContext {
  [pluginTokens.jestWrapper]: JestWrapper;
  [pluginTokens.resolve]: RequireResolve;
  [pluginTokens.requireFromCwd]: typeof requireResolve;
  [pluginTokens.processEnv]: typeof process.env;
  [pluginTokens.jestConfigWrapper]: JestConfigWrapper;
}

Usage Example:

// Used internally by Stryker's dependency injection system
// Typically not used directly by end users

// Example of how tokens are used in factory functions
function someFactory(
  jestWrapper: JestWrapper,
  configLoader: JestConfigLoader
) {
  // Factory implementation
}

someFactory.inject = tokens(
  pluginTokens.jestWrapper,
  pluginTokens.configLoader
);

Types

Configuration Enhancement Types

type CoverageAnalysis = 'off' | 'all' | 'perTest';

namespace Config {
  interface InitialOptions {
    testEnvironment?: string;
    testRunner?: string;
    setupFiles?: string[];
    setupFilesAfterEnv?: string[];
    testMatch?: string[];
    collectCoverage?: boolean;
    verbose?: boolean;
    notify?: boolean;
    bail?: boolean;
    reporters?: any[];
    globals?: { [key: string]: any };
    // ... other Jest configuration options
  }
}

Jest Result Types

import type { AggregatedResult } from '@jest/test-result';

// AggregatedResult contains complete Jest test execution results
// including test suites, individual test results, and coverage data

Utility Function Types

type RequireResolve = (id: string) => string;

interface PluginContext {
  // Base Stryker plugin context
}

Implementation Details

Environment Override Strategy

The configuration enhancement functions use a layered approach:

  1. Base Configuration: Start with user's Jest configuration
  2. Coverage Enhancement: Override test environment with Stryker-enhanced version
  3. Framework Setup: Configure appropriate test framework for coverage tracking
  4. Hit Limit Integration: Add hit counting capabilities when needed

Version Compatibility

The utilities handle Jest version differences:

  • Jest <27: Uses jest-jasmine2 test runner with custom setup files
  • Jest ≥27: Uses jest-circus test runner with event handlers
  • Automatic Detection: JestWrapper.getVersion() determines appropriate strategy

Coverage Validation Process

The coverage validation ensures proper Stryker integration:

  1. File Registration: Test files register with Stryker environment during execution
  2. Coverage Collection: Instrumenter tracks which tests execute which code
  3. Validation: Confirms all test files have proper Stryker environment integration
  4. Error Reporting: Provides detailed error messages for integration issues

Performance Optimizations

The override options are specifically chosen for mutation testing performance:

  • Disabled Coverage: Jest's built-in coverage conflicts with Stryker's instrumenter
  • No Reporters: Default reporters slow down test execution significantly
  • Quiet Output: Verbose logging creates unnecessary overhead
  • No Notifications: Desktop notifications interrupt automated testing workflows

Install with Tessl CLI

npx tessl i tessl/npm-stryker-mutator--jest-runner

docs

configuration.md

environment-integration.md

index.md

plugin-integration.md

test-runner.md

utilities.md

tile.json