This repository has been archived by the owner on Sep 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
vitest.shared.ts
155 lines (139 loc) · 6.05 KB
/
vitest.shared.ts
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
import path from 'path'
import { defineProject, mergeConfig, type UserConfig, type UserWorkspaceConfig } from 'vitest/config'
/** Whether we're running in Bazel. */
export const BAZEL = !!process.env.BAZEL
/** Use .js extension when running in Bazel. */
const TS_EXT = BAZEL ? 'js' : 'ts'
/**
* Default configuration for a project in a workspace.
*/
export const defaultProjectConfig: UserWorkspaceConfig = {
logLevel: 'warn',
clearScreen: false,
test: {
testTimeout: 10000,
hookTimeout: 1000,
pool: 'vmThreads',
include: [`**/*.test.${TS_EXT}?(x)`],
exclude: [
'**/integration-test',
'**/integration',
'**/end-to-end',
'**/regression',
'**/node_modules',
'**/dist',
'**/out',
'.git',
'**/.cache',
'**/*.runfiles/__main__', // for Bazel
'**/testSetup.test.[jt]s',
],
css: { modules: { classNameStrategy: 'non-scoped' } },
hideSkippedTests: true,
setupFiles: [path.join(BAZEL ? process.cwd() : __dirname, `client/testing/src/perTestSetup.${TS_EXT}`)],
globalSetup: [path.join(BAZEL ? process.cwd() : __dirname, `client/testing/src/globalTestSetup.${TS_EXT}`)],
},
plugins: BAZEL
? [
{
// In Bazel, `.module.scss` files have already been built to `.module.css` files,
// so we need to import those instead.
name: 'import-module-css-not-scss',
enforce: 'post',
resolveId(id, importer) {
if (id.endsWith('.module.scss')) {
return { id: path.join(importer ?? '', '..', id.replace('.module.scss', '.module.css')) }
}
return undefined
},
},
]
: undefined,
}
/**
* Configuration that applies to the entire workspace.
*/
const userConfig: UserConfig = {
test: {
cache: BAZEL ? false : undefined, // don't cache in Bazel
poolOptions: {
vmThreads: {
minThreads: 1, // Otherwise it's slow when there are many CPU cores
maxThreads: 8, // Warning: setting this value to 16 leads to "Error: Failed to terminate worker"
},
},
teardownTimeout: 1000,
// For compatibility with Jest's defaults; can be changed to the Vitest defaults.
snapshotFormat: {
escapeString: true,
printBasicPrototype: true,
},
reporters: ['basic'],
resolveSnapshotPath: BAZEL ? bazelResolveSnapshotPath : undefined,
},
}
export function defineProjectWithDefaults(dir: string, config: UserWorkspaceConfig): UserWorkspaceConfig {
const name = path.basename(dir)
if (!config.test) {
config.test = {}
}
if (!config.test.name) {
config.test.name = name
}
if (!config.test.root) {
// Reorient the dir around process.cwd() if we're running in Bazel and we got a __dirname-relative path.
// https://medium.com/@Jakeherringbone/running-tools-under-bazel-8aa416e7090c
if (BAZEL && dir.startsWith(__dirname)) {
dir = path.join(process.cwd(), dir.slice(__dirname.length))
}
config.test.root = dir
}
// Use .js extensions when running in Bazel.
if (BAZEL) {
if (config.test.setupFiles) {
config.test.setupFiles = (
Array.isArray(config.test.setupFiles) ? config.test.setupFiles : [config.test.setupFiles]
).map(toJSExtension)
}
if (config.test.environmentMatchGlobs) {
config.test.environmentMatchGlobs = config.test.environmentMatchGlobs.map(([glob, env]) => [
toJSExtension(glob),
env,
])
}
}
return mergeConfig(mergeConfig(defaultProjectConfig, userConfig), defineProject(config) as UserWorkspaceConfig)
}
function toJSExtension(path: string): string {
// TODO(sqs): Because Bazel ts_project preserve_jsx seems to be broken and always transpiles
// `.tsx` to `.js`, we need to assume that `.tsx` maps to `.js` here. This means that the glob
// pattern will match more than expected (e.g., if the glob pattern `*.tsx` is rewritten here to
// `*.js`, then it would match input files with both `.ts` and `.tsx` extensions). This
// introduces disparity between running `vitest` manually and running it in Bazel, but that is
// probably OK because the "worst" that would happen is that the jsdom environment would be used
// where it was not needed. If a file needs to explicitly opt into another environment, it
// should use the `@vitest-environment` directive at the top.
return path.replace(/\.ts$/, '.js').replace(/\.tsx$/, '.js')
}
function bazelResolveSnapshotPath(testPath: string, snapshotExtension: string): string {
// TODO(bazel): drop when non-bazel removed.
// TODO(bazel): bazel runs tests on the pre-compiled .js files, non-bazel runs on .tsx files.
// This snapshot resolver edits the pre-compiled .js to snapshots assuming a .tsx extension.
// This can be removed and snapshot files renamed to .js when non-bazel is removed.
// NOTE: this assumes all snapshot tests are in .tsx files, not .ts or .jsx and will not work for non-.tsx files.
/**
* Bazel runs the tests on pre-compiled .js files so we have no way of knowing
* if the original test was .ts or .tsx. Vitest requires mapping from the test file
* name (.js in bazel, .ts[x] in non-bazel) to the snapshot file name (.ts[x].snap)
* without any additional information - if we only know the .js name we don't know
* if the snapshot is .ts or .tsx.
*
* While we need to support non-bazel we can't update the existing snapshots to .js.snap.
* For now, we require all snapshot tests use .tsx extensions.
*/
return path.join(
path.dirname(testPath),
'__snapshots__',
path.basename(testPath).replace('.js', '.tsx') + snapshotExtension
)
}