feat(core-typescript): split vitest base into node + jsdom flavors
Adds vitest.base.node and vitest.base.jsdom with safety defaults (clearMocks, restoreMocks, mockReset, unstubGlobals, sequence.shuffle) and coverage thresholds (80/75/80/80). Migrates all feature configs to the new base. Existing baseVitestConfig kept as backwards-compat re-export of nodeVitestConfig. Spec: §6.2
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@repo/core-eslint": "workspace:*",
|
||||
"@repo/core-testing": "workspace:*",
|
||||
"@repo/core-typescript": "workspace:*",
|
||||
"@types/node": "^22.0.0",
|
||||
"vitest": "^3.1.0"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import path from "node:path";
|
||||
import { baseVitestConfig } from "@repo/core-typescript/vitest.base";
|
||||
import { mergeConfig } from "vitest/config";
|
||||
import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node";
|
||||
|
||||
export default {
|
||||
...baseVitestConfig,
|
||||
export default mergeConfig(nodeVitestConfig, {
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
alias: { "@": path.resolve(__dirname, "./src") },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@repo/core-eslint": "workspace:*",
|
||||
"@repo/core-testing": "workspace:*",
|
||||
"@repo/core-typescript": "workspace:*",
|
||||
"@types/node": "^22.0.0",
|
||||
"vitest": "^3.1.0"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import path from "path";
|
||||
import { baseVitestConfig } from "@repo/core-typescript/vitest.base";
|
||||
import path from "node:path";
|
||||
import { mergeConfig } from "vitest/config";
|
||||
import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node";
|
||||
|
||||
export default {
|
||||
...baseVitestConfig,
|
||||
export default mergeConfig(nodeVitestConfig, {
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
alias: { "@": path.resolve(__dirname, "./src") },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@repo/core-eslint": "workspace:*",
|
||||
"@repo/core-testing": "workspace:*",
|
||||
"@repo/core-typescript": "workspace:*",
|
||||
"@types/node": "^22.0.0",
|
||||
"vitest": "^3.1.0"
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import { baseVitestConfig } from "@repo/core-typescript/vitest.base";
|
||||
import path from "node:path";
|
||||
import { mergeConfig } from "vitest/config";
|
||||
import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node";
|
||||
|
||||
export default baseVitestConfig;
|
||||
export default mergeConfig(nodeVitestConfig, {
|
||||
resolve: {
|
||||
alias: { "@": path.resolve(__dirname, "./src") },
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,7 +7,12 @@
|
||||
"./base.json": "./base.json",
|
||||
"./nextjs.json": "./nextjs.json",
|
||||
"./react-library.json": "./react-library.json",
|
||||
"./vitest.base": "./vitest.base.ts"
|
||||
"./vitest.base": "./vitest.base.ts",
|
||||
"./vitest.base.node": "./vitest.base.node.ts",
|
||||
"./vitest.base.jsdom": "./vitest.base.jsdom.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vitest run"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vitest": "^3.1.0"
|
||||
|
||||
21
packages/core-typescript/vitest.base.jsdom.test.ts
Normal file
21
packages/core-typescript/vitest.base.jsdom.test.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { jsdomVitestConfig } from "./vitest.base.jsdom";
|
||||
|
||||
describe("jsdomVitestConfig", () => {
|
||||
it("uses jsdom environment", () => {
|
||||
expect(jsdomVitestConfig.test?.environment).toBe("jsdom");
|
||||
});
|
||||
it("loads the jsdom setup file", () => {
|
||||
expect(jsdomVitestConfig.test?.setupFiles).toEqual(
|
||||
expect.arrayContaining(["@repo/core-testing/setup/jsdom"]),
|
||||
);
|
||||
});
|
||||
it("includes tsx files", () => {
|
||||
expect(jsdomVitestConfig.test?.include).toEqual(
|
||||
expect.arrayContaining(["src/**/*.test.{ts,tsx}", "tests/**/*.test.{ts,tsx}"]),
|
||||
);
|
||||
});
|
||||
it("inherits clearMocks from node base", () => {
|
||||
expect(jsdomVitestConfig.test?.clearMocks).toBe(true);
|
||||
});
|
||||
});
|
||||
13
packages/core-typescript/vitest.base.jsdom.ts
Normal file
13
packages/core-typescript/vitest.base.jsdom.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig, mergeConfig } from "vitest/config";
|
||||
import { nodeVitestConfig } from "./vitest.base.node.js";
|
||||
|
||||
export const jsdomVitestConfig = mergeConfig(
|
||||
nodeVitestConfig,
|
||||
defineConfig({
|
||||
test: {
|
||||
environment: "jsdom",
|
||||
setupFiles: ["@repo/core-testing/setup/jsdom"],
|
||||
include: ["src/**/*.test.{ts,tsx}", "tests/**/*.test.{ts,tsx}"],
|
||||
},
|
||||
}),
|
||||
);
|
||||
28
packages/core-typescript/vitest.base.node.test.ts
Normal file
28
packages/core-typescript/vitest.base.node.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { nodeVitestConfig } from "./vitest.base.node";
|
||||
|
||||
describe("nodeVitestConfig", () => {
|
||||
it("uses node environment", () => {
|
||||
expect(nodeVitestConfig.test?.environment).toBe("node");
|
||||
});
|
||||
it("enables clearMocks, restoreMocks, mockReset", () => {
|
||||
expect(nodeVitestConfig.test?.clearMocks).toBe(true);
|
||||
expect(nodeVitestConfig.test?.restoreMocks).toBe(true);
|
||||
expect(nodeVitestConfig.test?.mockReset).toBe(true);
|
||||
});
|
||||
it("declares coverage thresholds", () => {
|
||||
expect(nodeVitestConfig.test?.coverage?.thresholds).toMatchObject({
|
||||
statements: 80, branches: 75, functions: 80, lines: 80,
|
||||
});
|
||||
});
|
||||
it("includes src and tests glob", () => {
|
||||
expect(nodeVitestConfig.test?.include).toEqual(
|
||||
expect.arrayContaining(["src/**/*.test.ts", "tests/**/*.test.ts"]),
|
||||
);
|
||||
});
|
||||
it("excludes factories and contracts from coverage", () => {
|
||||
expect(nodeVitestConfig.test?.coverage?.exclude).toEqual(
|
||||
expect.arrayContaining(["src/__factories__/**", "src/__contracts__/**"]),
|
||||
);
|
||||
});
|
||||
});
|
||||
29
packages/core-typescript/vitest.base.node.ts
Normal file
29
packages/core-typescript/vitest.base.node.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export const nodeVitestConfig = defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "node",
|
||||
include: ["src/**/*.test.ts", "tests/**/*.test.ts"],
|
||||
setupFiles: ["@repo/core-testing/setup/node"],
|
||||
clearMocks: true,
|
||||
restoreMocks: true,
|
||||
mockReset: true,
|
||||
unstubGlobals: true,
|
||||
sequence: { shuffle: true },
|
||||
coverage: {
|
||||
provider: "v8",
|
||||
reporter: ["text", "html", "lcov"],
|
||||
include: ["src/**"],
|
||||
exclude: [
|
||||
"src/**/*.test.{ts,tsx}",
|
||||
"src/**/index.ts",
|
||||
"src/__factories__/**",
|
||||
"src/__contracts__/**",
|
||||
],
|
||||
thresholds: {
|
||||
statements: 80, branches: 75, functions: 80, lines: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,15 +1,3 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export const baseVitestConfig = defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "node",
|
||||
include: ["src/**/*.test.ts", "src/**/*.test.tsx", "tests/**/*.test.ts"],
|
||||
coverage: {
|
||||
provider: "v8",
|
||||
reporter: ["text", "html"],
|
||||
include: ["src/**"],
|
||||
exclude: ["src/**/*.test.{ts,tsx}", "src/**/index.ts"],
|
||||
},
|
||||
},
|
||||
});
|
||||
// Backwards-compat re-export. New code should import from
|
||||
// vitest.base.node or vitest.base.jsdom directly.
|
||||
export { nodeVitestConfig as baseVitestConfig } from "./vitest.base.node.js";
|
||||
|
||||
13
packages/core-typescript/vitest.config.ts
Normal file
13
packages/core-typescript/vitest.config.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
// Core-typescript tests the vitest base configs themselves.
|
||||
// They live at package root (not under src/), so we use a standalone config.
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "node",
|
||||
include: ["*.test.ts"],
|
||||
clearMocks: true,
|
||||
restoreMocks: true,
|
||||
},
|
||||
});
|
||||
@@ -25,6 +25,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@repo/core-eslint": "workspace:*",
|
||||
"@repo/core-testing": "workspace:*",
|
||||
"@repo/core-typescript": "workspace:*",
|
||||
"@types/node": "^22.0.0",
|
||||
"vitest": "^3.1.0"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import path from "node:path";
|
||||
import { baseVitestConfig } from "@repo/core-typescript/vitest.base";
|
||||
import { mergeConfig } from "vitest/config";
|
||||
import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node";
|
||||
|
||||
export default {
|
||||
...baseVitestConfig,
|
||||
export default mergeConfig(nodeVitestConfig, {
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
alias: { "@": path.resolve(__dirname, "./src") },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@repo/core-eslint": "workspace:*",
|
||||
"@repo/core-testing": "workspace:*",
|
||||
"@repo/core-typescript": "workspace:*",
|
||||
"@types/node": "^22.0.0",
|
||||
"vitest": "^3.1.0"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import path from "node:path";
|
||||
import { baseVitestConfig } from "@repo/core-typescript/vitest.base";
|
||||
import { mergeConfig } from "vitest/config";
|
||||
import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node";
|
||||
|
||||
export default {
|
||||
...baseVitestConfig,
|
||||
export default mergeConfig(nodeVitestConfig, {
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
alias: { "@": path.resolve(__dirname, "./src") },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@@ -256,6 +256,9 @@ importers:
|
||||
'@repo/core-eslint':
|
||||
specifier: workspace:*
|
||||
version: link:../core-eslint
|
||||
'@repo/core-testing':
|
||||
specifier: workspace:*
|
||||
version: link:../core-testing
|
||||
'@repo/core-typescript':
|
||||
specifier: workspace:*
|
||||
version: link:../core-typescript
|
||||
@@ -290,6 +293,9 @@ importers:
|
||||
'@repo/core-eslint':
|
||||
specifier: workspace:*
|
||||
version: link:../core-eslint
|
||||
'@repo/core-testing':
|
||||
specifier: workspace:*
|
||||
version: link:../core-testing
|
||||
'@repo/core-typescript':
|
||||
specifier: workspace:*
|
||||
version: link:../core-typescript
|
||||
@@ -413,6 +419,9 @@ importers:
|
||||
'@repo/core-eslint':
|
||||
specifier: workspace:*
|
||||
version: link:../core-eslint
|
||||
'@repo/core-testing':
|
||||
specifier: workspace:*
|
||||
version: link:../core-testing
|
||||
'@repo/core-typescript':
|
||||
specifier: workspace:*
|
||||
version: link:../core-typescript
|
||||
@@ -570,6 +579,9 @@ importers:
|
||||
'@repo/core-eslint':
|
||||
specifier: workspace:*
|
||||
version: link:../core-eslint
|
||||
'@repo/core-testing':
|
||||
specifier: workspace:*
|
||||
version: link:../core-testing
|
||||
'@repo/core-typescript':
|
||||
specifier: workspace:*
|
||||
version: link:../core-typescript
|
||||
@@ -620,6 +632,9 @@ importers:
|
||||
'@repo/core-eslint':
|
||||
specifier: workspace:*
|
||||
version: link:../core-eslint
|
||||
'@repo/core-testing':
|
||||
specifier: workspace:*
|
||||
version: link:../core-testing
|
||||
'@repo/core-typescript':
|
||||
specifier: workspace:*
|
||||
version: link:../core-typescript
|
||||
|
||||
Reference in New Issue
Block a user