@analogjs/vitest-angular 3.0.0-alpha.8 → 3.0.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_virtual/_rolldown/runtime.js +7 -0
- package/package.json +5 -8
- package/setup-snapshots.js +71 -95
- package/setup-snapshots.js.map +1 -0
- package/setup-testbed.js +23 -29
- package/setup-testbed.js.map +1 -0
- package/setup-zone.js +90 -103
- package/setup-zone.js.map +1 -0
- package/src/index.js +3 -4
- package/src/lib/builders/build/devkit.js +22 -17
- package/src/lib/builders/build/devkit.js.map +1 -0
- package/src/lib/builders/build/plugins/angular-memory-plugin.js +51 -77
- package/src/lib/builders/build/plugins/angular-memory-plugin.js.map +1 -0
- package/src/lib/builders/build/plugins/downlevel-plugin.js +23 -22
- package/src/lib/builders/build/plugins/downlevel-plugin.js.map +1 -0
- package/src/lib/builders/build/schema.js +53 -0
- package/src/lib/builders/build/schema.js.map +1 -0
- package/src/lib/builders/build/vitest.impl.js +153 -190
- package/src/lib/builders/build/vitest.impl.js.map +1 -0
- package/src/lib/builders/test/schema.js +51 -0
- package/src/lib/builders/test/schema.js.map +1 -0
- package/src/lib/builders/test/vitest.impl.js +48 -58
- package/src/lib/builders/test/vitest.impl.js.map +1 -0
- package/src/lib/tools/package.json +2 -4
- package/src/lib/tools/src/index.js +3 -6
- package/src/lib/tools/src/schematics/setup/index.js +46 -71
- package/src/lib/tools/src/schematics/setup/index.js.map +1 -1
- package/src/lib/tools/src/schematics/utils/angular.js +16 -22
- package/src/lib/tools/src/schematics/utils/angular.js.map +1 -1
- package/src/lib/tools/src/schematics/utils/dependencies.js +34 -44
- package/src/lib/tools/src/schematics/utils/dependencies.js.map +1 -1
- package/src/lib/tools/src/schematics/utils/index.js +4 -8
- package/src/lib/tools/src/schematics/utils/versions.d.ts +1 -1
- package/src/lib/tools/src/schematics/utils/versions.js +17 -12
- package/src/lib/tools/src/schematics/utils/versions.js.map +1 -1
- package/src/lib/tools/src/schematics/utils/workspace.js +14 -17
- package/src/lib/tools/src/schematics/utils/workspace.js.map +1 -1
- package/src/lib/tools/src/test-global-setup.d.ts +1 -0
- package/README.md +0 -297
- package/src/lib/builders/build/schema.json +0 -47
- package/src/lib/builders/build/utils.js +0 -1
- package/src/lib/builders/test/schema.json +0 -47
- package/src/lib/tools/src/index.js.map +0 -1
- package/src/lib/tools/src/schematics/utils/index.js.map +0 -1
|
@@ -1,197 +1,160 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { __require } from "../../../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { createAngularMemoryPlugin } from "./plugins/angular-memory-plugin.js";
|
|
3
|
+
import { downlevelPlugin } from "./plugins/downlevel-plugin.js";
|
|
4
|
+
import { getBuildApplicationFunction } from "./devkit.js";
|
|
5
|
+
import { createBuilder } from "@angular-devkit/architect";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import { globSync } from "tinyglobby";
|
|
8
|
+
//#region packages/vitest-angular/src/lib/builders/build/vitest.impl.ts
|
|
9
|
+
var ResultKind = /* @__PURE__ */ function(ResultKind) {
|
|
10
|
+
ResultKind[ResultKind["Failure"] = 0] = "Failure";
|
|
11
|
+
ResultKind[ResultKind["Full"] = 1] = "Full";
|
|
12
|
+
ResultKind[ResultKind["Incremental"] = 2] = "Incremental";
|
|
13
|
+
ResultKind[ResultKind["ComponentUpdate"] = 3] = "ComponentUpdate";
|
|
14
|
+
return ResultKind;
|
|
15
|
+
}({});
|
|
16
|
+
process.env["VITE_CJS_IGNORE_WARNING"] = "true";
|
|
15
17
|
async function* vitestApplicationBuilder(options, context) {
|
|
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
|
-
else {
|
|
96
|
-
Object.keys(buildOutput.files).forEach((key) => {
|
|
97
|
-
outputFiles.set(key, buildOutput.files[key]);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (options.watch) {
|
|
102
|
-
if (!server) {
|
|
103
|
-
server = await startVitest('test', [], config, viteConfig);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
await server.start([]);
|
|
107
|
-
}
|
|
108
|
-
yield { success: true };
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
server = await startVitest('test', [], config, viteConfig);
|
|
112
|
-
const success = server?.state.getCountOfFailedTests() === 0;
|
|
113
|
-
yield { success };
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
yield { success: true };
|
|
18
|
+
process.env["TEST"] = "true";
|
|
19
|
+
process.env["VITEST"] = "true";
|
|
20
|
+
const { buildApplicationInternal, angularVersion } = await getBuildApplicationFunction();
|
|
21
|
+
const { startVitest } = await Function("return import(\"vitest/node\")")();
|
|
22
|
+
const projectConfig = await context.getProjectMetadata(context.target);
|
|
23
|
+
const extraArgs = await getExtraArgs(options);
|
|
24
|
+
const workspaceRoot = context.workspaceRoot;
|
|
25
|
+
const projectRoot = projectConfig["root"];
|
|
26
|
+
const setupFile = path.relative(projectRoot, options.setupFile);
|
|
27
|
+
const config = {
|
|
28
|
+
root: `${projectRoot || "."}`,
|
|
29
|
+
watch: options.watch === true,
|
|
30
|
+
config: options.configFile,
|
|
31
|
+
setupFiles: [setupFile],
|
|
32
|
+
globals: true,
|
|
33
|
+
pool: "vmThreads",
|
|
34
|
+
reporters: ["default"],
|
|
35
|
+
environment: "jsdom",
|
|
36
|
+
exclude: options?.exclude || [],
|
|
37
|
+
...extraArgs
|
|
38
|
+
};
|
|
39
|
+
const includes = findIncludes({
|
|
40
|
+
workspaceRoot,
|
|
41
|
+
projectRoot,
|
|
42
|
+
include: options.include,
|
|
43
|
+
exclude: options.exclude || []
|
|
44
|
+
});
|
|
45
|
+
const entryPoints = generateEntryPoints({
|
|
46
|
+
projectRoot,
|
|
47
|
+
testFiles: [path.relative(workspaceRoot, options.setupFile), ...includes.map((inc) => path.relative(workspaceRoot, inc))],
|
|
48
|
+
context,
|
|
49
|
+
angularVersion
|
|
50
|
+
});
|
|
51
|
+
const outputFiles = /* @__PURE__ */ new Map();
|
|
52
|
+
const viteConfig = { plugins: [await createAngularMemoryPlugin({
|
|
53
|
+
angularVersion,
|
|
54
|
+
workspaceRoot,
|
|
55
|
+
outputFiles
|
|
56
|
+
}), downlevelPlugin()] };
|
|
57
|
+
let server;
|
|
58
|
+
for await (const buildOutput of buildApplicationInternal({
|
|
59
|
+
aot: false,
|
|
60
|
+
index: false,
|
|
61
|
+
progress: false,
|
|
62
|
+
prerender: false,
|
|
63
|
+
optimization: false,
|
|
64
|
+
outputPath: `.angular/.vitest/${projectConfig["name"]}`,
|
|
65
|
+
outExtension: "mjs",
|
|
66
|
+
outputHashing: 2,
|
|
67
|
+
tsConfig: path.relative(workspaceRoot, options.tsConfig),
|
|
68
|
+
watch: options.watch === true,
|
|
69
|
+
entryPoints,
|
|
70
|
+
allowedCommonJsDependencies: ["@analogjs/vitest-angular/setup-zone"],
|
|
71
|
+
sourceMap: {
|
|
72
|
+
scripts: true,
|
|
73
|
+
styles: false,
|
|
74
|
+
vendor: false
|
|
75
|
+
}
|
|
76
|
+
}, context)) {
|
|
77
|
+
if (buildOutput.kind === ResultKind.Failure) return { success: false };
|
|
78
|
+
else if (buildOutput.kind === ResultKind.Incremental || buildOutput.kind === ResultKind.Full) if (buildOutput.kind === ResultKind.Full) {
|
|
79
|
+
outputFiles.clear();
|
|
80
|
+
Object.keys(buildOutput.files).forEach((key) => {
|
|
81
|
+
outputFiles.set(key, buildOutput.files[key]);
|
|
82
|
+
});
|
|
83
|
+
} else Object.keys(buildOutput.files).forEach((key) => {
|
|
84
|
+
outputFiles.set(key, buildOutput.files[key]);
|
|
85
|
+
});
|
|
86
|
+
if (options.watch) {
|
|
87
|
+
if (!server) server = await startVitest("test", [], config, viteConfig);
|
|
88
|
+
else await server.start([]);
|
|
89
|
+
yield { success: true };
|
|
90
|
+
} else {
|
|
91
|
+
server = await startVitest("test", [], config, viteConfig);
|
|
92
|
+
yield { success: server?.state.getCountOfFailedTests() === 0 };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
yield { success: true };
|
|
117
96
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (!schema.default.properties[key]) {
|
|
124
|
-
extraArgs[key] = options[key];
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return extraArgs;
|
|
97
|
+
async function getExtraArgs(options) {
|
|
98
|
+
const schema = await import("./schema.json", { with: { type: "json" } });
|
|
99
|
+
const extraArgs = {};
|
|
100
|
+
for (const key of Object.keys(options)) if (!schema.default.properties[key]) extraArgs[key] = options[key];
|
|
101
|
+
return extraArgs;
|
|
128
102
|
}
|
|
129
103
|
/**
|
|
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
|
-
|
|
157
|
-
|
|
104
|
+
* Finds test files to include in the Vitest run using tinyglobby pattern matching.
|
|
105
|
+
*
|
|
106
|
+
* This function:
|
|
107
|
+
* 1. Normalizes the project root path to ensure consistent path separators
|
|
108
|
+
* 2. Constructs glob patterns by prepending the project root to each include pattern
|
|
109
|
+
* 3. Uses globSync from tinyglobby to find all files matching the patterns while respecting exclusions
|
|
110
|
+
*
|
|
111
|
+
* @param options Configuration object containing workspace and project paths, include/exclude patterns
|
|
112
|
+
* @returns Array of absolute file paths that match the include patterns
|
|
113
|
+
*
|
|
114
|
+
* Sample output paths:
|
|
115
|
+
* - /workspace/apps/my-app/src/app/app.component.spec.ts
|
|
116
|
+
* - /workspace/apps/my-app/src/app/services/data.service.spec.ts
|
|
117
|
+
* - /workspace/apps/my-app/src/app/components/header/header.component.test.ts
|
|
118
|
+
* - /workspace/apps/my-app/src/app/utils/helpers.spec.ts
|
|
119
|
+
*
|
|
120
|
+
* tinyglobby vs fast-glob comparison:
|
|
121
|
+
* - Both support the same glob patterns and ignore functionality
|
|
122
|
+
* - Both are fast and efficient for file matching
|
|
123
|
+
* - tinyglobby is a lighter alternative with similar API
|
|
124
|
+
* - tinyglobby's globSync returns absolute paths by default when absolute: true is set
|
|
125
|
+
* - tinyglobby has fewer dependencies and smaller bundle size
|
|
126
|
+
*
|
|
127
|
+
* globSync options explained:
|
|
128
|
+
* - dot: true - Includes files/directories that start with a dot (e.g., .env.test)
|
|
129
|
+
* - absolute: true - Returns absolute file paths instead of relative paths
|
|
130
|
+
* - ignore: options.exclude - Excludes files matching the exclude patterns
|
|
131
|
+
*/
|
|
158
132
|
function findIncludes(options) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// Use globSync from tinyglobby to find all files matching the patterns
|
|
167
|
-
// Returns absolute file paths that match the include patterns while respecting exclusions
|
|
168
|
-
return globSync(globs, {
|
|
169
|
-
dot: true, // Include files/directories starting with dot (e.g., .env.test)
|
|
170
|
-
absolute: true, // Return absolute file paths
|
|
171
|
-
ignore: options.exclude, // Exclude files matching these patterns
|
|
172
|
-
});
|
|
133
|
+
const { normalizePath } = __require("vite");
|
|
134
|
+
const projectRoot = normalizePath(path.resolve(options.workspaceRoot, options.projectRoot));
|
|
135
|
+
return globSync([...options.include.map((glob) => `${projectRoot}/${glob}`)], {
|
|
136
|
+
dot: true,
|
|
137
|
+
absolute: true,
|
|
138
|
+
ignore: options.exclude
|
|
139
|
+
});
|
|
173
140
|
}
|
|
174
|
-
function generateEntryPoints({ projectRoot, testFiles, context, angularVersion
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
while (seen.has(uniqueName)) {
|
|
189
|
-
uniqueName = `${relativePath}-${suffix}`;
|
|
190
|
-
++suffix;
|
|
191
|
-
}
|
|
192
|
-
seen.add(uniqueName);
|
|
193
|
-
return [uniqueName, testFile];
|
|
194
|
-
}));
|
|
141
|
+
function generateEntryPoints({ projectRoot, testFiles, context, angularVersion }) {
|
|
142
|
+
if (angularVersion < 19) return testFiles;
|
|
143
|
+
const seen = /* @__PURE__ */ new Set();
|
|
144
|
+
return new Map(Array.from(testFiles, (testFile) => {
|
|
145
|
+
const relativePath = path.relative(testFile.startsWith(projectRoot) ? projectRoot : context.workspaceRoot, testFile).replace(/^[./]+/, "_").replace(/\//g, "-");
|
|
146
|
+
let uniqueName = `spec-${path.basename(relativePath, path.extname(relativePath))}`;
|
|
147
|
+
let suffix = 2;
|
|
148
|
+
while (seen.has(uniqueName)) {
|
|
149
|
+
uniqueName = `${relativePath}-${suffix}`;
|
|
150
|
+
++suffix;
|
|
151
|
+
}
|
|
152
|
+
seen.add(uniqueName);
|
|
153
|
+
return [uniqueName, testFile];
|
|
154
|
+
}));
|
|
195
155
|
}
|
|
196
|
-
|
|
197
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidml0ZXN0LmltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy92aXRlc3QtYW5ndWxhci9zcmMvbGliL2J1aWxkZXJzL2J1aWxkL3ZpdGVzdC5pbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRCxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUk3QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBR3RDLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFdkQsTUFBTSxDQUFOLElBQVksVUFLWDtBQUxELFdBQVksVUFBVTtJQUNwQixpREFBTyxDQUFBO0lBQ1AsMkNBQUksQ0FBQTtJQUNKLHlEQUFXLENBQUE7SUFDWCxpRUFBZSxDQUFBO0FBQ2pCLENBQUMsRUFMVyxVQUFVLEtBQVYsVUFBVSxRQUtyQjtBQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsR0FBRyxNQUFNLENBQUM7QUFFaEQsS0FBSyxTQUFTLENBQUMsQ0FBQyx3QkFBd0IsQ0FDdEMsT0FBcUIsRUFDckIsT0FBWTtJQUVaLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDO0lBQzdCLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDO0lBRS9CLE1BQU0sRUFBRSx3QkFBd0IsRUFBRSxjQUFjLEVBQUUsR0FDaEQsTUFBTSwyQkFBMkIsRUFBRSxDQUFDO0lBQ3RDLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxNQUFPLFFBQVEsQ0FDckMsOEJBQThCLENBQy9C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SUFBSSxDQUFDLFFBQVEsQ0FDcEMsWUFBWSxFQUNaLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQzNCLEVBQUUsQ0FBQztRQUNKLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNmLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzVCLFVBQVUsR0FBRyxHQUFHLFlBQVksSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUN6QyxFQUFFLE1BQU0sQ0FBQztRQUNYLENBQUM7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRXJCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDaEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQztBQUNKLENBQUM7QUFFRCxlQUFlLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBWSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlQnVpbGRlciB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9hcmNoaXRlY3QnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB0eXBlIHsgVml0ZXN0IH0gZnJvbSAndml0ZXN0L25vZGUnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW4sIFVzZXJDb25maWcgfSBmcm9tICd2aXRlJztcbmltcG9ydCB0eXBlIHsgVGVzdFVzZXJDb25maWcgYXMgVml0ZXN0Q29uZmlnIH0gZnJvbSAndml0ZXN0L25vZGUnO1xuaW1wb3J0IHsgZ2xvYlN5bmMgfSBmcm9tICd0aW55Z2xvYmJ5JztcblxuaW1wb3J0IHsgVml0ZXN0U2NoZW1hIH0gZnJvbSAnLi9zY2hlbWEnO1xuaW1wb3J0IHsgY3JlYXRlQW5ndWxhck1lbW9yeVBsdWdpbiB9IGZyb20gJy4vcGx1Z2lucy9hbmd1bGFyLW1lbW9yeS1wbHVnaW4nO1xuaW1wb3J0IHsgZG93bmxldmVsUGx1Z2luIH0gZnJvbSAnLi9wbHVnaW5zL2Rvd25sZXZlbC1wbHVnaW4nO1xuaW1wb3J0IHsgZ2V0QnVpbGRBcHBsaWNhdGlvbkZ1bmN0aW9uIH0gZnJvbSAnLi9kZXZraXQnO1xuXG5leHBvcnQgZW51bSBSZXN1bHRLaW5kIHtcbiAgRmFpbHVyZSxcbiAgRnVsbCxcbiAgSW5jcmVtZW50YWwsXG4gIENvbXBvbmVudFVwZGF0ZSxcbn1cblxucHJvY2Vzcy5lbnZbJ1ZJVEVfQ0pTX0lHTk9SRV9XQVJOSU5HJ10gPSAndHJ1ZSc7XG5cbmFzeW5jIGZ1bmN0aW9uKiB2aXRlc3RBcHBsaWNhdGlvbkJ1aWxkZXIoXG4gIG9wdGlvbnM6IFZpdGVzdFNjaGVtYSxcbiAgY29udGV4dDogYW55LFxuKTogQXN5bmNJdGVyYWJsZTx7IHN1Y2Nlc3M6IGJvb2xlYW4gfT4ge1xuICBwcm9jZXNzLmVudlsnVEVTVCddID0gJ3RydWUnO1xuICBwcm9jZXNzLmVudlsnVklURVNUJ10gPSAndHJ1ZSc7XG5cbiAgY29uc3QgeyBidWlsZEFwcGxpY2F0aW9uSW50ZXJuYWwsIGFuZ3VsYXJWZXJzaW9uIH0gPVxuICAgIGF3YWl0IGdldEJ1aWxkQXBwbGljYXRpb25GdW5jdGlvbigpO1xuICBjb25zdCB7IHN0YXJ0Vml0ZXN0IH0gPSBhd2FpdCAoRnVuY3Rpb24oXG4gICAgJ3JldHVybiBpbXBvcnQoXCJ2aXRlc3Qvbm9kZVwiKScsXG4gICkoKSBhcyBQcm9taXNlPHR5cGVvZiBpbXBvcnQoJ3ZpdGVzdC9ub2RlJyk+KTtcblxuICBjb25zdCBwcm9qZWN0Q29uZmlnID0gYXdhaXQgY29udGV4dC5nZXRQcm9qZWN0TWV0YWRhdGEoY29udGV4dC50YXJnZXQpO1xuICBjb25zdCBleHRyYUFyZ3MgPSBhd2FpdCBnZXRFeHRyYUFyZ3Mob3B0aW9ucyk7XG4gIGNvbnN0IHdvcmtzcGFjZVJvb3QgPSBjb250ZXh0LndvcmtzcGFjZVJvb3Q7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvamVjdENvbmZpZ1sncm9vdCddO1xuICBjb25zdCBzZXR1cEZpbGUgPSBwYXRoLnJlbGF0aXZlKHByb2plY3RSb290LCBvcHRpb25zLnNldHVwRmlsZSk7XG5cbiAgY29uc3QgY29uZmlnOiBWaXRlc3RDb25maWcgPSB7XG4gICAgcm9vdDogYCR7cHJvamVjdFJvb3QgfHwgJy4nfWAsXG4gICAgd2F0Y2g6IG9wdGlvbnMud2F0Y2ggPT09IHRydWUsXG4gICAgY29uZmlnOiBvcHRpb25zLmNvbmZpZ0ZpbGUsXG4gICAgc2V0dXBGaWxlczogW3NldHVwRmlsZV0sXG4gICAgZ2xvYmFsczogdHJ1ZSxcbiAgICBwb29sOiAndm1UaHJlYWRzJyxcbiAgICByZXBvcnRlcnM6IFsnZGVmYXVsdCddLFxuICAgIGVudmlyb25tZW50OiAnanNkb20nLFxuICAgIGV4Y2x1ZGU6IG9wdGlvbnM/LmV4Y2x1ZGUgfHwgW10sXG4gICAgLi4uZXh0cmFBcmdzLFxuICB9O1xuXG4gIGNvbnN0IGluY2x1ZGVzOiBzdHJpbmdbXSA9IGZpbmRJbmNsdWRlcyh7XG4gICAgd29ya3NwYWNlUm9vdCxcbiAgICBwcm9qZWN0Um9vdCxcbiAgICBpbmNsdWRlOiBvcHRpb25zLmluY2x1ZGUsXG4gICAgZXhjbHVkZTogb3B0aW9ucy5leGNsdWRlIHx8IFtdLFxuICB9KTtcblxuICBjb25zdCB0ZXN0RmlsZXMgPSBbXG4gICAgcGF0aC5yZWxhdGl2ZSh3b3Jrc3BhY2VSb290LCBvcHRpb25zLnNldHVwRmlsZSksXG4gICAgLi4uaW5jbHVkZXMubWFwKChpbmMpID0+IHBhdGgucmVsYXRpdmUod29ya3NwYWNlUm9vdCwgaW5jKSksXG4gIF07XG5cbiAgY29uc3QgZW50cnlQb2ludHMgPSBnZW5lcmF0ZUVudHJ5UG9pbnRzKHtcbiAgICBwcm9qZWN0Um9vdDogcHJvamVjdFJvb3QsXG4gICAgdGVzdEZpbGVzLFxuICAgIGNvbnRleHQsXG4gICAgYW5ndWxhclZlcnNpb24sXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dEZpbGVzID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0IHZpdGVDb25maWc6IGFueSA9IHtcbiAgICBwbHVnaW5zOiBbXG4gICAgICAoYXdhaXQgY3JlYXRlQW5ndWxhck1lbW9yeVBsdWdpbih7XG4gICAgICAgIGFuZ3VsYXJWZXJzaW9uLFxuICAgICAgICB3b3Jrc3BhY2VSb290LFxuICAgICAgICBvdXRwdXRGaWxlcyxcbiAgICAgIH0pKSBhcyBQbHVnaW4sXG4gICAgICBkb3dubGV2ZWxQbHVnaW4oKSxcbiAgICBdLFxuICB9O1xuXG4gIGxldCBzZXJ2ZXI6IFZpdGVzdCB8IHVuZGVmaW5lZDtcbiAgZm9yIGF3YWl0IChjb25zdCBidWlsZE91dHB1dCBvZiBidWlsZEFwcGxpY2F0aW9uSW50ZXJuYWwoXG4gICAge1xuICAgICAgYW90OiBmYWxzZSxcbiAgICAgIGluZGV4OiBmYWxzZSxcbiAgICAgIHByb2dyZXNzOiBmYWxzZSxcbiAgICAgIHByZXJlbmRlcjogZmFsc2UsXG4gICAgICBvcHRpbWl6YXRpb246IGZhbHNlLFxuICAgICAgb3V0cHV0UGF0aDogYC5hbmd1bGFyLy52aXRlc3QvJHtwcm9qZWN0Q29uZmlnWyduYW1lJ119YCxcbiAgICAgIG91dEV4dGVuc2lvbjogJ21qcycsXG4gICAgICBvdXRwdXRIYXNoaW5nOiAyLCAvLyBOb25lXG4gICAgICB0c0NvbmZpZzogcGF0aC5yZWxhdGl2ZSh3b3Jrc3BhY2VSb290LCBvcHRpb25zLnRzQ29uZmlnKSxcbiAgICAgIHdhdGNoOiBvcHRpb25zLndhdGNoID09PSB0cnVlLFxuICAgICAgZW50cnlQb2ludHMsXG4gICAgICBhbGxvd2VkQ29tbW9uSnNEZXBlbmRlbmNpZXM6IFsnQGFuYWxvZ2pzL3ZpdGVzdC1hbmd1bGFyL3NldHVwLXpvbmUnXSxcbiAgICAgIHNvdXJjZU1hcDoge1xuICAgICAgICBzY3JpcHRzOiB0cnVlLFxuICAgICAgICBzdHlsZXM6IGZhbHNlLFxuICAgICAgICB2ZW5kb3I6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGNvbnRleHQsXG4gICkpIHtcbiAgICBpZiAoYnVpbGRPdXRwdXQua2luZCA9PT0gUmVzdWx0S2luZC5GYWlsdXJlKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSB9O1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBidWlsZE91dHB1dC5raW5kID09PSBSZXN1bHRLaW5kLkluY3JlbWVudGFsIHx8XG4gICAgICBidWlsZE91dHB1dC5raW5kID09PSBSZXN1bHRLaW5kLkZ1bGxcbiAgICApIHtcbiAgICAgIGlmIChidWlsZE91dHB1dC5raW5kID09PSBSZXN1bHRLaW5kLkZ1bGwpIHtcbiAgICAgICAgb3V0cHV0RmlsZXMuY2xlYXIoKTtcbiAgICAgICAgT2JqZWN0LmtleXMoYnVpbGRPdXRwdXQuZmlsZXMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgIG91dHB1dEZpbGVzLnNldChrZXksIGJ1aWxkT3V0cHV0LmZpbGVzW2tleV0pO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIE9iamVjdC5rZXlzKGJ1aWxkT3V0cHV0LmZpbGVzKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICBvdXRwdXRGaWxlcy5zZXQoa2V5LCBidWlsZE91dHB1dC5maWxlc1trZXldKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMud2F0Y2gpIHtcbiAgICAgIGlmICghc2VydmVyKSB7XG4gICAgICAgIHNlcnZlciA9IGF3YWl0IHN0YXJ0Vml0ZXN0KCd0ZXN0JywgW10sIGNvbmZpZywgdml0ZUNvbmZpZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBzZXJ2ZXIuc3RhcnQoW10pO1xuICAgICAgfVxuXG4gICAgICB5aWVsZCB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VydmVyID0gYXdhaXQgc3RhcnRWaXRlc3QoJ3Rlc3QnLCBbXSwgY29uZmlnLCB2aXRlQ29uZmlnKTtcblxuICAgICAgY29uc3Qgc3VjY2VzcyA9IHNlcnZlcj8uc3RhdGUuZ2V0Q291bnRPZkZhaWxlZFRlc3RzKCkgPT09IDA7XG5cbiAgICAgIHlpZWxkIHsgc3VjY2VzcyB9O1xuICAgIH1cbiAgfVxuXG4gIHlpZWxkIHsgc3VjY2VzczogdHJ1ZSB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RXh0cmFBcmdzKFxuICBvcHRpb25zOiBWaXRlc3RTY2hlbWEsXG4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgLy8gc3VwcG9ydCBwYXNzaW5nIGV4dHJhIGFyZ3MgdG8gVml0ZXN0IENMSVxuICBjb25zdCBzY2hlbWEgPSBhd2FpdCBpbXBvcnQoJy4vc2NoZW1hLmpzb24nLCB7IHdpdGg6IHsgdHlwZTogJ2pzb24nIH0gfSk7XG4gIGNvbnN0IGV4dHJhQXJnczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhvcHRpb25zKSkge1xuICAgIGlmICghKHNjaGVtYSBhcyBhbnkpLmRlZmF1bHQucHJvcGVydGllc1trZXldKSB7XG4gICAgICBleHRyYUFyZ3Nba2V5XSA9IChvcHRpb25zIGFzIGFueSlba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXh0cmFBcmdzO1xufVxuXG4vKipcbiAqIEZpbmRzIHRlc3QgZmlsZXMgdG8gaW5jbHVkZSBpbiB0aGUgVml0ZXN0IHJ1biB1c2luZyB0aW55Z2xvYmJ5IHBhdHRlcm4gbWF0Y2hpbmcuXG4gKlxuICogVGhpcyBmdW5jdGlvbjpcbiAqIDEuIE5vcm1hbGl6ZXMgdGhlIHByb2plY3Qgcm9vdCBwYXRoIHRvIGVuc3VyZSBjb25zaXN0ZW50IHBhdGggc2VwYXJhdG9yc1xuICogMi4gQ29uc3RydWN0cyBnbG9iIHBhdHRlcm5zIGJ5IHByZXBlbmRpbmcgdGhlIHByb2plY3Qgcm9vdCB0byBlYWNoIGluY2x1ZGUgcGF0dGVyblxuICogMy4gVXNlcyBnbG9iU3luYyBmcm9tIHRpbnlnbG9iYnkgdG8gZmluZCBhbGwgZmlsZXMgbWF0Y2hpbmcgdGhlIHBhdHRlcm5zIHdoaWxlIHJlc3BlY3RpbmcgZXhjbHVzaW9uc1xuICpcbiAqIEBwYXJhbSBvcHRpb25zIENvbmZpZ3VyYXRpb24gb2JqZWN0IGNvbnRhaW5pbmcgd29ya3NwYWNlIGFuZCBwcm9qZWN0IHBhdGhzLCBpbmNsdWRlL2V4Y2x1ZGUgcGF0dGVybnNcbiAqIEByZXR1cm5zIEFycmF5IG9mIGFic29sdXRlIGZpbGUgcGF0aHMgdGhhdCBtYXRjaCB0aGUgaW5jbHVkZSBwYXR0ZXJuc1xuICpcbiAqIFNhbXBsZSBvdXRwdXQgcGF0aHM6XG4gKiAtIC93b3Jrc3BhY2UvYXBwcy9teS1hcHAvc3JjL2FwcC9hcHAuY29tcG9uZW50LnNwZWMudHNcbiAqIC0gL3dvcmtzcGFjZS9hcHBzL215LWFwcC9zcmMvYXBwL3NlcnZpY2VzL2RhdGEuc2VydmljZS5zcGVjLnRzXG4gKiAtIC93b3Jrc3BhY2UvYXBwcy9teS1hcHAvc3JjL2FwcC9jb21wb25lbnRzL2hlYWRlci9oZWFkZXIuY29tcG9uZW50LnRlc3QudHNcbiAqIC0gL3dvcmtzcGFjZS9hcHBzL215LWFwcC9zcmMvYXBwL3V0aWxzL2hlbHBlcnMuc3BlYy50c1xuICpcbiAqIHRpbnlnbG9iYnkgdnMgZmFzdC1nbG9iIGNvbXBhcmlzb246XG4gKiAtIEJvdGggc3VwcG9ydCB0aGUgc2FtZSBnbG9iIHBhdHRlcm5zIGFuZCBpZ25vcmUgZnVuY3Rpb25hbGl0eVxuICogLSBCb3RoIGFyZSBmYXN0IGFuZCBlZmZpY2llbnQgZm9yIGZpbGUgbWF0Y2hpbmdcbiAqIC0gdGlueWdsb2JieSBpcyBhIGxpZ2h0ZXIgYWx0ZXJuYXRpdmUgd2l0aCBzaW1pbGFyIEFQSVxuICogLSB0aW55Z2xvYmJ5J3MgZ2xvYlN5bmMgcmV0dXJucyBhYnNvbHV0ZSBwYXRocyBieSBkZWZhdWx0IHdoZW4gYWJzb2x1dGU6IHRydWUgaXMgc2V0XG4gKiAtIHRpbnlnbG9iYnkgaGFzIGZld2VyIGRlcGVuZGVuY2llcyBhbmQgc21hbGxlciBidW5kbGUgc2l6ZVxuICpcbiAqIGdsb2JTeW5jIG9wdGlvbnMgZXhwbGFpbmVkOlxuICogLSBkb3Q6IHRydWUgLSBJbmNsdWRlcyBmaWxlcy9kaXJlY3RvcmllcyB0aGF0IHN0YXJ0IHdpdGggYSBkb3QgKGUuZy4sIC5lbnYudGVzdClcbiAqIC0gYWJzb2x1dGU6IHRydWUgLSBSZXR1cm5zIGFic29sdXRlIGZpbGUgcGF0aHMgaW5zdGVhZCBvZiByZWxhdGl2ZSBwYXRoc1xuICogLSBpZ25vcmU6IG9wdGlvbnMuZXhjbHVkZSAtIEV4Y2x1ZGVzIGZpbGVzIG1hdGNoaW5nIHRoZSBleGNsdWRlIHBhdHRlcm5zXG4gKi9cbmZ1bmN0aW9uIGZpbmRJbmNsdWRlcyhvcHRpb25zOiB7XG4gIHdvcmtzcGFjZVJvb3Q6IHN0cmluZztcbiAgcHJvamVjdFJvb3Q6IHN0cmluZztcbiAgaW5jbHVkZTogc3RyaW5nW107XG4gIGV4Y2x1ZGU6IHN0cmluZ1tdO1xufSkge1xuICBjb25zdCB7IG5vcm1hbGl6ZVBhdGggfSA9IHJlcXVpcmUoJ3ZpdGUnKTtcblxuICAvLyBOb3JtYWxpemUgcHJvamVjdCByb290IHBhdGggdG8gZW5zdXJlIGNvbnNpc3RlbnQgcGF0aCBzZXBhcmF0b3JzIGFjcm9zcyBwbGF0Zm9ybXNcbiAgY29uc3QgcHJvamVjdFJvb3QgPSBub3JtYWxpemVQYXRoKFxuICAgIHBhdGgucmVzb2x2ZShvcHRpb25zLndvcmtzcGFjZVJvb3QsIG9wdGlvbnMucHJvamVjdFJvb3QpLFxuICApO1xuXG4gIC8vIENvbnN0cnVjdCBnbG9iIHBhdHRlcm5zIGJ5IHByZXBlbmRpbmcgcHJvamVjdCByb290IHRvIGVhY2ggaW5jbHVkZSBwYXR0ZXJuXG4gIC8vIEV4YW1wbGU6IGlmIGluY2x1ZGU9WycqKi8qLnNwZWMudHMnXSBhbmQgcHJvamVjdFJvb3Q9Jy93b3Jrc3BhY2UvYXBwcy9teS1hcHAnXG4gIC8vIFJlc3VsdDogWycvd29ya3NwYWNlL2FwcHMvbXktYXBwLyoqLyouc3BlYy50cyddXG4gIGNvbnN0IGdsb2JzID0gWy4uLm9wdGlvbnMuaW5jbHVkZS5tYXAoKGdsb2IpID0+IGAke3Byb2plY3RSb290fS8ke2dsb2J9YCldO1xuXG4gIC8vIFVzZSBnbG9iU3luYyBmcm9tIHRpbnlnbG9iYnkgdG8gZmluZCBhbGwgZmlsZXMgbWF0Y2hpbmcgdGhlIHBhdHRlcm5zXG4gIC8vIFJldHVybnMgYWJzb2x1dGUgZmlsZSBwYXRocyB0aGF0IG1hdGNoIHRoZSBpbmNsdWRlIHBhdHRlcm5zIHdoaWxlIHJlc3BlY3RpbmcgZXhjbHVzaW9uc1xuICByZXR1cm4gZ2xvYlN5bmMoZ2xvYnMsIHtcbiAgICBkb3Q6IHRydWUsIC8vIEluY2x1ZGUgZmlsZXMvZGlyZWN0b3JpZXMgc3RhcnRpbmcgd2l0aCBkb3QgKGUuZy4sIC5lbnYudGVzdClcbiAgICBhYnNvbHV0ZTogdHJ1ZSwgLy8gUmV0dXJuIGFic29sdXRlIGZpbGUgcGF0aHNcbiAgICBpZ25vcmU6IG9wdGlvbnMuZXhjbHVkZSwgLy8gRXhjbHVkZSBmaWxlcyBtYXRjaGluZyB0aGVzZSBwYXR0ZXJuc1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVFbnRyeVBvaW50cyh7XG4gIHByb2plY3RSb290LFxuICB0ZXN0RmlsZXMsXG4gIGNvbnRleHQsXG4gIGFuZ3VsYXJWZXJzaW9uLFxufToge1xuICBwcm9qZWN0Um9vdDogc3RyaW5nO1xuICB0ZXN0RmlsZXM6IHN0cmluZ1tdO1xuICBjb250ZXh0OiBhbnk7XG4gIGFuZ3VsYXJWZXJzaW9uOiBudW1iZXI7XG59KSB7XG4gIGlmIChhbmd1bGFyVmVyc2lvbiA8IDE5KSB7XG4gICAgcmV0dXJuIHRlc3RGaWxlcztcbiAgfVxuXG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0KCk7XG5cbiAgcmV0dXJuIG5ldyBNYXAoXG4gICAgQXJyYXkuZnJvbSh0ZXN0RmlsZXMsICh0ZXN0RmlsZSkgPT4ge1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aFxuICAgICAgICAucmVsYXRpdmUoXG4gICAgICAgICAgdGVzdEZpbGUuc3RhcnRzV2l0aChwcm9qZWN0Um9vdClcbiAgICAgICAgICAgID8gcHJvamVjdFJvb3RcbiAgICAgICAgICAgIDogY29udGV4dC53b3Jrc3BhY2VSb290LFxuICAgICAgICAgIHRlc3RGaWxlLFxuICAgICAgICApXG4gICAgICAgIC5yZXBsYWNlKC9eWy4vXSsvLCAnXycpXG4gICAgICAgIC5yZXBsYWNlKC9cXC8vZywgJy0nKTtcblxuICAgICAgbGV0IHVuaXF1ZU5hbWUgPSBgc3BlYy0ke3BhdGguYmFzZW5hbWUoXG4gICAgICAgIHJlbGF0aXZlUGF0aCxcbiAgICAgICAgcGF0aC5leHRuYW1lKHJlbGF0aXZlUGF0aCksXG4gICAgICApfWA7XG4gICAgICBsZXQgc3VmZml4ID0gMjtcbiAgICAgIHdoaWxlIChzZWVuLmhhcyh1bmlxdWVOYW1lKSkge1xuICAgICAgICB1bmlxdWVOYW1lID0gYCR7cmVsYXRpdmVQYXRofS0ke3N1ZmZpeH1gO1xuICAgICAgICArK3N1ZmZpeDtcbiAgICAgIH1cbiAgICAgIHNlZW4uYWRkKHVuaXF1ZU5hbWUpO1xuXG4gICAgICByZXR1cm4gW3VuaXF1ZU5hbWUsIHRlc3RGaWxlXTtcbiAgICB9KSxcbiAgKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY3JlYXRlQnVpbGRlcih2aXRlc3RBcHBsaWNhdGlvbkJ1aWxkZXIpIGFzIHVua25vd247XG4iXX0=
|
|
156
|
+
var vitest_impl_default = createBuilder(vitestApplicationBuilder);
|
|
157
|
+
//#endregion
|
|
158
|
+
export { vitest_impl_default as default };
|
|
159
|
+
|
|
160
|
+
//# sourceMappingURL=vitest.impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.impl.js","names":[],"sources":["../../../../../../../packages/vitest-angular/src/lib/builders/build/vitest.impl.ts"],"sourcesContent":["import { createBuilder } from '@angular-devkit/architect';\nimport * as path from 'path';\nimport type { Vitest } from 'vitest/node';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { TestUserConfig as VitestConfig } from 'vitest/node';\nimport { globSync } from 'tinyglobby';\n\nimport { VitestSchema } from './schema';\nimport { createAngularMemoryPlugin } from './plugins/angular-memory-plugin';\nimport { downlevelPlugin } from './plugins/downlevel-plugin';\nimport { getBuildApplicationFunction } from './devkit';\n\nexport enum ResultKind {\n Failure,\n Full,\n Incremental,\n ComponentUpdate,\n}\n\nprocess.env['VITE_CJS_IGNORE_WARNING'] = 'true';\n\nasync function* vitestApplicationBuilder(\n options: VitestSchema,\n context: any,\n): AsyncIterable<{ success: boolean }> {\n process.env['TEST'] = 'true';\n process.env['VITEST'] = 'true';\n\n const { buildApplicationInternal, angularVersion } =\n await getBuildApplicationFunction();\n const { startVitest } = await (Function(\n 'return import(\"vitest/node\")',\n )() as Promise<typeof import('vitest/node')>);\n\n const projectConfig = await context.getProjectMetadata(context.target);\n const extraArgs = await getExtraArgs(options);\n const workspaceRoot = context.workspaceRoot;\n const projectRoot = projectConfig['root'];\n const setupFile = path.relative(projectRoot, options.setupFile);\n\n const config: VitestConfig = {\n root: `${projectRoot || '.'}`,\n watch: options.watch === true,\n config: options.configFile,\n setupFiles: [setupFile],\n globals: true,\n pool: 'vmThreads',\n reporters: ['default'],\n environment: 'jsdom',\n exclude: options?.exclude || [],\n ...extraArgs,\n };\n\n const includes: string[] = findIncludes({\n workspaceRoot,\n projectRoot,\n include: options.include,\n exclude: options.exclude || [],\n });\n\n const testFiles = [\n path.relative(workspaceRoot, options.setupFile),\n ...includes.map((inc) => path.relative(workspaceRoot, inc)),\n ];\n\n const entryPoints = generateEntryPoints({\n projectRoot: projectRoot,\n testFiles,\n context,\n angularVersion,\n });\n\n const outputFiles = new Map();\n\n const viteConfig: any = {\n plugins: [\n (await createAngularMemoryPlugin({\n angularVersion,\n workspaceRoot,\n outputFiles,\n })) as Plugin,\n downlevelPlugin(),\n ],\n };\n\n let server: Vitest | undefined;\n for await (const buildOutput of buildApplicationInternal(\n {\n aot: false,\n index: false,\n progress: false,\n prerender: false,\n optimization: false,\n outputPath: `.angular/.vitest/${projectConfig['name']}`,\n outExtension: 'mjs',\n outputHashing: 2, // None\n tsConfig: path.relative(workspaceRoot, options.tsConfig),\n watch: options.watch === true,\n entryPoints,\n allowedCommonJsDependencies: ['@analogjs/vitest-angular/setup-zone'],\n sourceMap: {\n scripts: true,\n styles: false,\n vendor: false,\n },\n },\n context,\n )) {\n if (buildOutput.kind === ResultKind.Failure) {\n return { success: false };\n } else if (\n buildOutput.kind === ResultKind.Incremental ||\n buildOutput.kind === ResultKind.Full\n ) {\n if (buildOutput.kind === ResultKind.Full) {\n outputFiles.clear();\n Object.keys(buildOutput.files).forEach((key) => {\n outputFiles.set(key, buildOutput.files[key]);\n });\n } else {\n Object.keys(buildOutput.files).forEach((key) => {\n outputFiles.set(key, buildOutput.files[key]);\n });\n }\n }\n\n if (options.watch) {\n if (!server) {\n server = await startVitest('test', [], config, viteConfig);\n } else {\n await server.start([]);\n }\n\n yield { success: true };\n } else {\n server = await startVitest('test', [], config, viteConfig);\n\n const success = server?.state.getCountOfFailedTests() === 0;\n\n yield { success };\n }\n }\n\n yield { success: true };\n}\n\nexport async function getExtraArgs(\n options: VitestSchema,\n): Promise<Record<string, any>> {\n // support passing extra args to Vitest CLI\n const schema = await import('./schema.json', { with: { type: 'json' } });\n const extraArgs: Record<string, any> = {};\n for (const key of Object.keys(options)) {\n if (!(schema as any).default.properties[key]) {\n extraArgs[key] = (options as any)[key];\n }\n }\n\n return extraArgs;\n}\n\n/**\n * Finds test files to include in the Vitest run using tinyglobby pattern matching.\n *\n * This function:\n * 1. Normalizes the project root path to ensure consistent path separators\n * 2. Constructs glob patterns by prepending the project root to each include pattern\n * 3. Uses globSync from tinyglobby to find all files matching the patterns while respecting exclusions\n *\n * @param options Configuration object containing workspace and project paths, include/exclude patterns\n * @returns Array of absolute file paths that match the include patterns\n *\n * Sample output paths:\n * - /workspace/apps/my-app/src/app/app.component.spec.ts\n * - /workspace/apps/my-app/src/app/services/data.service.spec.ts\n * - /workspace/apps/my-app/src/app/components/header/header.component.test.ts\n * - /workspace/apps/my-app/src/app/utils/helpers.spec.ts\n *\n * tinyglobby vs fast-glob comparison:\n * - Both support the same glob patterns and ignore functionality\n * - Both are fast and efficient for file matching\n * - tinyglobby is a lighter alternative with similar API\n * - tinyglobby's globSync returns absolute paths by default when absolute: true is set\n * - tinyglobby has fewer dependencies and smaller bundle size\n *\n * globSync options explained:\n * - dot: true - Includes files/directories that start with a dot (e.g., .env.test)\n * - absolute: true - Returns absolute file paths instead of relative paths\n * - ignore: options.exclude - Excludes files matching the exclude patterns\n */\nfunction findIncludes(options: {\n workspaceRoot: string;\n projectRoot: string;\n include: string[];\n exclude: string[];\n}) {\n const { normalizePath } = require('vite');\n\n // Normalize project root path to ensure consistent path separators across platforms\n const projectRoot = normalizePath(\n path.resolve(options.workspaceRoot, options.projectRoot),\n );\n\n // Construct glob patterns by prepending project root to each include pattern\n // Example: if include=['**/*.spec.ts'] and projectRoot='/workspace/apps/my-app'\n // Result: ['/workspace/apps/my-app/**/*.spec.ts']\n const globs = [...options.include.map((glob) => `${projectRoot}/${glob}`)];\n\n // Use globSync from tinyglobby to find all files matching the patterns\n // Returns absolute file paths that match the include patterns while respecting exclusions\n return globSync(globs, {\n dot: true, // Include files/directories starting with dot (e.g., .env.test)\n absolute: true, // Return absolute file paths\n ignore: options.exclude, // Exclude files matching these patterns\n });\n}\n\nfunction generateEntryPoints({\n projectRoot,\n testFiles,\n context,\n angularVersion,\n}: {\n projectRoot: string;\n testFiles: string[];\n context: any;\n angularVersion: number;\n}) {\n if (angularVersion < 19) {\n return testFiles;\n }\n\n const seen = new Set();\n\n return new Map(\n Array.from(testFiles, (testFile) => {\n const relativePath = path\n .relative(\n testFile.startsWith(projectRoot)\n ? projectRoot\n : context.workspaceRoot,\n testFile,\n )\n .replace(/^[./]+/, '_')\n .replace(/\\//g, '-');\n\n let uniqueName = `spec-${path.basename(\n relativePath,\n path.extname(relativePath),\n )}`;\n let suffix = 2;\n while (seen.has(uniqueName)) {\n uniqueName = `${relativePath}-${suffix}`;\n ++suffix;\n }\n seen.add(uniqueName);\n\n return [uniqueName, testFile];\n }),\n );\n}\n\nexport default createBuilder(vitestApplicationBuilder) as unknown;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var schema_default = {
|
|
2
|
+
version: 2,
|
|
3
|
+
cli: "nx",
|
|
4
|
+
title: "Vitest Builder for Angular",
|
|
5
|
+
description: "Run unit tests using Vitest.",
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
"configFile": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The path to the local vitest config",
|
|
11
|
+
"x-completion-type": "file",
|
|
12
|
+
"x-completion-glob": "@(vitest|vite).config@(.js|.ts)",
|
|
13
|
+
"aliases": ["config"]
|
|
14
|
+
},
|
|
15
|
+
"reportsDirectory": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "Directory to write coverage report to."
|
|
18
|
+
},
|
|
19
|
+
"mode": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Mode for Vite."
|
|
22
|
+
},
|
|
23
|
+
"testFiles": {
|
|
24
|
+
"aliases": ["testFile"],
|
|
25
|
+
"type": "array",
|
|
26
|
+
"items": { "type": "string" }
|
|
27
|
+
},
|
|
28
|
+
"watch": {
|
|
29
|
+
"description": "Watch files for changes and rerun tests related to changed files.",
|
|
30
|
+
"type": "boolean"
|
|
31
|
+
},
|
|
32
|
+
"ui": {
|
|
33
|
+
"description": "Run tests using Vitest UI Mode.",
|
|
34
|
+
"type": "boolean"
|
|
35
|
+
},
|
|
36
|
+
"coverage": {
|
|
37
|
+
"description": "Enable code coverage analysis.",
|
|
38
|
+
"type": "boolean"
|
|
39
|
+
},
|
|
40
|
+
"update": {
|
|
41
|
+
"description": "Update snapshot.",
|
|
42
|
+
"type": "boolean",
|
|
43
|
+
"aliases": ["u"]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
required: []
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { schema_default as default };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","names":[],"sources":["../../../../../../../packages/vitest-angular/src/lib/builders/test/schema.json"],"sourcesContent":["{\n \"version\": 2,\n \"cli\": \"nx\",\n \"title\": \"Vitest Builder for Angular\",\n \"description\": \"Run unit tests using Vitest.\",\n \"type\": \"object\",\n \"properties\": {\n \"configFile\": {\n \"type\": \"string\",\n \"description\": \"The path to the local vitest config\",\n \"x-completion-type\": \"file\",\n \"x-completion-glob\": \"@(vitest|vite).config@(.js|.ts)\",\n \"aliases\": [\"config\"]\n },\n \"reportsDirectory\": {\n \"type\": \"string\",\n \"description\": \"Directory to write coverage report to.\"\n },\n \"mode\": {\n \"type\": \"string\",\n \"description\": \"Mode for Vite.\"\n },\n \"testFiles\": {\n \"aliases\": [\"testFile\"],\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"watch\": {\n \"description\": \"Watch files for changes and rerun tests related to changed files.\",\n \"type\": \"boolean\"\n },\n \"ui\": {\n \"description\": \"Run tests using Vitest UI Mode.\",\n \"type\": \"boolean\"\n },\n \"coverage\": {\n \"description\": \"Enable code coverage analysis.\",\n \"type\": \"boolean\"\n },\n \"update\": {\n \"description\": \"Update snapshot.\",\n \"type\": \"boolean\",\n \"aliases\": [\"u\"]\n }\n },\n \"required\": []\n}\n"],"mappings":""}
|
|
@@ -1,61 +1,51 @@
|
|
|
1
|
-
import { createBuilder
|
|
1
|
+
import { createBuilder } from "@angular-devkit/architect";
|
|
2
|
+
//#region packages/vitest-angular/src/lib/builders/test/vitest.impl.ts
|
|
2
3
|
async function vitestBuilder(options, context) {
|
|
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
|
-
process.on('SIGINT', processExit);
|
|
40
|
-
process.on('SIGTERM', processExit);
|
|
41
|
-
process.on('exit', processExit);
|
|
42
|
-
}
|
|
43
|
-
// vitest sets the exitCode = 1 when code coverage isn't met
|
|
44
|
-
hasErrors = (process.exitCode && process.exitCode !== 0);
|
|
45
|
-
return {
|
|
46
|
-
success: !hasErrors,
|
|
47
|
-
};
|
|
4
|
+
process.env["TEST"] = "true";
|
|
5
|
+
process.env["VITEST"] = "true";
|
|
6
|
+
const { startVitest } = await Function("return import(\"vitest/node\")")();
|
|
7
|
+
const projectConfig = await context.getProjectMetadata(context.target);
|
|
8
|
+
const { coverageArgs, ...extraArgs } = await getExtraArgs(options);
|
|
9
|
+
const watch = options.watch === true;
|
|
10
|
+
const ui = options.ui === true;
|
|
11
|
+
const coverageEnabled = options.coverage === true;
|
|
12
|
+
const update = options.update === true;
|
|
13
|
+
const config = {
|
|
14
|
+
root: `${projectConfig["root"] || "."}`,
|
|
15
|
+
watch,
|
|
16
|
+
ui,
|
|
17
|
+
config: options.configFile,
|
|
18
|
+
coverage: {
|
|
19
|
+
enabled: coverageEnabled,
|
|
20
|
+
...coverageArgs
|
|
21
|
+
},
|
|
22
|
+
update,
|
|
23
|
+
...extraArgs
|
|
24
|
+
};
|
|
25
|
+
const viteOverrides = { test: { watch } };
|
|
26
|
+
const server = await startVitest("test", options.testFiles ?? [], config, viteOverrides);
|
|
27
|
+
let hasErrors = false;
|
|
28
|
+
const processExit = () => {
|
|
29
|
+
server?.exit();
|
|
30
|
+
if (hasErrors) process.exit(1);
|
|
31
|
+
else process.exit(0);
|
|
32
|
+
};
|
|
33
|
+
if (options.watch) {
|
|
34
|
+
process.on("SIGINT", processExit);
|
|
35
|
+
process.on("SIGTERM", processExit);
|
|
36
|
+
process.on("exit", processExit);
|
|
37
|
+
}
|
|
38
|
+
hasErrors = process.exitCode && process.exitCode !== 0;
|
|
39
|
+
return { success: !hasErrors };
|
|
48
40
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (!schema.default.properties[key]) {
|
|
55
|
-
extraArgs[key] = options[key];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return extraArgs;
|
|
41
|
+
async function getExtraArgs(options) {
|
|
42
|
+
const schema = await import("./schema.json", { with: { type: "json" } });
|
|
43
|
+
const extraArgs = {};
|
|
44
|
+
for (const key of Object.keys(options)) if (!schema.default.properties[key]) extraArgs[key] = options[key];
|
|
45
|
+
return extraArgs;
|
|
59
46
|
}
|
|
60
|
-
|
|
61
|
-
//#
|
|
47
|
+
var vitest_impl_default = createBuilder(vitestBuilder);
|
|
48
|
+
//#endregion
|
|
49
|
+
export { vitest_impl_default as default };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=vitest.impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.impl.js","names":[],"sources":["../../../../../../../packages/vitest-angular/src/lib/builders/test/vitest.impl.ts"],"sourcesContent":["import {\n BuilderContext,\n BuilderOutput,\n createBuilder,\n} from '@angular-devkit/architect';\n\nimport { VitestSchema } from './schema';\n\nasync function vitestBuilder(\n options: VitestSchema,\n context: BuilderContext,\n): Promise<BuilderOutput> {\n process.env['TEST'] = 'true';\n process.env['VITEST'] = 'true';\n\n const { startVitest } = await (Function(\n 'return import(\"vitest/node\")',\n )() as Promise<typeof import('vitest/node')>);\n\n const projectConfig = await context.getProjectMetadata(\n context.target as unknown as string,\n );\n const { coverageArgs, ...extraArgs } = await getExtraArgs(options);\n const watch = options.watch === true;\n const ui = options.ui === true;\n const coverageEnabled = options.coverage === true;\n const update = options.update === true;\n const config = {\n root: `${projectConfig['root'] || '.'}`,\n watch,\n ui,\n config: options.configFile,\n coverage: {\n enabled: coverageEnabled,\n ...coverageArgs,\n },\n update,\n ...extraArgs,\n };\n const viteOverrides: any = {\n test: { watch },\n };\n\n const server = await startVitest(\n 'test',\n options.testFiles ?? [],\n config,\n viteOverrides,\n );\n\n let hasErrors = false;\n\n const processExit = () => {\n server?.exit();\n if (hasErrors) {\n process.exit(1);\n } else {\n process.exit(0);\n }\n };\n\n if (options.watch) {\n process.on('SIGINT', processExit);\n process.on('SIGTERM', processExit);\n process.on('exit', processExit);\n }\n\n // vitest sets the exitCode = 1 when code coverage isn't met\n hasErrors = (process.exitCode && process.exitCode !== 0) as boolean;\n\n return {\n success: !hasErrors,\n };\n}\n\nexport async function getExtraArgs(\n options: VitestSchema,\n): Promise<Record<string, any>> {\n // support passing extra args to Vitest CLI\n const schema = await import('./schema.json', { with: { type: 'json' } });\n const extraArgs: Record<string, any> = {};\n for (const key of Object.keys(options)) {\n if (!(schema as any).default.properties[key]) {\n extraArgs[key] = (options as any)[key];\n }\n }\n\n return extraArgs;\n}\n\nexport default createBuilder(vitestBuilder) as any;\n"],"mappings":";;AAQA,eAAe,cACb,SACA,SACwB;AACxB,SAAQ,IAAI,UAAU;AACtB,SAAQ,IAAI,YAAY;CAExB,MAAM,EAAE,gBAAgB,MAAO,SAC7B,iCACD,EAAE;CAEH,MAAM,gBAAgB,MAAM,QAAQ,mBAClC,QAAQ,OACT;CACD,MAAM,EAAE,cAAc,GAAG,cAAc,MAAM,aAAa,QAAQ;CAClE,MAAM,QAAQ,QAAQ,UAAU;CAChC,MAAM,KAAK,QAAQ,OAAO;CAC1B,MAAM,kBAAkB,QAAQ,aAAa;CAC7C,MAAM,SAAS,QAAQ,WAAW;CAClC,MAAM,SAAS;EACb,MAAM,GAAG,cAAc,WAAW;EAClC;EACA;EACA,QAAQ,QAAQ;EAChB,UAAU;GACR,SAAS;GACT,GAAG;GACJ;EACD;EACA,GAAG;EACJ;CACD,MAAM,gBAAqB,EACzB,MAAM,EAAE,OAAO,EAChB;CAED,MAAM,SAAS,MAAM,YACnB,QACA,QAAQ,aAAa,EAAE,EACvB,QACA,cACD;CAED,IAAI,YAAY;CAEhB,MAAM,oBAAoB;AACxB,UAAQ,MAAM;AACd,MAAI,UACF,SAAQ,KAAK,EAAE;MAEf,SAAQ,KAAK,EAAE;;AAInB,KAAI,QAAQ,OAAO;AACjB,UAAQ,GAAG,UAAU,YAAY;AACjC,UAAQ,GAAG,WAAW,YAAY;AAClC,UAAQ,GAAG,QAAQ,YAAY;;AAIjC,aAAa,QAAQ,YAAY,QAAQ,aAAa;AAEtD,QAAO,EACL,SAAS,CAAC,WACX;;AAGH,eAAsB,aACpB,SAC8B;CAE9B,MAAM,SAAS,MAAM,OAAO,iBAAiB,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE;CACvE,MAAM,YAAiC,EAAE;AACzC,MAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,CACpC,KAAI,CAAE,OAAe,QAAQ,WAAW,KACtC,WAAU,OAAQ,QAAgB;AAItC,QAAO;;AAGT,IAAA,sBAAe,cAAc,cAAc"}
|