Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(jest): support more config file formats #3761

Merged
merged 12 commits into from Oct 29, 2022
Merged

fix(jest): support more config file formats #3761

merged 12 commits into from Oct 29, 2022

Conversation

nicojs
Copy link
Member

@nicojs nicojs commented Oct 3, 2022

Support all config file formats for jest using jest's native config reading (including jest.config.ts). See https://jestjs.io/docs/configuration for a list of all available config formats.

Stryker only uses jest's native functionality if it finds jest@>=29.2, otherwise, it falls back on its custom config file reading algorithm.

This also adds support for exporting an async function from your jest config file even for jest@<29.2, because of added functionality in the custom config loading logic.

See jestjs/jest#13356

Fixes #3710
Fixes #3480
Fixes #3476

@nicojs nicojs marked this pull request as ready for review October 22, 2022 19:31
@nicojs nicojs enabled auto-merge (squash) October 22, 2022 20:08
@nicojs nicojs disabled auto-merge October 24, 2022 05:56
@nicojs
Copy link
Member Author

nicojs commented Oct 24, 2022

There is a complication with this approach. It might result in this error:

Cannot read properties of undefined (reading 'testEnvironmentOptions') TypeError: Cannot read properties of undefined (reading 'testEnvironmentOptions')

For both running regular unit tests as running stryker-js.

This happens when a user installed jest@<=27. See https://stackoverflow.com/questions/72078160/jest-testenvironmentoptions-cannot-be-read.

This happens because jest-config@>29.3 is now a direct dependency of @stryker-mutator/jest-runner. It has jest-environment-node and jest-environment-jsdom listed as transient dependencies. This results in roughly this tree:

.
└── node_modules
    ├── @stryker-mutator
    │   └── jest-runner
    ├── jest@27
    │   └── node_modules
    │       └── jest-environment-node@27
    └── jest-environment-node@29.3

(or jest-environment-jsdom equivalent)

The way to solve this is actually not that big of a deal: install jest-environment-node@27 yourself (or jsdom equivalent). This results in the following tree:

.
└── node_modules
    ├── @stryker-mutator
    │   └── jest-runner
    │       └── node_modules
    │           └── jest-environment-node@29
    ├── jest
    │   └── node_modules
    └── jest-environment-node@27

I still like the solution proposed in this PR.

An alternative might be to use the preinstalled version of jest-config when jest@>29.3 is detected. The downsides of that are:

  • ⛔ reading jest.config.ts and other formats won't be supported for jest@<29.3.
  • ⛔ a more significant maintenance burden on us.

@jimCresswell @bmordue @chaouiyounes11 what would you guys prefer?

@SimenB feel free to pitch in as well 😅

@jimCresswell
Copy link

Thanks @nicojs !

The way to solve this is actually not that big of a deal: install jest-environment-node@27 yourself (or jsdom equivalent).

I prefer this solution as well, it is more transparent to the end user, and also gives them the opportunity to solve the problem by updating their dependencies.

I think the only caveat is that it needs to be well documented in a way that is easy to find with a quick search.

@SimenB
Copy link

SimenB commented Oct 24, 2022

I'd try to load jest-config via the jest installation (meaning "reading jest.config.ts and other formats won't be supported for jest@<29.3" which is fine I think? Just document it).

const {createRequire} = require('module');
const requireFromJest = createRequire(require.resolve('jest'));
const requireFromJestCli = createRequire(requireFromJest.resolve('jest-cli'));
const jestConfigFromJest = requireFromJestCli('jest-config');
// or  requireFromJestCli('jest-config/package.json'); if you wanna look at e.g. the exact version

We've talked about splitting out defaults from jest-config before, so that it can be used without also loading the envs etc.. Never got around to doing it, tho.

@nicojs
Copy link
Member Author

nicojs commented Oct 24, 2022

Thanks, @SimonB, and @jimCresswell for the advice.

I'm tempted to go with @SimonB's approach, simply because it would save a lot of headaches for existing users. One big downside is that create-react-app users don't have the luxury of choosing when to update jest... 😑

@SimenB
Copy link

SimenB commented Oct 24, 2022

RN and Metro recently upgraded to Jest 29, so CRA might be able to as well 🙂 (assuming the holdup is Meta and not CRA itself).

EDIT: Seems like it's CRA 😛 facebook/create-react-app#12662

@jimCresswell
Copy link

Either way, I am very excited about being able to validate the unit tests in Next.js projects.

@nicojs
Copy link
Member Author

nicojs commented Oct 28, 2022

I've implemented @SimenB 's suggestion. I also added custom support for exporting an async function from jest config, even when using older versions (implemented that while I was at it ;)).

@nicojs nicojs enabled auto-merge (squash) October 29, 2022 09:35
@nicojs nicojs merged commit 7d42139 into master Oct 29, 2022
@nicojs nicojs deleted the feat/jest-config branch October 29, 2022 10:11
@jimCresswell
Copy link

💥

@nicojs
Copy link
Member Author

nicojs commented Oct 30, 2022

Released in v6.3 🎉
https://github.com/stryker-mutator/stryker-js/releases/tag/v6.3.0

@nicojs
Copy link
Member Author

nicojs commented Oct 31, 2022

Thanks for all help and feedback everyone! ♥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support jest.config.ts file format Jest support config as function Doesn't work with jest.config.ts
3 participants