UNPKG

@stryker-mutator/jest-runner

Version:

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

83 lines (72 loc) 3.44 kB
import path from 'path'; import type { Config } from '@jest/types'; import { commonTokens, tokens } from '@stryker-mutator/api/plugin'; import { propertyPath, type requireResolve } from '@stryker-mutator/util'; import { Logger } from '@stryker-mutator/api/logging'; import { pluginTokens } from '../plugin-di.js'; import { JestRunnerOptionsWithStrykerOptions } from '../jest-runner-options-with-stryker-options.js'; import { state } from '../jest-plugins/messaging.cjs'; import { JestConfigLoader } from './jest-config-loader.js'; function isString(maybeString: unknown): maybeString is string { return typeof maybeString === 'string'; } export class ReactScriptsJestConfigLoader implements JestConfigLoader { public static inject = tokens(commonTokens.logger, pluginTokens.resolve, pluginTokens.processEnv, pluginTokens.requireFromCwd); constructor( private readonly log: Logger, private readonly resolve: RequireResolve, private readonly processEnvRef: NodeJS.ProcessEnv, private readonly requireFromCwd: typeof requireResolve ) {} public async loadConfig(): Promise<Config.InitialOptions> { try { // Create the React configuration for Jest const { config, reactScriptsLocation } = this.createJestConfig(); // Make sure that any jest environment plugins (i.e. jest-environment-jsdom) is loaded from the react-script module state.resolveFromDirectory = reactScriptsLocation; config.watchPlugins = config.watchPlugins?.filter(isString).map((watchPlugin) => this.resolve(watchPlugin, { paths: [reactScriptsLocation] })); this.setEnv(); return config; } catch (e) { if (this.isNodeErrnoException(e) && e.code === 'MODULE_NOT_FOUND') { throw Error( `Unable to locate package "react-scripts". This package is required when "${propertyPath<JestRunnerOptionsWithStrykerOptions>()( 'jest', 'projectType' )}" is set to "create-react-app".` ); } throw e; } } private isNodeErrnoException(arg: any): arg is NodeJS.ErrnoException { return arg.code !== undefined; } private createJestConfig(): { reactScriptsLocation: string; config: Config.InitialOptions } { const createReactJestConfig = this.requireFromCwd('react-scripts/scripts/utils/createJestConfig') as ( resolve: (thing: string) => string, rootDir: string, isEjecting: boolean ) => Config.InitialOptions; const reactScriptsLocation = path.join(this.resolve('react-scripts/package.json'), '..'); return { reactScriptsLocation, config: createReactJestConfig((relativePath) => path.join(reactScriptsLocation, relativePath), process.cwd(), false), }; } private setEnv() { // Jest CLI will set process.env.NODE_ENV to 'test' when it's null, do the same here // https://github.com/facebook/jest/blob/master/packages/jest-cli/bin/jest.js#L12-L14 if (!this.processEnvRef.NODE_ENV) { this.processEnvRef.NODE_ENV = 'test'; } try { this.requireFromCwd('react-scripts/config/env.js'); } catch (err) { this.log.warn( 'Unable to load environment variables using "react-scripts/config/env.js". The environment variables might differ from expected. Please open an issue if you think this is a bug: https://github.com/stryker-mutator/stryker-js/issues/new/choose.' ); this.log.debug('Inner error', err); } } }