mirror of https://github.com/abpframework/abp.git
9 changed files with 918 additions and 173 deletions
@ -1,118 +1,130 @@ |
|||
{ |
|||
"migrations": [ |
|||
{ |
|||
"version": "22.0.0-beta.1", |
|||
"description": "Updates release version config based on the breaking changes in Nx v22", |
|||
"implementation": "./src/migrations/update-22-0-0/release-version-config-changes", |
|||
"cli": "nx", |
|||
"version": "22.6.0-beta.10", |
|||
"description": "Adds .claude/worktrees to .gitignore", |
|||
"implementation": "./dist/src/migrations/update-22-6-0/add-claude-worktrees-to-git-ignore", |
|||
"package": "nx", |
|||
"name": "22-0-0-release-version-config-changes" |
|||
"name": "22-6-1-add-claude-worktrees-to-git-ignore" |
|||
}, |
|||
{ |
|||
"version": "22.0.0-beta.2", |
|||
"description": "Consolidates releaseTag* options into nested releaseTag object structure", |
|||
"implementation": "./src/migrations/update-22-0-0/consolidate-release-tag-config", |
|||
"cli": "nx", |
|||
"version": "22.7.0-beta.0", |
|||
"description": "Adds .nx/polygraph to .gitignore", |
|||
"implementation": "./dist/src/migrations/update-22-7-0/add-polygraph-to-git-ignore", |
|||
"package": "nx", |
|||
"name": "22-0-0-consolidate-release-tag-config" |
|||
"name": "22-7-0-add-polygraph-to-git-ignore" |
|||
}, |
|||
{ |
|||
"cli": "nx", |
|||
"version": "22.1.0-beta.5", |
|||
"description": "Updates the nx wrapper.", |
|||
"implementation": "./src/migrations/update-22-1-0/update-nx-wrapper", |
|||
"version": "22.6.0-rc.0", |
|||
"description": "Adds .claude/settings.local.json to .gitignore", |
|||
"implementation": "./dist/src/migrations/update-17-3-0/update-nxw", |
|||
"package": "nx", |
|||
"name": "22-1-0-update-nx-wrapper" |
|||
"name": "22-6-0-add-claude-settings-local-to-git-ignore" |
|||
}, |
|||
{ |
|||
"version": "21.5.0-beta.2", |
|||
"description": "Migrate the legacy 'development' custom condition to a workspace-unique custom condition name.", |
|||
"factory": "./src/migrations/update-21-5-0/migrate-development-custom-condition", |
|||
"package": "@nx/js", |
|||
"name": "migrate-development-custom-condition" |
|||
"cli": "nx", |
|||
"version": "22.7.0-beta.0", |
|||
"description": "Adds .nx/self-healing to .gitignore", |
|||
"implementation": "./dist/src/migrations/update-22-2-0/add-self-healing-to-gitignore", |
|||
"package": "nx", |
|||
"name": "22-7-0-add-self-healing-to-gitignore" |
|||
}, |
|||
{ |
|||
"version": "22.0.0-beta.0", |
|||
"description": "Remove the deprecated `external` and `externalBuildTargets` options from the `@nx/js:swc` and `@nx/js:tsc` executors.", |
|||
"factory": "./src/migrations/update-22-0-0/remove-external-options-from-js-executors", |
|||
"package": "@nx/js", |
|||
"name": "remove-external-options-from-js-executors" |
|||
"version": "22.3.2-beta.0", |
|||
"requires": { |
|||
"@angular/build": ">=21.0.0" |
|||
}, |
|||
"description": "Create AI Instructions to help migrate users workspaces past breaking changes for Vitest 4.", |
|||
"implementation": "./src/migrations/update-22-1-0/create-ai-instructions-for-vitest-4", |
|||
"package": "@nx/vitest", |
|||
"name": "update-22-3-2" |
|||
}, |
|||
{ |
|||
"version": "22.1.0-rc.1", |
|||
"description": "Removes redundant TypeScript project references from project's tsconfig.json files when runtime tsconfig files (e.g., tsconfig.lib.json, tsconfig.app.json) exist.", |
|||
"factory": "./src/migrations/update-22-1-0/remove-redundant-ts-project-references", |
|||
"package": "@nx/js", |
|||
"name": "remove-redundant-ts-project-references" |
|||
"version": "22.6.0-beta.11", |
|||
"description": "Prefix reportsDirectory with {projectRoot} to maintain correct resolution after workspace-root-relative behavior change.", |
|||
"implementation": "./src/migrations/update-22-6-0/prefix-reports-directory-with-project-root", |
|||
"package": "@nx/vitest", |
|||
"name": "update-22-6-0-prefix-reports-directory" |
|||
}, |
|||
{ |
|||
"version": "21.3.0-beta.3", |
|||
"description": "Rename the CLI option `testPathPattern` to `testPathPatterns`.", |
|||
"implementation": "./src/migrations/update-21-3-0/rename-test-path-pattern", |
|||
"package": "@nx/jest", |
|||
"name": "rename-test-path-pattern" |
|||
"version": "22.7.0-beta.12", |
|||
"description": "Add missing inputs to @nx/eslint:lint executor target defaults", |
|||
"implementation": "./src/migrations/update-21-6-0/update-executor-lint-inputs", |
|||
"package": "@nx/eslint", |
|||
"name": "update-executor-lint-inputs" |
|||
}, |
|||
{ |
|||
"version": "22.2.0-beta.2", |
|||
"description": "Convert jest.config.ts files from ESM to CJS syntax (export default -> module.exports, import -> require) for projects using CommonJS resolution to ensure correct loading under Node.js type-stripping.", |
|||
"implementation": "./src/migrations/update-22-2-0/convert-jest-config-to-cjs", |
|||
"version": "22.3.2-beta.0", |
|||
"requires": { |
|||
"jest": ">=30.0.0" |
|||
}, |
|||
"description": "Replace removed matcher aliases in Jest v30 with their corresponding matcher", |
|||
"implementation": "./src/migrations/update-21-3-0/replace-removed-matcher-aliases", |
|||
"package": "@nx/jest", |
|||
"name": "convert-jest-config-to-cjs" |
|||
"name": "replace-removed-matcher-aliases-v22-3" |
|||
}, |
|||
{ |
|||
"cli": "nx", |
|||
"version": "21.3.0-beta.4", |
|||
"requires": { "@angular/core": ">=20.1.0" }, |
|||
"description": "Update the @angular/cli package version to ~20.1.0.", |
|||
"factory": "./src/migrations/update-21-3-0/update-angular-cli", |
|||
"version": "22.3.0-beta.0", |
|||
"requires": { |
|||
"@angular/core": ">=21.0.0" |
|||
}, |
|||
"description": "Updates webpack-based SSR configuration to use preserve module format and bundler module resolution.", |
|||
"factory": "./src/migrations/update-22-3-0/update-ssr-webpack-config", |
|||
"package": "@nx/angular", |
|||
"name": "update-angular-cli-version-20-1-0" |
|||
"name": "update-ssr-webpack-config-22-2-0" |
|||
}, |
|||
{ |
|||
"version": "21.5.0-beta.0", |
|||
"description": "Set the 'tsConfig' option to build and test targets to help with Angular migration issues.", |
|||
"factory": "./src/migrations/update-21-5-0/set-tsconfig-option", |
|||
"version": "22.3.0-beta.0", |
|||
"requires": { |
|||
"@angular/core": ">=21.0.0-rc.3" |
|||
}, |
|||
"description": "Update 'module' to 'preserve' and 'moduleResolution' to 'bundler' in TypeScript configurations for Angular projects.", |
|||
"factory": "./src/migrations/update-22-3-0/update-module-resolution", |
|||
"package": "@nx/angular", |
|||
"name": "set-tsconfig-option" |
|||
"name": "update-module-resolution-22-2-0" |
|||
}, |
|||
{ |
|||
"cli": "nx", |
|||
"version": "21.5.0-beta.2", |
|||
"requires": { "@angular/core": ">=20.2.0" }, |
|||
"description": "Update the @angular/cli package version to ~20.2.0.", |
|||
"factory": "./src/migrations/update-21-5-0/update-angular-cli", |
|||
"version": "22.3.0-beta.0", |
|||
"requires": { |
|||
"@angular/core": ">=21.0.0" |
|||
}, |
|||
"description": "Updates the 'lib' property in tsconfig files to use 'es2022' or a more modern version.", |
|||
"factory": "./src/migrations/update-22-3-0/update-typescript-lib", |
|||
"package": "@nx/angular", |
|||
"name": "update-angular-cli-version-20-2-0" |
|||
"name": "update-typescript-lib-22-2-0" |
|||
}, |
|||
{ |
|||
"version": "21.5.0-beta.2", |
|||
"requires": { "@angular/core": ">=20.2.0" }, |
|||
"description": "Remove any Karma configuration files that only contain the default content. The default configuration is automatically available without a specific project configurationfile.", |
|||
"factory": "./src/migrations/update-21-5-0/remove-default-karma-configuration-files", |
|||
"version": "22.3.0-beta.0", |
|||
"requires": { |
|||
"@angular/core": ">=21.0.0" |
|||
}, |
|||
"description": "Update 'vitest' unit test runner option to 'vitest-analog' in generator defaults.", |
|||
"factory": "./src/migrations/update-22-3-0/update-unit-test-runner-option", |
|||
"package": "@nx/angular", |
|||
"name": "remove-default-karma-configuration-files" |
|||
"name": "update-unit-test-runner-option" |
|||
}, |
|||
{ |
|||
"cli": "nx", |
|||
"version": "21.6.1-beta.2", |
|||
"requires": { "@angular/core": ">=20.3.0" }, |
|||
"description": "Update the @angular/cli package version to ~20.3.0.", |
|||
"factory": "./src/migrations/update-21-6-1/update-angular-cli", |
|||
"version": "22.3.0-beta.3", |
|||
"requires": { |
|||
"@angular/core": ">=21.0.0" |
|||
}, |
|||
"description": "Set 'isolatedModules' to 'true' in TypeScript test configurations for Angular projects.", |
|||
"factory": "./src/migrations/update-22-3-0/set-isolated-modules", |
|||
"package": "@nx/angular", |
|||
"name": "update-angular-cli-version-20-3-0" |
|||
"name": "set-isolated-modules-22-3-0" |
|||
}, |
|||
{ |
|||
"version": "20.2.0", |
|||
"description": "Replaces usages of the deprecated Router.getCurrentNavigation method with the Router.currentNavigation signal", |
|||
"factory": "./bundles/router-current-navigation.cjs#migrate", |
|||
"optional": true, |
|||
"package": "@angular/core", |
|||
"name": "router-current-navigation" |
|||
}, |
|||
{ |
|||
"version": "20.3.0", |
|||
"description": "Adds `BootstrapContext` to `bootstrapApplication` calls in `main.server.ts` to support server rendering.", |
|||
"factory": "./bundles/add-bootstrap-context-to-server-main.cjs#migrate", |
|||
"package": "@angular/core", |
|||
"name": "add-bootstrap-context-to-server-main" |
|||
"version": "22.3.0-beta.3", |
|||
"requires": { |
|||
"@angular/core": ">=21.0.0" |
|||
}, |
|||
"description": "Replace 'jest-preset-angular/setup-jest' imports with the new 'setupZoneTestEnv' function.", |
|||
"factory": "./src/migrations/update-22-3-0/update-jest-preset-angular-setup", |
|||
"package": "@nx/angular", |
|||
"name": "update-jest-preset-angular-setup" |
|||
} |
|||
] |
|||
} |
|||
|
|||
@ -0,0 +1,725 @@ |
|||
# Vitest 4.0 Migration Instructions for LLM |
|||
|
|||
## Overview |
|||
|
|||
These instructions guide you through migrating an Nx workspace containing multiple Vitest projects from Vitest 3.x to Vitest 4.0. Work systematically through each breaking change category. |
|||
|
|||
## Pre-Migration Checklist |
|||
|
|||
1. **Identify all Vitest projects**: |
|||
|
|||
```bash |
|||
nx show projects --with-target test |
|||
``` |
|||
|
|||
2. **Locate all Vitest configuration files**: |
|||
- Search for `vitest.config.{ts,js,mjs}` |
|||
- Search for `vitest.workspace.{ts,js,mjs}` |
|||
- Check `project.json` files for inline Vitest configuration |
|||
|
|||
3. **Identify affected code**: |
|||
- Test files: `**/*.{spec,test}.{ts,js,tsx,jsx}` |
|||
- Mock usage: Files using `vi.fn()`, `vi.spyOn()`, `vi.mock()` |
|||
- Coverage configuration references |
|||
|
|||
## Migration Steps by Category |
|||
|
|||
### 1. Configuration File Updates |
|||
|
|||
#### 1.1 Coverage Configuration |
|||
|
|||
**Search Pattern**: `coverage` in all `vitest.config.*` files and `project.json` test target options |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
export default defineConfig({ |
|||
test: { |
|||
coverage: { |
|||
all: true, |
|||
extensions: ['.ts', '.tsx'], |
|||
ignoreEmptyLines: false, |
|||
experimentalAstAwareRemapping: true, |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
export default defineConfig({ |
|||
test: { |
|||
coverage: { |
|||
// Explicitly define files to include in coverage |
|||
include: ['src/**/*.{ts,tsx}'], |
|||
// Remove: all, extensions, ignoreEmptyLines, experimentalAstAwareRemapping |
|||
}, |
|||
}, |
|||
}); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Remove `coverage.all` option |
|||
- [ ] Remove `coverage.extensions` option |
|||
- [ ] Remove `coverage.ignoreEmptyLines` option |
|||
- [ ] Remove `coverage.experimentalAstAwareRemapping` option |
|||
- [ ] Add explicit `coverage.include` patterns based on project structure |
|||
- [ ] Update any documentation referencing these options |
|||
|
|||
#### 1.2 Pool Options Restructuring |
|||
|
|||
**Search Pattern**: `poolOptions`, `maxThreads`, `maxForks`, `singleThread`, `singleFork` in all Vitest config files |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
export default defineConfig({ |
|||
test: { |
|||
maxThreads: 4, |
|||
maxForks: 2, |
|||
singleThread: false, |
|||
poolOptions: { |
|||
threads: { |
|||
useAtomics: true, |
|||
}, |
|||
vmThreads: { |
|||
memoryLimit: '512MB', |
|||
}, |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
export default defineConfig({ |
|||
test: { |
|||
maxWorkers: 4, // Consolidates maxThreads and maxForks |
|||
isolate: true, // Replaces singleThread: false |
|||
// Remove: poolOptions, threads.useAtomics |
|||
vmMemoryLimit: '512MB', // Moved to top-level |
|||
}, |
|||
}); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Replace `maxThreads` and `maxForks` with single `maxWorkers` option |
|||
- [ ] Replace `singleThread: true` or `singleFork: true` with `maxWorkers: 1, isolate: false` |
|||
- [ ] Move all `poolOptions.*` nested options to top-level (e.g., `poolOptions.vmThreads.memoryLimit` → `vmMemoryLimit`) |
|||
- [ ] Remove `threads.useAtomics` option |
|||
- [ ] Update CI environment variables: `VITEST_MAX_THREADS` and `VITEST_MAX_FORKS` → `VITEST_MAX_WORKERS` |
|||
|
|||
#### 1.3 Workspace to Projects Rename |
|||
|
|||
**Search Pattern**: `workspace` property in Vitest config files |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
export default defineConfig({ |
|||
test: { |
|||
workspace: ['apps/*', 'libs/*'], |
|||
}, |
|||
}); |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
export default defineConfig({ |
|||
test: { |
|||
projects: ['apps/*', 'libs/*'], |
|||
}, |
|||
}); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Rename `workspace` property to `projects` in all config files |
|||
- [ ] Remove external workspace file references (must be inline in config) |
|||
- [ ] Update `poolMatchGlobs` to use `projects` pattern matching instead |
|||
- [ ] Update `environmentMatchGlobs` to use `projects` pattern matching instead |
|||
|
|||
#### 1.4 Browser Configuration |
|||
|
|||
**Search Pattern**: `browser.provider`, `browser.testerScripts`, imports from `@vitest/browser` |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
export default defineConfig({ |
|||
test: { |
|||
browser: { |
|||
enabled: true, |
|||
provider: 'playwright', // String value |
|||
testerScripts: ['./setup.js'], |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
// Import changes |
|||
import { page } from '@vitest/browser'; |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
export default defineConfig({ |
|||
test: { |
|||
browser: { |
|||
enabled: true, |
|||
provider: { name: 'playwright' }, // Object value |
|||
testerHtmlPath: './test-setup.html', // Renamed from testerScripts |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
// Import changes |
|||
import { page } from 'vitest/browser'; |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Convert `browser.provider` string values to object format: `{ name: 'provider-name' }` |
|||
- [ ] Replace `browser.testerScripts` with `browser.testerHtmlPath` |
|||
- [ ] Update all imports from `@vitest/browser` to `vitest/browser` |
|||
- [ ] Remove `@vitest/browser` from dependencies if no longer needed |
|||
|
|||
#### 1.5 Deprecated Configuration Options |
|||
|
|||
**Search Pattern**: `deps.external`, `deps.inline`, `deps.fallbackCJS` in config files |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
export default defineConfig({ |
|||
test: { |
|||
deps: { |
|||
external: ['some-package'], |
|||
inline: ['inline-package'], |
|||
fallbackCJS: true, |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
export default defineConfig({ |
|||
test: { |
|||
server: { |
|||
deps: { |
|||
external: ['some-package'], |
|||
inline: ['inline-package'], |
|||
fallbackCJS: true, |
|||
}, |
|||
}, |
|||
}, |
|||
}); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Move `deps.*` options under `server.deps` namespace |
|||
- [ ] Remove `poolMatchGlobs` (use `projects` with conditions instead) |
|||
- [ ] Remove `environmentMatchGlobs` (use `projects` with conditions instead) |
|||
|
|||
### 2. Test Code Updates |
|||
|
|||
#### 2.1 Mock Function Name Changes |
|||
|
|||
**Search Pattern**: `.getMockName()` calls in test files |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
const mockFn = vi.fn(); |
|||
expect(mockFn.getMockName()).toBe('spy'); // Old default |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
const mockFn = vi.fn(); |
|||
expect(mockFn.getMockName()).toBe('vi.fn()'); // New default |
|||
|
|||
// If you need custom names, set them explicitly |
|||
const namedMock = vi.fn().mockName('myCustomName'); |
|||
expect(namedMock.getMockName()).toBe('myCustomName'); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Update test assertions checking default mock names from `'spy'` to `'vi.fn()'` |
|||
- [ ] Add explicit `.mockName()` calls where specific names are required |
|||
|
|||
#### 2.2 Mock Invocation Call Order |
|||
|
|||
**Search Pattern**: `.mock.invocationCallOrder` in test files |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
const mockFn = vi.fn(); |
|||
mockFn(); |
|||
expect(mockFn.mock.invocationCallOrder[0]).toBe(0); // Started at 0 |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
const mockFn = vi.fn(); |
|||
mockFn(); |
|||
expect(mockFn.mock.invocationCallOrder[0]).toBe(1); // Now starts at 1 (Jest-compatible) |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Update assertions on `invocationCallOrder` to account for 1-based indexing |
|||
- [ ] Search for off-by-one errors in call order comparisons |
|||
|
|||
#### 2.3 Constructor Spies and Mocks |
|||
|
|||
**Search Pattern**: `vi.spyOn` on constructors, `vi.fn()` used as constructors |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) - Arrow function constructors might have worked |
|||
const MockConstructor = vi.fn(() => ({ value: 42 })); |
|||
new MockConstructor(); // May have worked in v3 |
|||
|
|||
// ✅ AFTER (Vitest 4.0) - Must use function or class |
|||
const MockConstructor = vi.fn(function () { |
|||
return { value: 42 }; |
|||
}); |
|||
new MockConstructor(); // Correctly supports 'new' |
|||
|
|||
// Or use class syntax |
|||
class MockClass { |
|||
value = 42; |
|||
} |
|||
const MockConstructor = vi.fn(MockClass); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Convert arrow function mocks used as constructors to `function` keyword or `class` syntax |
|||
- [ ] Test all constructor spies to ensure `new` keyword works correctly |
|||
- [ ] Update any mocks that expect constructor behavior |
|||
|
|||
#### 2.4 RestoreAllMocks Behavior |
|||
|
|||
**Search Pattern**: `vi.restoreAllMocks()` in test files |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
vi.mock('./module', () => ({ fn: vi.fn() })); |
|||
vi.restoreAllMocks(); // Would restore automocks |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
vi.mock('./module', () => ({ fn: vi.fn() })); |
|||
vi.restoreAllMocks(); // Only restores manual spies, NOT automocks |
|||
|
|||
// To reset automocks, use: |
|||
vi.unmock('./module'); |
|||
// or |
|||
vi.resetModules(); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Review all `vi.restoreAllMocks()` usage |
|||
- [ ] Add explicit `vi.unmock()` or `vi.resetModules()` calls for automocked modules |
|||
- [ ] Ensure test isolation is maintained after this change |
|||
|
|||
#### 2.5 SpyOn Return Value Changes |
|||
|
|||
**Search Pattern**: `vi.spyOn()` on already mocked functions |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
const mock = vi.fn(); |
|||
const spy = vi.spyOn({ method: mock }, 'method'); |
|||
// spy !== mock (created new spy) |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
const mock = vi.fn(); |
|||
const spy = vi.spyOn({ method: mock }, 'method'); |
|||
// spy === mock (returns same instance) |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Review code that creates spies on existing mocks |
|||
- [ ] Remove redundant spy creation if same instance is returned |
|||
- [ ] Update assertions that check spy identity |
|||
|
|||
#### 2.6 Automock Behavior Changes |
|||
|
|||
**Search Pattern**: `vi.mock()` with factory functions, `.mockRestore()` on automocks |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
vi.mock('./utils', () => ({ |
|||
get value() { |
|||
return 42; |
|||
}, // Would call getter |
|||
})); |
|||
|
|||
import { value } from './utils'; |
|||
console.log(value); // Would execute getter logic |
|||
|
|||
// Restore might have worked |
|||
const spy = vi.spyOn(obj, 'method'); |
|||
spy.mockRestore(); // Might work on automocks |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
vi.mock('./utils', () => ({ |
|||
get value() { |
|||
return 42; |
|||
}, |
|||
})); |
|||
|
|||
import { value } from './utils'; |
|||
console.log(value); // Returns undefined (doesn't call getter) |
|||
|
|||
// Explicitly return value if needed |
|||
vi.mock('./utils', () => ({ |
|||
value: 42, // Not a getter |
|||
})); |
|||
|
|||
// mockRestore no longer works on automocks |
|||
const spy = vi.spyOn(obj, 'method'); |
|||
spy.mockRestore(); // Throws error if method is automocked |
|||
|
|||
// Use unmock instead |
|||
vi.unmock('./module'); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Convert automocked getters to plain property values where needed |
|||
- [ ] Remove `.mockRestore()` calls on automocked methods |
|||
- [ ] Use `vi.unmock()` to clear automocks instead |
|||
- [ ] Test instance method isolation (they now share state with prototype) |
|||
|
|||
#### 2.7 Settled Results Immediate Population |
|||
|
|||
**Search Pattern**: `.mock.settledResults` in test files |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ✅ AFTER (Vitest 4.0) |
|||
const asyncMock = vi.fn(async () => 'result'); |
|||
const promise = asyncMock(); |
|||
|
|||
// settledResults is immediately populated with 'incomplete' status |
|||
expect(asyncMock.mock.settledResults[0]).toEqual({ |
|||
type: 'incomplete', |
|||
value: undefined, |
|||
}); |
|||
|
|||
// After promise resolves |
|||
await promise; |
|||
expect(asyncMock.mock.settledResults[0]).toEqual({ |
|||
type: 'fulfilled', |
|||
value: 'result', |
|||
}); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Update tests that check `settledResults` before promise resolution |
|||
- [ ] Handle `'incomplete'` status in assertions |
|||
- [ ] Ensure tests properly await promises before checking settled results |
|||
|
|||
### 3. Reporter and CLI Changes |
|||
|
|||
#### 3.1 Reporter API Changes |
|||
|
|||
**Search Pattern**: Custom reporters, `onCollected`, `onTaskUpdate`, `onFinished` |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
export default { |
|||
onCollected(files) { |
|||
// Handle collected files |
|||
}, |
|||
onTaskUpdate(task) { |
|||
// Handle task update |
|||
}, |
|||
onFinished(files) { |
|||
// Handle completion |
|||
}, |
|||
}; |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
// Use new reporter API - consult Vitest 4 docs for replacement methods |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Review custom reporters for removed API usage |
|||
- [ ] Consult Vitest 4 documentation for new reporter API |
|||
- [ ] Update or rewrite custom reporters to use new APIs |
|||
|
|||
#### 3.2 Built-in Reporter Changes |
|||
|
|||
**Search Pattern**: `reporters: ['basic']`, `reporters: ['verbose']` |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
export default defineConfig({ |
|||
test: { |
|||
reporters: ['basic'], |
|||
}, |
|||
}); |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
export default defineConfig({ |
|||
test: { |
|||
reporters: [['default', { summary: false }]], // Equivalent to 'basic' |
|||
}, |
|||
}); |
|||
|
|||
// For verbose (tree output) |
|||
reporters: ['tree']; // Use 'tree' for hierarchical output |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Replace `'basic'` reporter with `['default', { summary: false }]` |
|||
- [ ] Replace `'verbose'` reporter with `'tree'` for hierarchical output |
|||
- [ ] Update CI configuration if reporters are specified there |
|||
|
|||
### 4. Snapshot Changes |
|||
|
|||
#### 4.1 Custom Elements Shadow Root |
|||
|
|||
**Search Pattern**: Snapshot tests involving custom elements or Web Components |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ✅ AFTER (Vitest 4.0) |
|||
// Shadow root contents now printed by default in snapshots |
|||
|
|||
// If you want old behavior (don't print shadow root): |
|||
export default defineConfig({ |
|||
test: { |
|||
printShadowRoot: false, |
|||
}, |
|||
}); |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Review snapshot tests for custom elements |
|||
- [ ] Update snapshots if shadow root contents are now included |
|||
- [ ] Add `printShadowRoot: false` if old behavior is required |
|||
|
|||
### 5. Environment Variable Updates |
|||
|
|||
**Search Pattern**: CI/CD configuration files, `.env` files, documentation |
|||
|
|||
**Changes Required**: |
|||
|
|||
```bash |
|||
# ❌ BEFORE (Vitest 3.x) |
|||
VITEST_MAX_THREADS=4 |
|||
VITEST_MAX_FORKS=2 |
|||
VITE_NODE_DEPS_MODULE_DIRECTORIES=/custom/path |
|||
|
|||
# ✅ AFTER (Vitest 4.0) |
|||
VITEST_MAX_WORKERS=4 |
|||
VITEST_MODULE_DIRECTORIES=/custom/path |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Update CI/CD pipeline environment variables |
|||
- [ ] Update `.env` files |
|||
- [ ] Update documentation referencing old environment variables |
|||
- [ ] Search for `VITEST_MAX_THREADS`, `VITEST_MAX_FORKS`, `VITE_NODE_DEPS_MODULE_DIRECTORIES` |
|||
|
|||
### 6. Advanced: Module Runner Changes |
|||
|
|||
**Search Pattern**: `vitest/execute`, `__vitest_executor`, `vite-node` |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// ❌ BEFORE (Vitest 3.x) |
|||
import { execute } from 'vitest/execute'; |
|||
// Access to __vitest_executor |
|||
|
|||
// ✅ AFTER (Vitest 4.0) |
|||
// Use Vite's Module Runner API instead |
|||
// Consult Vite Module Runner documentation |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] If using `vitest/execute`, migrate to Vite Module Runner |
|||
- [ ] Remove dependencies on `__vitest_executor` |
|||
- [ ] Update custom pool implementations (complete rewrite needed) |
|||
|
|||
### 7. Type Definition Updates |
|||
|
|||
**Search Pattern**: TypeScript imports from `vitest`, type errors after upgrade |
|||
|
|||
**Changes Required**: |
|||
|
|||
```typescript |
|||
// All deprecated type exports removed |
|||
// If you get TypeScript errors about missing types: |
|||
// - Check if you're using deprecated type names |
|||
// - Update to current type names from Vitest 4 API |
|||
// - Remove explicit @types/node if it was only needed due to Vitest bug |
|||
``` |
|||
|
|||
**Action Items**: |
|||
|
|||
- [ ] Run TypeScript compilation on all test files |
|||
- [ ] Fix any type errors related to removed Vitest type definitions |
|||
- [ ] Review `@types/node` usage (may no longer be accidentally included) |
|||
|
|||
## Post-Migration Validation |
|||
|
|||
### 1. Run Tests Per Project |
|||
|
|||
```bash |
|||
# Test each project individually |
|||
nx run-many -t test -p PROJECT_NAME |
|||
``` |
|||
|
|||
### 2. Run All Tests |
|||
|
|||
```bash |
|||
# Run tests across all affected projects |
|||
nx affected -t test |
|||
``` |
|||
|
|||
### 3. Check Coverage |
|||
|
|||
```bash |
|||
# Verify coverage generation works with new config |
|||
nx affected -t test --coverage |
|||
``` |
|||
|
|||
### 4. Validate CI Pipeline |
|||
|
|||
```bash |
|||
# Run full CI validation |
|||
nx prepush |
|||
``` |
|||
|
|||
### 5. Review Migration Checklist |
|||
|
|||
- [ ] All configuration files updated |
|||
- [ ] All test files pass |
|||
- [ ] Coverage reports generate correctly |
|||
- [ ] CI/CD pipeline runs successfully |
|||
- [ ] Environment variables updated |
|||
- [ ] Documentation updated |
|||
- [ ] No deprecated API warnings in console |
|||
|
|||
## Common Issues and Solutions |
|||
|
|||
### Issue: Coverage includes too many files |
|||
|
|||
**Solution**: Add explicit `coverage.include` patterns to match your source files |
|||
|
|||
### Issue: Tests fail with "arrow function constructors not supported" |
|||
|
|||
**Solution**: Convert arrow functions used as constructors to `function` keyword or `class` syntax |
|||
|
|||
### Issue: Automocks not resetting between tests |
|||
|
|||
**Solution**: Use `vi.unmock()` or `vi.resetModules()` instead of `vi.restoreAllMocks()` |
|||
|
|||
### Issue: Mock call order assertions failing |
|||
|
|||
**Solution**: Update to 1-based indexing for `invocationCallOrder` |
|||
|
|||
### Issue: Browser tests failing after upgrade |
|||
|
|||
**Solution**: Check browser provider is object format and imports use `vitest/browser` |
|||
|
|||
### Issue: TypeScript errors in test files |
|||
|
|||
**Solution**: Update to new type definitions and remove usage of deprecated types |
|||
|
|||
## Files to Review |
|||
|
|||
Create a checklist of all files that need review: |
|||
|
|||
```bash |
|||
# Configuration files |
|||
find . -name "vitest.config.*" -o -name "vitest.workspace.*" |
|||
find . -name "project.json" -exec grep -l "vitest" {} \; |
|||
|
|||
# Test files |
|||
find . -name "*.spec.*" -o -name "*.test.*" |
|||
|
|||
# Files with mock usage |
|||
rg "vi\.(fn|spyOn|mock|restoreAllMocks)" --type ts --type tsx --type js |
|||
|
|||
# Files with coverage config |
|||
rg "coverage\.(all|extensions|ignoreEmptyLines)" --type ts --type js |
|||
|
|||
# CI configuration |
|||
find . -name ".github/workflows/*.yml" -o -name ".gitlab-ci.yml" -o -name "azure-pipelines.yml" |
|||
``` |
|||
|
|||
## Migration Strategy for Large Workspaces |
|||
|
|||
1. **Migrate in phases**: Start with a small project, validate, then expand |
|||
2. **Use feature branches**: Create separate branches for different migration aspects |
|||
3. **Run tests frequently**: After each configuration change, run affected tests |
|||
4. **Document issues**: Keep track of project-specific issues and solutions |
|||
5. **Automate where possible**: Create codemods for repetitive changes |
|||
|
|||
## Useful Commands During Migration |
|||
|
|||
```bash |
|||
# Find all vitest configurations |
|||
nx show projects --with-target test |
|||
|
|||
# Test specific project after changes |
|||
nx test PROJECT_NAME |
|||
|
|||
# Test all affected |
|||
nx affected -t test |
|||
|
|||
# View project details |
|||
nx show project PROJECT_NAME --web |
|||
|
|||
# Clear Nx cache if needed |
|||
nx reset |
|||
``` |
|||
|
|||
## Guard Rails |
|||
|
|||
DO NOT |
|||
|
|||
- Force tests to pass by removing test logic and replacing it with `expect(true).toBe(true)` |
|||
- Remove assertions |
|||
- Add additional mocks that force tests to pass |
|||
|
|||
--- |
|||
|
|||
## Notes for LLM Execution |
|||
|
|||
When executing this migration: |
|||
|
|||
1. **Work systematically**: Complete one category before moving to the next |
|||
2. **Test after each change**: Don't batch all changes without validation |
|||
3. **Keep user informed**: Report progress through each section |
|||
4. **Handle errors promptly**: If tests fail, fix immediately before proceeding |
|||
5. **Update documentation**: Note any workspace-specific patterns or issues |
|||
6. **Create meaningful commits**: Group related changes together with clear messages |
|||
7. **Use TodoWrite tool**: Track migration progress for visibility |
|||
Loading…
Reference in new issue