Skip to content

Commit 6698e3a

Browse files
authored
test: Migrate all packages from jest to vitest (#13)
Jest's ESM support sucks ([ref](jestjs/jest#9430)) and is held up on some interminable issues related to Node VMs ([ref](nodejs/node#37648)). I was impressed with `vite` and `vitest` following my experience implementing #8, and after I discovered that `vitest` has a [browser mode for unit tests](https://vitest.dev/guide/browser/#browser-mode)—which will ultimately allow us to test under `ses` in an actual browser environment—I was sold. This migrates the entire repo from `jest` to `vitest`. They work very similarly, except [`vitest` has a number of benefits over `jest`](https://vitest.dev/guide/comparisons.html), such as not polluting the global namespace by default. I tried running some tests under `ses` with lockdown in the browser, and it worked perfectly. However, it's held up on rewriting tests that rely on JSDOM, so we're tracking that work in #12.
1 parent ceedae6 commit 6698e3a

15 files changed

+416
-2182
lines changed

.depcheckrc.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ ignores:
66
- '@metamask/auto-changelog'
77
- '@ts-bridge/cli'
88
- '@ts-bridge/shims'
9-
- '@types/jest'
109
- '@types/node'
1110
- '@yarnpkg/*'
12-
- 'jest-silent-reporter'
1311
- 'jsdom'
1412
- 'prettier-plugin-*'
15-
- 'ts-jest'
1613
- 'typedoc'
14+
- 'vite'
15+
- 'vitest'

.eslintrc.js

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ module.exports = {
1313

1414
ignorePatterns: [
1515
'!.eslintrc.js',
16-
'!jest.config.js',
16+
'!vite.config.mts',
17+
'!vitest.config.mts',
1718
'node_modules',
1819
'**/dist',
1920
'**/docs',
@@ -49,7 +50,7 @@ module.exports = {
4950
},
5051

5152
{
52-
files: ['**/scripts/*.mjs'],
53+
files: ['**/scripts/*.mjs', '*.mts'],
5354
parserOptions: {
5455
ecmaVersion: '2022',
5556
},
@@ -98,34 +99,44 @@ module.exports = {
9899
},
99100

100101
{
101-
files: ['**/jest.environment.js'],
102+
// @metamask/eslint-plugin-vitest does not exist, so this is copied from the
103+
// jest-equivalent. All of the rules we specify are the same. Ref:
104+
// https://github.com/MetaMask/eslint-config/blob/95275db568999bf48670894a3dc6b6c1a2f517f9/packages/jest/src/index.js
105+
files: ['**/*.test.{ts,js}'],
106+
plugins: ['vitest'],
107+
extends: ['plugin:vitest/recommended'],
102108
rules: {
103-
// These files run under Node, and thus `require(...)` is expected.
104-
'n/global-require': 'off',
105-
},
106-
},
107-
108-
{
109-
files: ['*.test.{ts,js}', '**/tests/**/*.{ts,js}'],
110-
extends: ['@metamask/eslint-config-jest'],
111-
rules: {
112-
'@typescript-eslint/no-shadow': [
109+
// From the jest/style ruleset (no corresponding ruleset for vitest). Ref:
110+
// https://github.com/jest-community/eslint-plugin-jest/blob/39719a323466aada48531fe28ec953e17dee6e65/src/index.ts#L74-L77
111+
'vitest/no-alias-methods': 'error', // We upgrade this to an error
112+
'vitest/prefer-to-be': 'error',
113+
'vitest/prefer-to-contain': 'error',
114+
'vitest/prefer-to-have-length': 'error',
115+
// From MetaMask's custom ruleset
116+
'vitest/consistent-test-it': ['error', { fn: 'it' }],
117+
'vitest/no-conditional-in-test': 'error', // Previously "jest/no-if"
118+
'vitest/no-duplicate-hooks': 'error',
119+
'vitest/no-test-return-statement': 'error',
120+
'vitest/prefer-hooks-on-top': 'error',
121+
'vitest/prefer-lowercase-title': ['error', { ignore: ['describe'] }],
122+
'vitest/prefer-spy-on': 'error',
123+
'vitest/prefer-strict-equal': 'error',
124+
'vitest/prefer-todo': 'error',
125+
'vitest/require-top-level-describe': 'error',
126+
'vitest/require-to-throw-message': 'error',
127+
'vitest/valid-expect': ['error', { alwaysAwait: true }],
128+
'vitest/no-restricted-matchers': [
113129
'error',
114-
{ allow: ['describe', 'expect', 'it'] },
130+
{
131+
resolves: 'Use `expect(await promise)` instead.',
132+
toBeFalsy: 'Avoid `toBeFalsy`',
133+
toBeTruthy: 'Avoid `toBeTruthy`',
134+
toMatchSnapshot: 'Use `toMatchInlineSnapshot()` instead',
135+
toThrowErrorMatchingSnapshot:
136+
'Use `toThrowErrorMatchingInlineSnapshot()` instead',
137+
},
115138
],
116139
},
117140
},
118-
119-
{
120-
// These files are test helpers, not tests. We still use the Jest ESLint
121-
// config here to ensure that ESLint expects a test-like environment, but
122-
// various rules meant just to apply to tests have been disabled.
123-
files: ['**/tests/**/*.{ts,js}', '!*.test.{ts,js}'],
124-
rules: {
125-
'jest/no-export': 'off',
126-
'jest/require-top-level-describe': 'off',
127-
'jest/no-if': 'off',
128-
},
129-
},
130141
],
131142
};

constraints.pro

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -299,29 +299,24 @@ gen_enforced_field(WorkspaceCwd, 'scripts.changelog:update', CorrectChangelogUpd
299299
\+ atom_concat(ExpectedPrefix, _, ChangelogUpdateCommand).
300300

301301
% All non-root packages must have the same "test" script.
302-
gen_enforced_field(WorkspaceCwd, 'scripts.test', 'jest --reporters=jest-silent-reporter') :-
303-
WorkspaceCwd \= 'packages/extension',
302+
gen_enforced_field(WorkspaceCwd, 'scripts.test', 'vitest run --config vitest.config.mts') :-
304303
WorkspaceCwd \= 'packages/shims',
305304
WorkspaceCwd \= '.'.
306305

307306
% All non-root packages must have the same "test:clean" script.
308-
gen_enforced_field(WorkspaceCwd, 'scripts.test:clean', 'jest --clearCache') :-
309-
WorkspaceCwd \= 'packages/extension',
307+
gen_enforced_field(WorkspaceCwd, 'scripts.test:clean', 'yarn test --no-cache --coverage.clean') :-
310308
WorkspaceCwd \= '.'.
311309

312-
% All non-root packages must have the same "test:verbose" script.
313-
gen_enforced_field(WorkspaceCwd, 'scripts.test:verbose', 'jest --verbose') :-
314-
WorkspaceCwd \= 'packages/extension',
310+
% All non-root packages must have the same "test:dev" script.
311+
gen_enforced_field(WorkspaceCwd, 'scripts.test:dev', 'yarn test --coverage false') :-
315312
WorkspaceCwd \= '.'.
316313

317314
% All non-root packages must have the same "test:verbose" script.
318-
gen_enforced_field(WorkspaceCwd, 'scripts.test:dev', 'jest --verbose --coverage false') :-
319-
WorkspaceCwd \= 'packages/extension',
315+
gen_enforced_field(WorkspaceCwd, 'scripts.test:verbose', 'yarn test --reporter verbose') :-
320316
WorkspaceCwd \= '.'.
321317

322318
% All non-root packages must have the same "test:watch" script.
323-
gen_enforced_field(WorkspaceCwd, 'scripts.test:watch', 'jest --watch') :-
324-
WorkspaceCwd \= 'packages/extension',
319+
gen_enforced_field(WorkspaceCwd, 'scripts.test:watch', 'vitest --config vitest.config.mts') :-
325320
WorkspaceCwd \= '.'.
326321

327322
% All dependency ranges must be recognizable (this makes it possible to apply

jest.config.packages.js

Lines changed: 0 additions & 220 deletions
This file was deleted.

0 commit comments

Comments
 (0)