Repository navigation
Expand file tree
/
Copy pathvitest.config.ts
More file actions
139 lines (125 loc) · 4.44 KB
/
Copy pathvitest.config.ts
File metadata and controls
139 lines (125 loc) · 4.44 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
import { globSync, readFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { loadConfigFromFile } from 'vite';
import type { TestProjectConfiguration, UserWorkspaceConfig } from 'vitest/config';
import { configDefaults, defineConfig } from 'vitest/config';
// Directories to exclude from project discovery
const EXCLUDED_DIRS = new Set([
'packages/_config',
'packages/_types-builder',
'packages/_vendored',
'server-adapters/server-adapters-test-suite',
'browser/_test-utils',
'workspaces/_test-utils',
'observability/_examples',
// Standalone private app: not a pnpm workspace member, so its dependencies
// are never installed and its suite cannot resolve them (e.g. `hono`).
'mastracode/web',
]);
// Directories to scan for vitest configs
const PROJECT_GLOBS = [
'packages/*/vitest.config.ts',
'packages/playground/vercel-preview/vitest.config.ts',
'stores/*/vitest.config.ts',
'deployers/*/vitest.config.ts',
'voice/*/vitest.config.ts',
'server-adapters/*/vitest.config.ts',
'client-sdks/*/vitest.config.ts',
'auth/*/vitest.config.ts',
'observability/*/vitest.config.ts',
'pubsub/*/vitest.config.ts',
'signals/*/vitest.config.ts',
'workflows/*/vitest.config.ts',
'code-mode/*/vitest.config.ts',
'integrations/*/vitest.config.ts',
'channels/*/vitest.config.ts',
'browser/*/vitest.config.ts',
'workspaces/*/vitest.config.ts',
'agent-sdks/*/vitest.config.ts',
'mastracode/*/vitest.config.ts',
];
/**
* Discovers all vitest projects from package configs.
* For configs with nested projects, expands them with the correct root path.
* For simple configs, returns the directory as a project path.
*/
async function discoverProjects(): Promise<TestProjectConfiguration[]> {
const projects: TestProjectConfiguration[] = [];
// Find all vitest.config.ts files
const configPaths = PROJECT_GLOBS.flatMap(pattern => {
const matches = globSync(pattern);
if (matches.length === 0) {
throw new Error(`Vitest project glob matched no configs: ${pattern}`);
}
return matches;
});
for (const configPath of configPaths) {
const projectDir = dirname(configPath);
// Skip excluded directories
if (EXCLUDED_DIRS.has(projectDir)) {
continue;
}
// Match workspace test:unit scripts; integration suites keep their package-local CI jobs.
if (projectDir.startsWith('workspaces/')) {
projects.push({
extends: resolve(configPath),
test: {
name: `unit:${projectDir}`,
root: resolve(projectDir),
exclude: [...configDefaults.exclude, '**/*.integration.test.ts'],
},
});
continue;
}
// Read the config file to check if it has nested projects
const configContent = readFileSync(configPath, 'utf-8');
const hasNestedProjects = /test:\s*\{[\s\S]*?projects:\s*\[/.test(configContent);
if (!hasNestedProjects) {
// Simple config - use directory path
projects.push(projectDir);
continue;
}
// Config has nested projects - load it using Vite's config loader
try {
const absolutePath = resolve(process.cwd(), configPath);
const loaded = await loadConfigFromFile({} as any, absolutePath);
if (!loaded) {
projects.push(projectDir);
continue;
}
const config = loaded.config as UserWorkspaceConfig;
if (!config.test?.projects) {
// Fallback if config parsing didn't work as expected
projects.push(projectDir);
continue;
}
// Expand nested projects with root path
for (const nestedProject of config.test.projects) {
if (typeof nestedProject === 'string') {
// String reference - resolve relative to the config's directory
projects.push(`${projectDir}/${nestedProject}`);
} else {
// Inline project config - add root path
const projectConfig = nestedProject as UserWorkspaceConfig;
projects.push({
...projectConfig,
test: {
...projectConfig.test,
root: `./${projectDir}`,
},
});
}
}
} catch (error) {
// If we can't import the config, fall back to using the directory path
console.warn(`Warning: Could not import ${configPath}, using directory path instead:`, error);
projects.push(projectDir);
}
}
return projects;
}
export default defineConfig(async () => ({
test: {
projects: await discoverProjects(),
},
}));