Description
π Feature Proposal
Hi πββοΈ It's me again π .
We currently use this code to resolve the jest config programmatically:
const requireFromJest = createRequire(require.resolve('jest', { paths: [resolveFromDirectory] }));
const requireFromJestCli = createRequire(requireFromJest.resolve('jest-cli'));
const jestConfig = requireFromJestCli('jest-config');
const { config, configPath } = jestConfig.readInitialOptions();
However, this doesn't seem to resolve presets. I.e. this:
// jest.config.js
module.exports = { preset: 'jest-preset-angular' };
Results in { preset: 'jest-preset-angular' }
I would love a way to resolve the entire config inc presets and use that config to run jest.
Motivation
In StrykerJS, we're running jest programmatically in the @stryker-mutator/jest-runner
plugin. We need to wrap around the user's configured test environment because we need access to the global variables to report mutation coverage; we're using the workaround specified here: #7421 (comment)
To do that, we want to know which test environment the user configured. That way, we can override that test environment by a class that extends the user's test environment (a mixin class):
function mixinJestEnvironment(JestEnvironmentClass) {
class StrykerJestEnvironment extends JestEnvironmentClass {
constructor(config, context) {
super(config, context);
this.global.__stryker__ = globalThis.__stryker__; // coverage is reported on __stryker__
}
// ...
}
return StrykerJestEnvironment;
}
When the testEnvironment
is empty, we assume the default ("node"), which is incorrect when the preset would override to, say, "jsdom".
See also: stryker-mutator/stryker-js#4068
Example
Ideally, we would like to read the config for a project and use that in the runCLI
API (or similar API).
const requireFromJest = createRequire(require.resolve('jest', { paths: [process.cwd()] }));
const requireFromJestCli = createRequire(requireFromJest.resolve('jest-cli'));
const jest = requireFromJestCli('jest');
const jestConfig = requireFromJestCli('jest-config');
const { globalConfig, projectConfig} = jestConfig.readConfig(argv);
// Override the jest env
globalThis.originalJestEnv = projectConfig.testEnvironment ?? globalConfig.testEnvironment ?? 'node';
projectConfig.testEnvironment = 'stryker-jest-env';
const { results } = await jest.run(globalConfig, projectConfig);
Pitch
A proper programmatic API would help the mission for Jest as a Platform.