-
-
Notifications
You must be signed in to change notification settings - Fork 140
/
index.ts
119 lines (100 loc) · 4.49 KB
/
index.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
import type { PackageJson } from '#p/types/package-json.js';
import type { IsPluginEnabled, Plugin, PluginOptions, ResolveConfig, ResolveEntryPaths } from '#p/types/plugins.js';
import { isAbsolute, join, relative } from '#p/util/path.js';
import { hasDependency, tryResolve } from '#p/util/plugin.js';
import { toEntryPattern } from '#p/util/protocols.js';
import { getEnvPackageName, getExternalReporters } from './helpers.js';
import type { COMMAND, MODE, ViteConfig, ViteConfigOrFn, VitestWorkspaceConfig } from './types.js';
// https://vitest.dev/config/
const title = 'Vitest';
const enablers = ['vitest'];
const isEnabled: IsPluginEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
const config = ['vitest*.config.{js,mjs,ts,cjs,mts,cts}', 'vitest.{workspace,projects}.{ts,js,json}'];
const entry = ['**/*.{bench,test,test-d,spec}.?(c|m)[jt]s?(x)'];
const resolveEntry = (options: PluginOptions, rootDir: string, specifier: string) => {
const { configFileDir, configFileName } = options;
const resolvedPath = isAbsolute(specifier)
? specifier
: tryResolve(join(configFileDir, rootDir, specifier), join(configFileDir, rootDir, configFileName));
if (resolvedPath) return toEntryPattern(relative(configFileDir, resolvedPath));
return specifier;
};
const isVitestCoverageCommand = /vitest(.+)--coverage(?:\.enabled(?:=true)?)?/;
const hasScriptWithCoverage = (scripts: PackageJson['scripts']) =>
scripts
? Object.values(scripts).some(script => {
return isVitestCoverageCommand.test(script);
})
: false;
const findConfigDependencies = (localConfig: ViteConfig, options: PluginOptions) => {
const { manifest } = options;
const testConfig = localConfig.test;
if (!testConfig) return [];
const environments =
testConfig.environment && testConfig.environment !== 'node' ? [getEnvPackageName(testConfig.environment)] : [];
const reporters = getExternalReporters(testConfig.reporters);
const hasCoverageEnabled =
(testConfig.coverage && testConfig.coverage.enabled !== false) || hasScriptWithCoverage(manifest.scripts);
const coverage = hasCoverageEnabled ? [`@vitest/coverage-${testConfig.coverage?.provider ?? 'v8'}`] : [];
const rootDir = testConfig.root ?? '.';
const setupFiles = [testConfig.setupFiles ?? []].flat().map(v => resolveEntry(options, rootDir, v));
const globalSetup = [testConfig.globalSetup ?? []].flat().map(v => resolveEntry(options, rootDir, v));
return [...environments, ...reporters, ...coverage, ...setupFiles, ...globalSetup];
};
const getConfigs = async (localConfig: ViteConfigOrFn | VitestWorkspaceConfig) => {
const configs: ViteConfig[] = [];
for (const config of [localConfig].flat()) {
if (config && typeof config !== 'string') {
if (typeof config === 'function') {
for (const command of ['dev', 'serve', 'build'] as COMMAND[]) {
for (const mode of ['development', 'production'] as MODE[]) {
const cfg = await config({ command, mode, ssrBuild: undefined });
configs.push(cfg);
}
}
} else {
configs.push(config);
}
}
}
return configs;
};
export const resolveEntryPaths: ResolveEntryPaths<ViteConfigOrFn | VitestWorkspaceConfig> = async (
localConfig,
options
) => {
const dependencies = new Set<string>();
const configs = await getConfigs(localConfig);
for (const cfg of configs) {
const rootDir = cfg.test?.root ?? '.';
if (cfg.test?.include) {
for (const dependency of cfg.test.include) dependencies.add(join(rootDir, dependency));
} else {
for (const dependency of options.config.entry ?? entry) dependencies.add(join(rootDir, dependency));
}
}
return Array.from(dependencies).map(toEntryPattern);
};
export const resolveConfig: ResolveConfig<ViteConfigOrFn | VitestWorkspaceConfig> = async (localConfig, options) => {
const dependencies = new Set<string>();
const configs = await getConfigs(localConfig);
for (const cfg of configs) {
for (const dependency of findConfigDependencies(cfg, options)) dependencies.add(dependency);
const entry = cfg.build?.lib?.entry ?? [];
const rootDir = cfg.test?.root ?? '.';
const deps = (typeof entry === 'string' ? [entry] : Object.values(entry)).map(specifier =>
resolveEntry(options, rootDir, specifier)
);
for (const dependency of deps) dependencies.add(dependency);
}
return Array.from(dependencies);
};
export default {
title,
enablers,
isEnabled,
config,
entry,
resolveEntryPaths,
resolveConfig,
} satisfies Plugin;