Skip to content

Commit 7c744ea

Browse files
committed
feat!: migrate from Jest to Vitest
Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
1 parent f1de957 commit 7c744ea

40 files changed

Lines changed: 4910 additions & 5876 deletions

package-lock.json

Lines changed: 4321 additions & 5686 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
### 📦 Package scripts
1414

15-
- `test`: Run tests with [jest](https://jestjs.io/)
15+
- `test`: Run tests with [Vitest](https://vitest.dev/)
1616
- `lint`: Run linter with [eslint](https://eslint.org/)
1717
- `prepare`: Self install / update
1818

@@ -38,9 +38,7 @@
3838
- Install and configure [eslint](https://eslint.org/) with recommended [rules](https://eslint.org/docs/rules/)
3939
- Configure Eslint to works with [typescript](https://github.com/typescript-eslint/typescript-eslint#readme)
4040
- Install and configure the following Eslint plugins:
41-
4241
- [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import): ES2015+ (ES6+) import/export syntax
43-
- [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest#readme): Rules for Jest
4442
- [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node#readme): Additional ESLint's rules for Node.js
4543
- [eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise#readme): Enforce best practices for JavaScript promises.
4644

@@ -53,13 +51,13 @@
5351

5452
### 🧪 Tests
5553

56-
- Install and configure [Jest](https://jestjs.io/)
57-
- Install and configure [ts-jest](https://kulshekhar.github.io/ts-jest) to make Jest and Typescript work together
54+
- Install and configure [Vitest](https://vitest.dev/)
55+
- Install and configure [@vitest/coverage-v8](https://www.npmjs.com/package/@vitest/coverage-v8) for coverage reports
5856

5957
### 📖 Types
6058

6159
- [@types/node](https://www.npmjs.com/package/@types/node)
62-
- [@types/jest](https://www.npmjs.com/package/@types/jest)
60+
- [vitest/globals](https://vitest.dev/config/#globals)
6361

6462
---
6563

packages/core/package.json

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
"start": "npm link && tsc -w",
3535
"stop": "npm unlink",
3636
"build": "rimraf dist && tsc",
37-
"jest": "jest --detectOpenHandles --forceExit",
38-
"test": "npm run jest -- --maxWorkers=50%",
39-
"test:unit": "npm run test -- --testPathPattern \".+spec\\.ts\"",
40-
"test:e2e": "npm run test -- --testPathPattern \".+e2e\\.spec\\.ts\"",
41-
"test:coverage": "npm run test -- --coverage",
37+
"vitest": "vitest",
38+
"test": "vitest run",
39+
"test:unit": "vitest run spec.ts",
40+
"test:e2e": "vitest run e2e.spec.ts",
41+
"test:coverage": "vitest run --coverage",
4242
"lint": "biome lint src",
4343
"lint:fix": "biome check --write src",
4444
"lint:ci": "biome check src"
@@ -48,30 +48,14 @@
4848
},
4949
"dependencies": {
5050
"@biomejs/biome": "^2.4.8",
51+
"@vitest/coverage-v8": "^4.1.6",
5152
"@commitlint/cli": "^21.0.1",
5253
"@commitlint/config-conventional": "^21.0.2",
53-
"@types/jest": "^30.0.0",
5454
"@types/node": "^25.9.1",
55-
"jest": "^30.4.2",
56-
"ts-jest": "^29.4.11",
57-
"typescript": "^6.0.3"
55+
"typescript": "^6.0.3",
56+
"vitest": "^4.1.6"
5857
},
5958
"devDependencies": {
6059
"ts-node": "^10.9.2"
61-
},
62-
"jest": {
63-
"preset": "ts-jest",
64-
"testEnvironment": "node",
65-
"testMatch": [
66-
"**/src/**/__tests__/**/*.[jt]s?(x)",
67-
"**/src/**/?(*.)+(spec|test)?(.*).+(ts|tsx|js)"
68-
],
69-
"collectCoverageFrom": [
70-
"**/src/**/*.[jt]s?(x)"
71-
],
72-
"reporters": [
73-
"default",
74-
"github-actions"
75-
]
7660
}
7761
}

packages/core/src/__snapshots__/core.e2e.spec.ts.snap

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`E2E - core Monorepo project Installs core package 1`] = `
3+
exports[`E2E - core > Monorepo project > Installs core package 1`] = `
44
"Installing ts-dev-tools...
55
Applying migration "core - 20201024173398-init"...
66
Migration "core - 20201024173398-init" applied!
@@ -18,21 +18,17 @@ Applying migration "core - 20250623095600-remove-prettier-oxc"...
1818
Migration "core - 20250623095600-remove-prettier-oxc" applied!
1919
Applying migration "core - 20260311120000-migrate-to-biome"...
2020
Migration "core - 20260311120000-migrate-to-biome" applied!
21+
Applying migration "core - 20260604100000-migrate-to-vitest"...
22+
Migration "core - 20260604100000-migrate-to-vitest" applied!
2123
Symlinking dev dependencies...
2224
- Symlinking @biomejs/biome
25+
- Symlinking @vitest/coverage-v8
2326
- Symlinking @commitlint/cli
2427
- Symlinking @commitlint/config-conventional
25-
- Symlinking @types/jest
2628
- Symlinking @types/node
27-
- Symlinking jest
28-
- Symlinking ts-jest
29+
- Symlinking vitest
2930
Symlinking dev dependencies done!
3031
Resolving peer dependencies...
31-
- Symlinking peer dependency "@babel/core" required by "ts-jest"
32-
- Symlinking peer dependency "@jest/transform" required by "ts-jest"
33-
- Symlinking peer dependency "@jest/types" required by "ts-jest"
34-
- Symlinking peer dependency "babel-jest" required by "ts-jest"
35-
- Symlinking peer dependency "jest-util" required by "ts-jest"
3632
Resolving peer dependencies done!
3733
Checking for duplicate dev dependencies...
3834
Some dev dependencies are unnecessarily installed as their are already required by "@ts-dev-tools/core":
@@ -42,7 +38,7 @@ Check for duplicate dev dependencies done!
4238
Installation done!"
4339
`;
4440

45-
exports[`E2E - core Simple project Installs core package 1`] = `
41+
exports[`E2E - core > Simple project > Installs core package 1`] = `
4642
"Installing ts-dev-tools...
4743
Applying migration "core - 20201024173398-init"...
4844
Migration "core - 20201024173398-init" applied!
@@ -60,21 +56,17 @@ Applying migration "core - 20250623095600-remove-prettier-oxc"...
6056
Migration "core - 20250623095600-remove-prettier-oxc" applied!
6157
Applying migration "core - 20260311120000-migrate-to-biome"...
6258
Migration "core - 20260311120000-migrate-to-biome" applied!
59+
Applying migration "core - 20260604100000-migrate-to-vitest"...
60+
Migration "core - 20260604100000-migrate-to-vitest" applied!
6361
Symlinking dev dependencies...
6462
- Symlinking @biomejs/biome
63+
- Symlinking @vitest/coverage-v8
6564
- Symlinking @commitlint/cli
6665
- Symlinking @commitlint/config-conventional
67-
- Symlinking @types/jest
6866
- Symlinking @types/node
69-
- Symlinking jest
70-
- Symlinking ts-jest
67+
- Symlinking vitest
7168
Symlinking dev dependencies done!
7269
Resolving peer dependencies...
73-
- Symlinking peer dependency "@babel/core" required by "ts-jest"
74-
- Symlinking peer dependency "@jest/transform" required by "ts-jest"
75-
- Symlinking peer dependency "@jest/types" required by "ts-jest"
76-
- Symlinking peer dependency "babel-jest" required by "ts-jest"
77-
- Symlinking peer dependency "jest-util" required by "ts-jest"
7870
Resolving peer dependencies done!
7971
Checking for duplicate dev dependencies...
8072
Some dev dependencies are unnecessarily installed as their are already required by "@ts-dev-tools/core":
@@ -84,38 +76,40 @@ Check for duplicate dev dependencies done!
8476
Installation done!"
8577
`;
8678

87-
exports[`E2E - core Simple project Installs core package 2`] = `
79+
exports[`E2E - core > Simple project > Installs core package 2`] = `
8880
{
8981
"build": "tsc --noEmit",
9082
"check": "biome check --write .",
9183
"dev": "vite",
9284
"format": "biome format --write .",
93-
"jest": "jest --detectOpenHandles --forceExit",
9485
"lint": "biome lint .",
9586
"prepare": "ts-dev-tools install",
9687
"preview": "vite preview",
97-
"test": "npm run jest --maxWorkers=50%",
98-
"test:ci": "npm run test:cov --runInBand",
99-
"test:cov": "npm run test --coverage",
100-
"test:watch": "npm run jest --watch --maxWorkers=25%",
88+
"test": "vitest run",
89+
"test:ci": "npm run test:cov",
90+
"test:cov": "vitest run --coverage",
91+
"test:watch": "vitest",
92+
"vitest": "vitest",
10193
}
10294
`;
10395

104-
exports[`E2E - core Simple project Installs core package 3`] = `
105-
{
106-
"collectCoverageFrom": [
107-
"**/src/**/*.[jt]s?(x)",
108-
],
109-
"preset": "ts-jest",
110-
"testEnvironment": "node",
111-
"testMatch": [
112-
"**/__tests__/**/*.[jt]s?(x)",
113-
"**/?(*.)+(spec|test)?(.*).+(ts|tsx|js)",
114-
],
115-
}
96+
exports[`E2E - core > Simple project > Installs core package 3`] = `
97+
"import { defineConfig } from "vitest/config";
98+
99+
export default defineConfig({
100+
test: {
101+
coverage: {
102+
include: ["src/**/*.{ts,tsx,js,jsx}"],
103+
provider: "v8",
104+
},
105+
environment: "node",
106+
globals: true,
107+
},
108+
});
109+
"
116110
`;
117111

118-
exports[`E2E - core Simple project Installs core package 4`] = `
112+
exports[`E2E - core > Simple project > Installs core package 4`] = `
119113
"{
120114
"$schema": "https://biomejs.dev/schemas/__VERSION__/schema.json",
121115
"vcs": {

packages/core/src/core.e2e.spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,13 @@ describe(`E2E - ${packageToTest}`, () => {
105105
expect(packageJson.getTsDevToolsVersion()).not.toBeFalsy();
106106
expect(packageJson.getContent().scripts).toMatchSnapshot();
107107
expect(packageJson.getContent().prettier).toBeUndefined();
108-
expect(packageJson.getContent().jest).toMatchSnapshot();
108+
expect(packageJson.getContent().jest).toBeUndefined();
109+
110+
const vitestConfigFilePath = `${testProjectDir}/vitest.config.ts`;
111+
expect(FileService.fileExists(vitestConfigFilePath)).toBe(true);
112+
expect(
113+
FileService.getFileContent(vitestConfigFilePath),
114+
).toMatchSnapshot();
109115

110116
const biomeConfigFilePath = `${testProjectDir}/biome.json`;
111117
expect(FileService.fileExists(biomeConfigFilePath)).toBe(true);

packages/core/src/install/__snapshots__/command.spec.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`Install command should run fresh installation without error 1`] = `
3+
exports[`Install command > should run fresh installation without error 1`] = `
44
"Installing ts-dev-tools...
55
Symlinking dev dependencies...
66
Symlinking dev dependencies done!
@@ -12,7 +12,7 @@ Check for duplicate dev dependencies done!
1212
Installation done!"
1313
`;
1414

15-
exports[`Install command should run update without error 1`] = `
15+
exports[`Install command > should run update without error 1`] = `
1616
"Updating ts-dev-tools installation...
1717
Symlinking dev dependencies...
1818
Symlinking dev dependencies done!

packages/core/src/install/migrations/20260311120000-migrate-to-biome.spec.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ describe("Migration 20260311120000-migrate-to-biome", () => {
196196
const invalidBiomeConfig = '{\n "vcs":\n';
197197
FileService.putFileContent(biomeConfigFilePath, invalidBiomeConfig);
198198

199-
const warnSpy = jest.spyOn(console, "warn").mockImplementation(() => {});
199+
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
200200

201201
try {
202202
await expect(up(testProjectDir)).resolves.toBeUndefined();
@@ -214,9 +214,7 @@ describe("Migration 20260311120000-migrate-to-biome", () => {
214214
});
215215

216216
it("should continue when biome init does not create a config file", async () => {
217-
const execCmdSpy = jest
218-
.spyOn(CmdService, "execCmd")
219-
.mockResolvedValue("");
217+
const execCmdSpy = vi.spyOn(CmdService, "execCmd").mockResolvedValue("");
220218

221219
try {
222220
await expect(up(testProjectDir)).resolves.toBeUndefined();
@@ -314,7 +312,7 @@ export default tsDevToolsCore;
314312
);
315313

316314
const originalSetContent = PackageJson.prototype.setContent;
317-
const setContentSpy = jest
315+
const setContentSpy = vi
318316
.spyOn(PackageJson.prototype, "setContent")
319317
.mockImplementation(function mockSetContent(
320318
this: PackageJson,
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { join } from "node:path";
2+
3+
import { FileService } from "../../services/FileService";
4+
import { PackageJson } from "../../services/PackageJson";
5+
import {
6+
createProjectForTestFile,
7+
deleteTestProject,
8+
} from "../../tests/test-project";
9+
import { up as init } from "./20201024173398-init";
10+
import { up as migrateToBiome } from "./20260311120000-migrate-to-biome";
11+
import { up } from "./20260604100000-migrate-to-vitest";
12+
13+
const useCache = true;
14+
const shouldCleanupAfterTest = true;
15+
16+
describe("Migration 20260604100000-migrate-to-vitest", () => {
17+
let testProjectDir: string;
18+
19+
beforeAll(() => {
20+
if (!useCache) {
21+
console.warn("Cache is disabled. Enable it one dev is done.");
22+
}
23+
if (!shouldCleanupAfterTest) {
24+
console.warn("Cleanup is disabled. Enable it one dev is done.");
25+
}
26+
});
27+
28+
beforeEach(async () => {
29+
testProjectDir = await createProjectForTestFile(__filename, useCache);
30+
});
31+
32+
afterEach(async () => {
33+
if (shouldCleanupAfterTest) {
34+
await deleteTestProject(__filename);
35+
}
36+
});
37+
38+
it("should migrate generated Jest config and scripts to Vitest", async () => {
39+
await init(testProjectDir);
40+
await migrateToBiome(testProjectDir);
41+
await up(testProjectDir);
42+
43+
const packageJsonContent =
44+
PackageJson.fromDirPath(testProjectDir).getContent();
45+
46+
expect(packageJsonContent).toMatchSnapshot();
47+
expect(
48+
FileService.getFileContent(join(testProjectDir, "vitest.config.ts")),
49+
).toMatchSnapshot();
50+
});
51+
52+
it("should preserve an existing custom Vitest config", async () => {
53+
const vitestConfigFilePath = join(testProjectDir, "vitest.config.ts");
54+
const customVitestConfig = "export default {}\n";
55+
56+
await init(testProjectDir);
57+
await migrateToBiome(testProjectDir);
58+
FileService.putFileContent(vitestConfigFilePath, customVitestConfig);
59+
60+
await up(testProjectDir);
61+
62+
expect(FileService.getFileContent(vitestConfigFilePath)).toBe(
63+
customVitestConfig,
64+
);
65+
});
66+
});

0 commit comments

Comments
 (0)