-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvitest.config.ts
More file actions
156 lines (143 loc) · 4.85 KB
/
vitest.config.ts
File metadata and controls
156 lines (143 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { defineConfig } from 'vitest/config';
import path from 'path';
import fs from 'fs';
export default defineConfig({
test: {
globals: true,
environment: 'node',
// FIX: Use explicit paths instead of ** to avoid scanning node_modules
// This prevents the "hang" during file discovery when vitest tries to scan all directories
include: [
'packages/**/*.test.ts',
],
exclude: [
'node_modules/**',
'dist/**',
'_bmad-output/**', // Output directory
'**/node_modules/**',
// Performance tests - run separately in dedicated job
'tests/performance/**',
// Backup directories - excluded to prevent duplicate tests
'team/backups/**',
// Reference directory - contains tests with missing dependencies (openclaw/plugin-sdk)
'reference/**',
],
coverage: {
provider: 'istanbul', // Better TypeScript source map support than v8
reporter: ['text', 'json', 'html', 'json-summary'],
include: [
'packages/core/src/**/*.ts',
],
exclude: [
'**/*.d.ts',
'node_modules/**',
'dist/**',
'packages/*/tests/**'
],
// Istanbul coverage options
all: true,
extension: ['.js', '.ts', '.jsx', '.tsx'],
// Source map handling for TypeScript
usePerFileCoverage: true,
},
testTimeout: 30000,
hookTimeout: 30000,
setupFiles: ['./tests/vitest-setup.js'],
// VAL-11-001: Use separate forks per test file to prevent OOM from memory accumulation
// Use multiple workers for speed, but with proper teardown to avoid worker exit issues
pool: 'forks',
poolOptions: {
forks: {
singleFork: false,
execArgv: ['--max-old-space-size=8192', '--expose-gc']
}
},
isolate: true,
maxConcurrency: 1,
minWorkers: 1,
maxWorkers: 1,
// Force garbage collection between test files to reduce memory pressure
sequence: {
hooks: {
// Only run afterAll/afterEach hooks in the same worker
}
}
},
resolve: {
alias: {
'@framework': path.resolve(__dirname, '_bmad/framework'),
'@validators': path.resolve(__dirname, '.claude/validators-node/src'),
'@bmad/validators': path.resolve(__dirname, '.claude/validators-node/src'),
'@bmad': path.resolve(__dirname, '_bmad'),
},
},
plugins: [
{
name: 'resolve-test-imports',
resolveId(source, importer) {
// Only handle imports from test files in tests/utility/tools/
if (!importer || !importer.includes('/tests/utility/tools/')) {
return null;
}
// Handle relative imports (both ./ and ../)
if (!source.startsWith('./') && !source.startsWith('../')) {
return null;
}
// Skip if already resolving a .test.js file
if (source.endsWith('.test.js')) {
return null;
}
// Get the directory containing the importer
const importerDir = path.dirname(importer);
// Resolve the relative path
const resolvedTestPath = path.resolve(importerDir, source);
// Map the resolved path from tests/ to src/
if (resolvedTestPath.includes('/tests/utility/tools/')) {
const sourcePath = resolvedTestPath.replace('/tests/utility/tools/', '/src/utility/tools/');
// Check if source file exists
if (fs.existsSync(sourcePath)) {
return sourcePath;
}
}
return null;
}
},
{
name: 'resolve-packages-js-to-ts',
resolveId(source, importer) {
// Handle imports from packages/*/tests/ that use .js extension for .ts files
// This is needed for NodeNext moduleResolution where .ts files use .js in imports
if (!importer || !importer.includes('/packages/') || !importer.includes('/tests/')) {
return null;
}
// Only handle relative imports
if (!source.startsWith('./') && !source.startsWith('../')) {
return null;
}
// Only process .js extension imports
if (!source.endsWith('.js')) {
return null;
}
// Resolve the full path
const importerDir = path.dirname(importer);
const resolvedJsPath = path.resolve(importerDir, source);
const resolvedTsPath = resolvedJsPath.replace(/\.js$/, '.ts');
// If .ts file exists, return it
if (fs.existsSync(resolvedTsPath)) {
return resolvedTsPath;
}
return null;
}
}
],
esbuild: {
target: 'node18'
},
// Suppress source map warnings for validators-node src files
// Source maps are generated in dist/ during build, tests run from src/
sourcemap: {
ignore: ['**/.claude/validators-node/src/**/*.ts']
},
// Don't fail on unhandled errors - worker exit from E2E subprocesses is expected
failOnUnhandledErrors: false
});