vitest 0.30.1 → 0.31.0
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/LICENSE.md +1 -264
- package/dist/browser.d.ts +3 -4
- package/dist/browser.js +2 -2
- package/dist/child.js +11 -3
- package/dist/{chunk-api-setup.c93e5069.js → chunk-api-setup.df3106cd.js} +8 -1
- package/dist/{chunk-install-pkg.ee5cc9a8.js → chunk-install-pkg.e0e70dba.js} +3 -4
- package/dist/{chunk-integrations-globals.d419838f.js → chunk-integrations-globals.88c8a0cf.js} +2 -2
- package/dist/cli.js +5 -6
- package/dist/config.cjs +1 -0
- package/dist/config.d.ts +6 -6
- package/dist/config.js +1 -0
- package/dist/coverage.d.ts +5 -5
- package/dist/coverage.js +6 -6
- package/dist/entry.js +21 -5
- package/dist/environments.d.ts +3 -4
- package/dist/index.d.ts +14 -6
- package/dist/index.js +3 -3
- package/dist/node.d.ts +4 -5
- package/dist/node.js +5 -6
- package/dist/runners.d.ts +7 -5
- package/dist/runners.js +11 -1
- package/dist/{types-e3c9754d.d.ts → types-b7007192.d.ts} +82 -326
- package/dist/{vendor-cli-api.70680cd5.js → vendor-cli-api.de0530cb.js} +2044 -2336
- package/dist/{vendor-coverage.a585b712.js → vendor-coverage.c8fd34c3.js} +2 -0
- package/dist/{vendor-execute.70609f6f.js → vendor-execute.a08cff9c.js} +1 -1
- package/dist/{vendor-index.81b9e499.js → vendor-index.b0b501c8.js} +1 -1
- package/dist/{vendor-setup.common.cef38f4e.js → vendor-setup.common.266b69fb.js} +1 -1
- package/dist/{vendor-vi.a3ff54b1.js → vendor-vi.458e47b1.js} +9 -1
- package/dist/worker.js +11 -3
- package/package.json +11 -10
- package/suppress-warnings.cjs +1 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { resolve as resolve$2, relative, isAbsolute, dirname, basename, normalize, join, extname, toNamespacedPath } from 'pathe';
|
|
2
2
|
import { E as EXIT_CODE_RESTART, c as configFiles, d as defaultPort, a as defaultBrowserPort, w as workspacesFiles, C as CONFIG_NAMES } from './vendor-constants.538d9b49.js';
|
|
3
|
-
import { g as getCoverageProvider, C as CoverageProviderMap } from './vendor-coverage.
|
|
3
|
+
import { g as getCoverageProvider, C as CoverageProviderMap } from './vendor-coverage.c8fd34c3.js';
|
|
4
4
|
import { g as getEnvPackageName } from './vendor-index.75f2b63d.js';
|
|
5
|
+
import url, { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
6
|
import c from 'picocolors';
|
|
6
7
|
import { isPackageExists, resolveModule } from 'local-pkg';
|
|
7
8
|
import { i as isNode, r as relativePath, a as removeUndefinedValues, b as isWindows } from './vendor-index.fad2598b.js';
|
|
8
9
|
import { isCI } from 'std-env';
|
|
9
10
|
import { loadConfigFromFile, createServer, mergeConfig } from 'vite';
|
|
10
11
|
import path$a from 'node:path';
|
|
11
|
-
import url, { fileURLToPath, pathToFileURL } from 'node:url';
|
|
12
12
|
import process$1 from 'node:process';
|
|
13
13
|
import fs$8, { promises, existsSync, readFileSync } from 'node:fs';
|
|
14
14
|
import p from 'path';
|
|
@@ -21,6 +21,7 @@ import { c as commonjsGlobal } from './vendor-_commonjsHelpers.76cdd49e.js';
|
|
|
21
21
|
import { slash as slash$2, normalizeRequestId, cleanUrl } from 'vite-node/utils';
|
|
22
22
|
import { ViteNodeRunner } from 'vite-node/client';
|
|
23
23
|
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
24
|
+
import { ViteNodeServer } from 'vite-node/server';
|
|
24
25
|
import { d as distDir, r as rootDir } from './vendor-paths.84fc7a99.js';
|
|
25
26
|
import v8 from 'node:v8';
|
|
26
27
|
import { fork } from 'node:child_process';
|
|
@@ -28,7 +29,7 @@ import { g as groupBy, a as getEnvironmentTransformMode, c as createBirpc, A as
|
|
|
28
29
|
import { MessageChannel } from 'node:worker_threads';
|
|
29
30
|
import { cpus, hostname } from 'node:os';
|
|
30
31
|
import Tinypool from 'tinypool';
|
|
31
|
-
import { createDefer, getSafeTimers, notNullish, parseErrorStacktrace, shuffle, stringify as stringify$5, positionToOffset, lineSplitRE
|
|
32
|
+
import { createDefer, getSafeTimers, notNullish, parseErrorStacktrace, shuffle, stringify as stringify$5, positionToOffset, lineSplitRE } from '@vitest/utils';
|
|
32
33
|
import { performance } from 'node:perf_hooks';
|
|
33
34
|
import { g as getFullName, h as hasFailedSnapshot } from './vendor-tasks.042d6084.js';
|
|
34
35
|
import { getTests, hasFailed, getSuites, generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks } from '@vitest/runner/utils';
|
|
@@ -36,13 +37,11 @@ import { createRequire } from 'node:module';
|
|
|
36
37
|
import { createHash } from 'node:crypto';
|
|
37
38
|
import { s as signalExit, e as execa } from './vendor-index.c1e09929.js';
|
|
38
39
|
import { writeFile, rm } from 'node:fs/promises';
|
|
39
|
-
import { SourceMapConsumer } from 'source-map';
|
|
40
40
|
import cn from 'module';
|
|
41
41
|
import { parse as parse$4 } from 'acorn';
|
|
42
|
-
import { ancestor } from 'acorn-walk';
|
|
42
|
+
import { ancestor, simple, findNodeAround } from 'acorn-walk';
|
|
43
43
|
import MagicString from 'magic-string';
|
|
44
44
|
import { stripLiteral } from 'strip-literal';
|
|
45
|
-
import { ViteNodeServer } from 'vite-node/server';
|
|
46
45
|
import readline from 'node:readline';
|
|
47
46
|
import require$$0$4 from 'readline';
|
|
48
47
|
|
|
@@ -61,10 +60,11 @@ function _mergeNamespaces(n, m) {
|
|
|
61
60
|
return Object.freeze(n);
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
var version$1 = "0.
|
|
63
|
+
var version$1 = "0.31.0";
|
|
65
64
|
|
|
65
|
+
const __dirname$1 = url.fileURLToPath(new URL(".", import.meta.url));
|
|
66
66
|
async function ensurePackageInstalled(dependency, root) {
|
|
67
|
-
if (isPackageExists(dependency, { paths: [root] }))
|
|
67
|
+
if (isPackageExists(dependency, { paths: [root, __dirname$1] }))
|
|
68
68
|
return true;
|
|
69
69
|
const promptInstall = !isCI && process.stdout.isTTY;
|
|
70
70
|
process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEP "))} Can not find dependency '${dependency}'
|
|
@@ -79,7 +79,7 @@ async function ensurePackageInstalled(dependency, root) {
|
|
|
79
79
|
message: c.reset(`Do you want to install ${c.green(dependency)}?`)
|
|
80
80
|
});
|
|
81
81
|
if (install) {
|
|
82
|
-
await (await import('./chunk-install-pkg.
|
|
82
|
+
await (await import('./chunk-install-pkg.e0e70dba.js')).installPackage(dependency, { dev: true });
|
|
83
83
|
process.stderr.write(c.yellow(`
|
|
84
84
|
Package ${dependency} installed, re-run the command to start.
|
|
85
85
|
`));
|
|
@@ -952,7 +952,7 @@ function splitToRanges(min, max) {
|
|
|
952
952
|
}
|
|
953
953
|
|
|
954
954
|
stops = [...stops];
|
|
955
|
-
stops.sort(compare
|
|
955
|
+
stops.sort(compare);
|
|
956
956
|
return stops;
|
|
957
957
|
}
|
|
958
958
|
|
|
@@ -1058,7 +1058,7 @@ function zip(a, b) {
|
|
|
1058
1058
|
return arr;
|
|
1059
1059
|
}
|
|
1060
1060
|
|
|
1061
|
-
function compare
|
|
1061
|
+
function compare(a, b) {
|
|
1062
1062
|
return a > b ? 1 : b > a ? -1 : 0;
|
|
1063
1063
|
}
|
|
1064
1064
|
|
|
@@ -7055,15 +7055,22 @@ function createMethodsRPC(project) {
|
|
|
7055
7055
|
},
|
|
7056
7056
|
onFinished(files) {
|
|
7057
7057
|
project.report("onFinished", files, ctx.state.getUnhandledErrors());
|
|
7058
|
+
},
|
|
7059
|
+
onCancel(reason) {
|
|
7060
|
+
ctx.cancelCurrentRun(reason);
|
|
7061
|
+
},
|
|
7062
|
+
getCountOfFailedTests() {
|
|
7063
|
+
return ctx.state.getCountOfFailedTests();
|
|
7058
7064
|
}
|
|
7059
7065
|
};
|
|
7060
7066
|
}
|
|
7061
7067
|
|
|
7062
7068
|
const childPath = fileURLToPath(pathToFileURL(resolve$2(distDir, "./child.js")).href);
|
|
7063
7069
|
function setupChildProcessChannel(project, fork2) {
|
|
7064
|
-
createBirpc(
|
|
7070
|
+
const rpc = createBirpc(
|
|
7065
7071
|
createMethodsRPC(project),
|
|
7066
7072
|
{
|
|
7073
|
+
eventNames: ["onCancel"],
|
|
7067
7074
|
serialize: v8.serialize,
|
|
7068
7075
|
deserialize: (v) => v8.deserialize(Buffer.from(v)),
|
|
7069
7076
|
post(v) {
|
|
@@ -7074,6 +7081,7 @@ function setupChildProcessChannel(project, fork2) {
|
|
|
7074
7081
|
}
|
|
7075
7082
|
}
|
|
7076
7083
|
);
|
|
7084
|
+
project.ctx.onCancel((reason) => rpc.onCancel(reason));
|
|
7077
7085
|
}
|
|
7078
7086
|
function stringifyRegex(input) {
|
|
7079
7087
|
if (typeof input === "string")
|
|
@@ -7161,9 +7169,10 @@ function createWorkerChannel(project) {
|
|
|
7161
7169
|
const channel = new MessageChannel();
|
|
7162
7170
|
const port = channel.port2;
|
|
7163
7171
|
const workerPort = channel.port1;
|
|
7164
|
-
createBirpc(
|
|
7172
|
+
const rpc = createBirpc(
|
|
7165
7173
|
createMethodsRPC(project),
|
|
7166
7174
|
{
|
|
7175
|
+
eventNames: ["onCancel"],
|
|
7167
7176
|
post(v) {
|
|
7168
7177
|
port.postMessage(v);
|
|
7169
7178
|
},
|
|
@@ -7172,6 +7181,7 @@ function createWorkerChannel(project) {
|
|
|
7172
7181
|
}
|
|
7173
7182
|
}
|
|
7174
7183
|
);
|
|
7184
|
+
project.ctx.onCancel((reason) => rpc.onCancel(reason));
|
|
7175
7185
|
return { workerPort, port };
|
|
7176
7186
|
}
|
|
7177
7187
|
function createThreadsPool(ctx, { execArgv, env }) {
|
|
@@ -7218,6 +7228,8 @@ function createThreadsPool(ctx, { execArgv, env }) {
|
|
|
7218
7228
|
} catch (error) {
|
|
7219
7229
|
if (error instanceof Error && /Failed to terminate worker/.test(error.message))
|
|
7220
7230
|
ctx.state.addProcessTimeoutCause(`Failed to terminate worker while running ${files.join(", ")}.`);
|
|
7231
|
+
else if (ctx.isCancelling && error instanceof Error && /The task has been cancelled/.test(error.message))
|
|
7232
|
+
ctx.state.cancelFiles(files, ctx.config.root);
|
|
7221
7233
|
else
|
|
7222
7234
|
throw error;
|
|
7223
7235
|
} finally {
|
|
@@ -7228,6 +7240,7 @@ function createThreadsPool(ctx, { execArgv, env }) {
|
|
|
7228
7240
|
const Sequencer = ctx.config.sequence.sequencer;
|
|
7229
7241
|
const sequencer = new Sequencer(ctx);
|
|
7230
7242
|
return async (specs, invalidates) => {
|
|
7243
|
+
ctx.onCancel(() => pool.cancelPendingTasks());
|
|
7231
7244
|
const configs = /* @__PURE__ */ new Map();
|
|
7232
7245
|
const getConfig = (project) => {
|
|
7233
7246
|
if (configs.has(project))
|
|
@@ -7295,6 +7308,11 @@ function createBrowserPool(ctx) {
|
|
|
7295
7308
|
};
|
|
7296
7309
|
const runTests = async (project, files) => {
|
|
7297
7310
|
var _a;
|
|
7311
|
+
ctx.state.clearFiles(project, files);
|
|
7312
|
+
let isCancelled = false;
|
|
7313
|
+
project.ctx.onCancel(() => {
|
|
7314
|
+
isCancelled = true;
|
|
7315
|
+
});
|
|
7298
7316
|
const provider = project.browserProvider;
|
|
7299
7317
|
providers.add(provider);
|
|
7300
7318
|
const origin = `http://${((_a = ctx.config.browser.api) == null ? void 0 : _a.host) || "localhost"}:${project.browser.config.server.port}`;
|
|
@@ -7302,6 +7320,10 @@ function createBrowserPool(ctx) {
|
|
|
7302
7320
|
const isolate = project.config.isolate;
|
|
7303
7321
|
if (isolate) {
|
|
7304
7322
|
for (const path of paths) {
|
|
7323
|
+
if (isCancelled) {
|
|
7324
|
+
ctx.state.cancelFiles(files.slice(paths.indexOf(path)), ctx.config.root);
|
|
7325
|
+
break;
|
|
7326
|
+
}
|
|
7305
7327
|
const url = new URL("/", origin);
|
|
7306
7328
|
url.searchParams.append("path", path);
|
|
7307
7329
|
url.searchParams.set("id", path);
|
|
@@ -7353,6 +7375,8 @@ function createPool(ctx) {
|
|
|
7353
7375
|
}
|
|
7354
7376
|
function getPoolName([project, file]) {
|
|
7355
7377
|
for (const [glob, pool] of project.config.poolMatchGlobs || []) {
|
|
7378
|
+
if (pool === "browser")
|
|
7379
|
+
throw new Error('Since Vitest 0.31.0 "browser" pool is not supported in "poolMatchGlobs". You can create a workspace to run some of your tests in browser in parallel. Read more: https://vitest.dev/guide/workspace');
|
|
7356
7380
|
if (micromatch_1.isMatch(file, glob, { cwd: project.config.root }))
|
|
7357
7381
|
return pool;
|
|
7358
7382
|
}
|
|
@@ -7612,6 +7636,8 @@ const WAIT_FOR_CHANGE_PASS = `
|
|
|
7612
7636
|
${c.bold(c.inverse(c.green(" PASS ")))}${c.green(" Waiting for file changes...")}`;
|
|
7613
7637
|
const WAIT_FOR_CHANGE_FAIL = `
|
|
7614
7638
|
${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(" Tests failed. Watching for file changes...")}`;
|
|
7639
|
+
const WAIT_FOR_CHANGE_CANCELLED = `
|
|
7640
|
+
${c.bold(c.inverse(c.red(" CANCELLED ")))}${c.red(" Test run cancelled. Watching for file changes...")}`;
|
|
7615
7641
|
const LAST_RUN_LOG_TIMEOUT = 1500;
|
|
7616
7642
|
class BaseReporter {
|
|
7617
7643
|
constructor() {
|
|
@@ -7689,8 +7715,11 @@ class BaseReporter {
|
|
|
7689
7715
|
this.resetLastRunLog();
|
|
7690
7716
|
const failed = errors.length > 0 || hasFailed(files);
|
|
7691
7717
|
const failedSnap = hasFailedSnapshot(files);
|
|
7718
|
+
const cancelled = this.ctx.isCancelling;
|
|
7692
7719
|
if (failed)
|
|
7693
7720
|
this.ctx.logger.log(WAIT_FOR_CHANGE_FAIL);
|
|
7721
|
+
else if (cancelled)
|
|
7722
|
+
this.ctx.logger.log(WAIT_FOR_CHANGE_CANCELLED);
|
|
7694
7723
|
else
|
|
7695
7724
|
this.ctx.logger.log(WAIT_FOR_CHANGE_PASS);
|
|
7696
7725
|
const hints = [];
|
|
@@ -8834,7 +8863,7 @@ function renderBenchmark$1(task, tasks) {
|
|
|
8834
8863
|
].join("");
|
|
8835
8864
|
}
|
|
8836
8865
|
function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
8837
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8866
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
8838
8867
|
const output = [];
|
|
8839
8868
|
let currentRowCount = 0;
|
|
8840
8869
|
for (const task of [...tasks].reverse()) {
|
|
@@ -8851,19 +8880,21 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
8851
8880
|
}
|
|
8852
8881
|
if (task.mode === "skip" || task.mode === "todo")
|
|
8853
8882
|
suffix += ` ${c.dim(c.gray("[skipped]"))}`;
|
|
8854
|
-
if (((_c = task.result) == null ? void 0 : _c.
|
|
8883
|
+
if (task.type === "test" && ((_c = task.result) == null ? void 0 : _c.repeatCount) && task.result.repeatCount > 1)
|
|
8884
|
+
suffix += c.yellow(` (repeat x${task.result.repeatCount})`);
|
|
8885
|
+
if (((_d = task.result) == null ? void 0 : _d.duration) != null) {
|
|
8855
8886
|
if (task.result.duration > DURATION_LONG$1)
|
|
8856
8887
|
suffix += c.yellow(` ${Math.round(task.result.duration)}${c.dim("ms")}`);
|
|
8857
8888
|
}
|
|
8858
|
-
if (options.showHeap && ((
|
|
8889
|
+
if (options.showHeap && ((_e = task.result) == null ? void 0 : _e.heap) != null)
|
|
8859
8890
|
suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
|
|
8860
8891
|
let name = task.name;
|
|
8861
8892
|
if (level === 0)
|
|
8862
8893
|
name = formatFilepath$1(name);
|
|
8863
8894
|
const padding = " ".repeat(level);
|
|
8864
|
-
const body = ((
|
|
8895
|
+
const body = ((_f = task.meta) == null ? void 0 : _f.benchmark) ? renderBenchmark$1(task, tasks) : name;
|
|
8865
8896
|
taskOutput.push(padding + prefix + body + suffix);
|
|
8866
|
-
if (((
|
|
8897
|
+
if (((_g = task.result) == null ? void 0 : _g.state) !== "pass" && outputMap$1.get(task) != null) {
|
|
8867
8898
|
let data = outputMap$1.get(task);
|
|
8868
8899
|
if (typeof data === "string") {
|
|
8869
8900
|
data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
|
|
@@ -8878,8 +8909,14 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
8878
8909
|
taskOutput.push(renderHookState(task, "beforeAll", level + 1));
|
|
8879
8910
|
taskOutput.push(renderHookState(task, "beforeEach", level + 1));
|
|
8880
8911
|
if (task.type === "suite" && task.tasks.length > 0) {
|
|
8881
|
-
if (((
|
|
8882
|
-
|
|
8912
|
+
if (((_h = task.result) == null ? void 0 : _h.state) === "fail" || ((_i = task.result) == null ? void 0 : _i.state) === "run" || options.renderSucceed) {
|
|
8913
|
+
if (options.logger.ctx.config.hideSkippedTests) {
|
|
8914
|
+
const filteredTasks = task.tasks.filter((t) => t.mode !== "skip" && t.mode !== "todo");
|
|
8915
|
+
taskOutput.push(renderTree$1(filteredTasks, options, level + 1, maxRows));
|
|
8916
|
+
} else {
|
|
8917
|
+
taskOutput.push(renderTree$1(task.tasks, options, level + 1, maxRows));
|
|
8918
|
+
}
|
|
8919
|
+
}
|
|
8883
8920
|
}
|
|
8884
8921
|
taskOutput.push(renderHookState(task, "afterAll", level + 1));
|
|
8885
8922
|
taskOutput.push(renderHookState(task, "afterEach", level + 1));
|
|
@@ -8896,14 +8933,26 @@ function createListRenderer(_tasks, options) {
|
|
|
8896
8933
|
let timer;
|
|
8897
8934
|
const log = options.logger.logUpdate;
|
|
8898
8935
|
function update() {
|
|
8899
|
-
|
|
8900
|
-
tasks
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8936
|
+
if (options.logger.ctx.config.hideSkippedTests) {
|
|
8937
|
+
const filteredTasks = tasks.filter((t) => t.mode !== "skip" && t.mode !== "todo");
|
|
8938
|
+
log(renderTree$1(
|
|
8939
|
+
filteredTasks,
|
|
8940
|
+
options,
|
|
8941
|
+
0,
|
|
8942
|
+
// log-update already limits the amount of printed rows to fit the current terminal
|
|
8943
|
+
// but we can optimize performance by doing it ourselves
|
|
8944
|
+
process.stdout.rows
|
|
8945
|
+
));
|
|
8946
|
+
} else {
|
|
8947
|
+
log(renderTree$1(
|
|
8948
|
+
tasks,
|
|
8949
|
+
options,
|
|
8950
|
+
0,
|
|
8951
|
+
// log-update already limits the amount of printed rows to fit the current terminal
|
|
8952
|
+
// but we can optimize performance by doing it ourselves
|
|
8953
|
+
process.stdout.rows
|
|
8954
|
+
));
|
|
8955
|
+
}
|
|
8907
8956
|
}
|
|
8908
8957
|
return {
|
|
8909
8958
|
start() {
|
|
@@ -8922,7 +8971,12 @@ function createListRenderer(_tasks, options) {
|
|
|
8922
8971
|
timer = void 0;
|
|
8923
8972
|
}
|
|
8924
8973
|
log.clear();
|
|
8925
|
-
options.logger.
|
|
8974
|
+
if (options.logger.ctx.config.hideSkippedTests) {
|
|
8975
|
+
const filteredTasks = tasks.filter((t) => t.mode !== "skip" && t.mode !== "todo");
|
|
8976
|
+
options.logger.log(renderTree$1(filteredTasks, options));
|
|
8977
|
+
} else {
|
|
8978
|
+
options.logger.log(renderTree$1(tasks, options));
|
|
8979
|
+
}
|
|
8926
8980
|
return this;
|
|
8927
8981
|
},
|
|
8928
8982
|
clear() {
|
|
@@ -10022,6 +10076,26 @@ class StateManager {
|
|
|
10022
10076
|
task.logs.push(log);
|
|
10023
10077
|
}
|
|
10024
10078
|
}
|
|
10079
|
+
getCountOfFailedTests() {
|
|
10080
|
+
return Array.from(this.idMap.values()).filter((t) => {
|
|
10081
|
+
var _a;
|
|
10082
|
+
return ((_a = t.result) == null ? void 0 : _a.state) === "fail";
|
|
10083
|
+
}).length;
|
|
10084
|
+
}
|
|
10085
|
+
cancelFiles(files, root) {
|
|
10086
|
+
this.collectFiles(files.map((filepath) => ({
|
|
10087
|
+
filepath,
|
|
10088
|
+
name: relative(root, filepath),
|
|
10089
|
+
id: filepath,
|
|
10090
|
+
mode: "skip",
|
|
10091
|
+
type: "suite",
|
|
10092
|
+
result: {
|
|
10093
|
+
state: "skip"
|
|
10094
|
+
},
|
|
10095
|
+
// Cancelled files have not yet collected tests
|
|
10096
|
+
tasks: []
|
|
10097
|
+
})));
|
|
10098
|
+
}
|
|
10025
10099
|
}
|
|
10026
10100
|
|
|
10027
10101
|
const defaultInclude = ["**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"];
|
|
@@ -10094,6 +10168,7 @@ const config = {
|
|
|
10094
10168
|
update: false,
|
|
10095
10169
|
reporters: [],
|
|
10096
10170
|
silent: false,
|
|
10171
|
+
hideSkippedTests: false,
|
|
10097
10172
|
api: false,
|
|
10098
10173
|
ui: false,
|
|
10099
10174
|
uiBase: "/__vitest__/",
|
|
@@ -10331,7 +10406,7 @@ function resolveApiServerConfig(options) {
|
|
|
10331
10406
|
return api;
|
|
10332
10407
|
}
|
|
10333
10408
|
function resolveConfig(mode, options, viteConfig) {
|
|
10334
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
10409
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
10335
10410
|
if (options.dom) {
|
|
10336
10411
|
if (((_a = viteConfig.test) == null ? void 0 : _a.environment) != null && viteConfig.test.environment !== "happy-dom") {
|
|
10337
10412
|
console.warn(
|
|
@@ -10476,6 +10551,7 @@ function resolveConfig(mode, options, viteConfig) {
|
|
|
10476
10551
|
resolved.browser ?? (resolved.browser = {});
|
|
10477
10552
|
(_i = resolved.browser).enabled ?? (_i.enabled = false);
|
|
10478
10553
|
(_j = resolved.browser).headless ?? (_j.headless = isCI);
|
|
10554
|
+
(_k = resolved.browser).slowHijackESM ?? (_k.slowHijackESM = true);
|
|
10479
10555
|
resolved.browser.api = resolveApiServerConfig(resolved.browser) || {
|
|
10480
10556
|
port: defaultBrowserPort
|
|
10481
10557
|
};
|
|
@@ -11034,2372 +11110,1986 @@ createLogUpdate(process$1.stdout);
|
|
|
11034
11110
|
|
|
11035
11111
|
createLogUpdate(process$1.stderr);
|
|
11036
11112
|
|
|
11037
|
-
var version = "0.
|
|
11038
|
-
|
|
11039
|
-
function L(n){return /^\\\\\?\\/.test(n)?n:n.replace(/\\/g,"/")}function S(n,s){for(;;){const t=p.posix.join(n,s);if(require$$0$3.existsSync(t))return t;const e=p.dirname(n);if(e===n)return;n=e;}}const W=/^\.{1,2}(\/.*)?$/,M=n=>L(W.test(n)?n:`./${n}`);function un(n,s=!1){const t=n.length;let e=0,i="",l=0,c=16,a=0,g=0,v=0,k=0,r=0;function F(o,f){let u=0,j=0;for(;u<o||!f;){let T=n.charCodeAt(e);if(T>=48&&T<=57)j=j*16+T-48;else if(T>=65&&T<=70)j=j*16+T-65+10;else if(T>=97&&T<=102)j=j*16+T-97+10;else break;e++,u++;}return u<o&&(j=-1),j}function U(o){e=o,i="",l=0,c=16,r=0;}function A(){let o=e;if(n.charCodeAt(e)===48)e++;else for(e++;e<n.length&&_(n.charCodeAt(e));)e++;if(e<n.length&&n.charCodeAt(e)===46)if(e++,e<n.length&&_(n.charCodeAt(e)))for(e++;e<n.length&&_(n.charCodeAt(e));)e++;else return r=3,n.substring(o,e);let f=e;if(e<n.length&&(n.charCodeAt(e)===69||n.charCodeAt(e)===101))if(e++,(e<n.length&&n.charCodeAt(e)===43||n.charCodeAt(e)===45)&&e++,e<n.length&&_(n.charCodeAt(e))){for(e++;e<n.length&&_(n.charCodeAt(e));)e++;f=e;}else r=3;return n.substring(o,f)}function b(){let o="",f=e;for(;;){if(e>=t){o+=n.substring(f,e),r=2;break}const u=n.charCodeAt(e);if(u===34){o+=n.substring(f,e),e++;break}if(u===92){if(o+=n.substring(f,e),e++,e>=t){r=2;break}switch(n.charCodeAt(e++)){case 34:o+='"';break;case 92:o+="\\";break;case 47:o+="/";break;case 98:o+="\b";break;case 102:o+="\f";break;case 110:o+=`
|
|
11040
|
-
`;break;case 114:o+="\r";break;case 116:o+=" ";break;case 117:const T=F(4,!0);T>=0?o+=String.fromCharCode(T):r=4;break;default:r=5;}f=e;continue}if(u>=0&&u<=31)if(N(u)){o+=n.substring(f,e),r=2;break}else r=6;e++;}return o}function O(){if(i="",r=0,l=e,g=a,k=v,e>=t)return l=t,c=17;let o=n.charCodeAt(e);if(R(o)){do e++,i+=String.fromCharCode(o),o=n.charCodeAt(e);while(R(o));return c=15}if(N(o))return e++,i+=String.fromCharCode(o),o===13&&n.charCodeAt(e)===10&&(e++,i+=`
|
|
11041
|
-
`),a++,v=e,c=14;switch(o){case 123:return e++,c=1;case 125:return e++,c=2;case 91:return e++,c=3;case 93:return e++,c=4;case 58:return e++,c=6;case 44:return e++,c=5;case 34:return e++,i=b(),c=10;case 47:const f=e-1;if(n.charCodeAt(e+1)===47){for(e+=2;e<t&&!N(n.charCodeAt(e));)e++;return i=n.substring(f,e),c=12}if(n.charCodeAt(e+1)===42){e+=2;const u=t-1;let j=!1;for(;e<u;){const T=n.charCodeAt(e);if(T===42&&n.charCodeAt(e+1)===47){e+=2,j=!0;break}e++,N(T)&&(T===13&&n.charCodeAt(e)===10&&e++,a++,v=e);}return j||(e++,r=1),i=n.substring(f,e),c=13}return i+=String.fromCharCode(o),e++,c=16;case 45:if(i+=String.fromCharCode(o),e++,e===t||!_(n.charCodeAt(e)))return c=16;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return i+=A(),c=11;default:for(;e<t&&E(o);)e++,o=n.charCodeAt(e);if(l!==e){switch(i=n.substring(l,e),i){case"true":return c=8;case"false":return c=9;case"null":return c=7}return c=16}return i+=String.fromCharCode(o),e++,c=16}}function E(o){if(R(o)||N(o))return !1;switch(o){case 125:case 93:case 123:case 91:case 34:case 58:case 44:case 47:return !1}return !0}function $(){let o;do o=O();while(o>=12&&o<=15);return o}return {setPosition:U,getPosition:()=>e,scan:s?$:O,getToken:()=>c,getTokenValue:()=>i,getTokenOffset:()=>l,getTokenLength:()=>e-l,getTokenStartLine:()=>g,getTokenStartCharacter:()=>l-k,getTokenError:()=>r}}function R(n){return n===32||n===9}function N(n){return n===10||n===13}function _(n){return n>=48&&n<=57}var P;(function(n){n[n.lineFeed=10]="lineFeed",n[n.carriageReturn=13]="carriageReturn",n[n.space=32]="space",n[n._0=48]="_0",n[n._1=49]="_1",n[n._2=50]="_2",n[n._3=51]="_3",n[n._4=52]="_4",n[n._5=53]="_5",n[n._6=54]="_6",n[n._7=55]="_7",n[n._8=56]="_8",n[n._9=57]="_9",n[n.a=97]="a",n[n.b=98]="b",n[n.c=99]="c",n[n.d=100]="d",n[n.e=101]="e",n[n.f=102]="f",n[n.g=103]="g",n[n.h=104]="h",n[n.i=105]="i",n[n.j=106]="j",n[n.k=107]="k",n[n.l=108]="l",n[n.m=109]="m",n[n.n=110]="n",n[n.o=111]="o",n[n.p=112]="p",n[n.q=113]="q",n[n.r=114]="r",n[n.s=115]="s",n[n.t=116]="t",n[n.u=117]="u",n[n.v=118]="v",n[n.w=119]="w",n[n.x=120]="x",n[n.y=121]="y",n[n.z=122]="z",n[n.A=65]="A",n[n.B=66]="B",n[n.C=67]="C",n[n.D=68]="D",n[n.E=69]="E",n[n.F=70]="F",n[n.G=71]="G",n[n.H=72]="H",n[n.I=73]="I",n[n.J=74]="J",n[n.K=75]="K",n[n.L=76]="L",n[n.M=77]="M",n[n.N=78]="N",n[n.O=79]="O",n[n.P=80]="P",n[n.Q=81]="Q",n[n.R=82]="R",n[n.S=83]="S",n[n.T=84]="T",n[n.U=85]="U",n[n.V=86]="V",n[n.W=87]="W",n[n.X=88]="X",n[n.Y=89]="Y",n[n.Z=90]="Z",n[n.asterisk=42]="asterisk",n[n.backslash=92]="backslash",n[n.closeBrace=125]="closeBrace",n[n.closeBracket=93]="closeBracket",n[n.colon=58]="colon",n[n.comma=44]="comma",n[n.dot=46]="dot",n[n.doubleQuote=34]="doubleQuote",n[n.minus=45]="minus",n[n.openBrace=123]="openBrace",n[n.openBracket=91]="openBracket",n[n.plus=43]="plus",n[n.slash=47]="slash",n[n.formFeed=12]="formFeed",n[n.tab=9]="tab";})(P||(P={}));var h;(function(n){n.DEFAULT={allowTrailingComma:!1};})(h||(h={}));function fn(n,s=[],t=h.DEFAULT){let e=null,i=[];const l=[];function c(g){Array.isArray(i)?i.push(g):e!==null&&(i[e]=g);}return rn(n,{onObjectBegin:()=>{const g={};c(g),l.push(i),i=g,e=null;},onObjectProperty:g=>{e=g;},onObjectEnd:()=>{i=l.pop();},onArrayBegin:()=>{const g=[];c(g),l.push(i),i=g,e=null;},onArrayEnd:()=>{i=l.pop();},onLiteralValue:c,onError:(g,v,k)=>{s.push({error:g,offset:v,length:k});}},t),i[0]}function rn(n,s,t=h.DEFAULT){const e=un(n,!1),i=[];function l(m){return m?()=>m(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function c(m){return m?()=>m(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>i.slice()):()=>!0}function a(m){return m?w=>m(w,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function g(m){return m?w=>m(w,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>i.slice()):()=>!0}const v=c(s.onObjectBegin),k=g(s.onObjectProperty),r=l(s.onObjectEnd),F=c(s.onArrayBegin),U=l(s.onArrayEnd),A=g(s.onLiteralValue),b=a(s.onSeparator),O=l(s.onComment),E=a(s.onError),$=t&&t.disallowComments,o=t&&t.allowTrailingComma;function f(){for(;;){const m=e.scan();switch(e.getTokenError()){case 4:u(14);break;case 5:u(15);break;case 3:u(13);break;case 1:$||u(11);break;case 2:u(12);break;case 6:u(16);break}switch(m){case 12:case 13:$?u(10):O();break;case 16:u(1);break;case 15:case 14:break;default:return m}}}function u(m,w=[],H=[]){if(E(m),w.length+H.length>0){let I=e.getToken();for(;I!==17;){if(w.indexOf(I)!==-1){f();break}else if(H.indexOf(I)!==-1)break;I=f();}}}function j(m){const w=e.getTokenValue();return m?A(w):(k(w),i.push(w)),f(),!0}function T(){switch(e.getToken()){case 11:const m=e.getTokenValue();let w=Number(m);isNaN(w)&&(u(2),w=0),A(w);break;case 7:A(null);break;case 8:A(!0);break;case 9:A(!1);break;default:return !1}return f(),!0}function sn(){return e.getToken()!==10?(u(3,[],[2,5]),!1):(j(!1),e.getToken()===6?(b(":"),f(),V()||u(4,[],[2,5])):u(5,[],[2,5]),i.pop(),!0)}function on(){v(),f();let m=!1;for(;e.getToken()!==2&&e.getToken()!==17;){if(e.getToken()===5){if(m||u(4,[],[]),b(","),f(),e.getToken()===2&&o)break}else m&&u(6,[],[]);sn()||u(4,[],[2,5]),m=!0;}return r(),e.getToken()!==2?u(7,[2],[]):f(),!0}function ln(){F(),f();let m=!0,w=!1;for(;e.getToken()!==4&&e.getToken()!==17;){if(e.getToken()===5){if(w||u(4,[],[]),b(","),f(),e.getToken()===4&&o)break}else w&&u(6,[],[]);m?(i.push(0),m=!1):i[i.length-1]++,V()||u(4,[],[4,5]),w=!0;}return U(),m||i.pop(),e.getToken()!==4?u(8,[4],[]):f(),!0}function V(){switch(e.getToken()){case 3:return ln();case 1:return on();case 10:return j(!0);default:return T()}}return f(),e.getToken()===17?t.allowEmptyContent?!0:(u(4,[],[]),!1):V()?(e.getToken()!==17&&u(9,[],[]),!0):(u(4,[],[]),!1)}var X;(function(n){n[n.None=0]="None",n[n.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=2]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",n[n.InvalidUnicode=4]="InvalidUnicode",n[n.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",n[n.InvalidCharacter=6]="InvalidCharacter";})(X||(X={}));var Y;(function(n){n[n.OpenBraceToken=1]="OpenBraceToken",n[n.CloseBraceToken=2]="CloseBraceToken",n[n.OpenBracketToken=3]="OpenBracketToken",n[n.CloseBracketToken=4]="CloseBracketToken",n[n.CommaToken=5]="CommaToken",n[n.ColonToken=6]="ColonToken",n[n.NullKeyword=7]="NullKeyword",n[n.TrueKeyword=8]="TrueKeyword",n[n.FalseKeyword=9]="FalseKeyword",n[n.StringLiteral=10]="StringLiteral",n[n.NumericLiteral=11]="NumericLiteral",n[n.LineCommentTrivia=12]="LineCommentTrivia",n[n.BlockCommentTrivia=13]="BlockCommentTrivia",n[n.LineBreakTrivia=14]="LineBreakTrivia",n[n.Trivia=15]="Trivia",n[n.Unknown=16]="Unknown",n[n.EOF=17]="EOF";})(Y||(Y={}));const pn=fn;var Z;(function(n){n[n.InvalidSymbol=1]="InvalidSymbol",n[n.InvalidNumberFormat=2]="InvalidNumberFormat",n[n.PropertyNameExpected=3]="PropertyNameExpected",n[n.ValueExpected=4]="ValueExpected",n[n.ColonExpected=5]="ColonExpected",n[n.CommaExpected=6]="CommaExpected",n[n.CloseBraceExpected=7]="CloseBraceExpected",n[n.CloseBracketExpected=8]="CloseBracketExpected",n[n.EndOfFileExpected=9]="EndOfFileExpected",n[n.InvalidCommentToken=10]="InvalidCommentToken",n[n.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=12]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",n[n.InvalidUnicode=14]="InvalidUnicode",n[n.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",n[n.InvalidCharacter=16]="InvalidCharacter";})(Z||(Z={}));const q=n=>pn(require$$0$3.readFileSync(n,"utf8")),{existsSync:D}=require$$0$3,gn=()=>{const{findPnpApi:n}=cn;return n&&n(process.cwd())};function d(n){const s=q(n);return p.join(n,"..",s&&"tsconfig"in s?s.tsconfig:"tsconfig.json")}function mn(n,s){let t=n;const e=n[0]===".";if(e||p.isAbsolute(n)){if(e&&(t===".."&&(t+="/tsconfig.json"),t=p.resolve(s,t)),D(t)&&require$$0$3.statSync(t).isFile()||!t.endsWith(".json")&&(t+=".json",D(t)))return t;throw new Error(`File '${n}' not found.`)}const i=gn();if(i){const{resolveRequest:c}=i,[a,g]=n.split("/"),v=a.startsWith("@")?`${a}/${g}`:a;try{if(v===n){const k=c(p.join(v,"package.json"),s);if(k){const r=d(k);if(D(r))return r}}else {let k;try{k=c(n,s,{extensions:[".json"]});}catch{k=c(p.join(n,"tsconfig.json"),s);}if(k)return k}}catch{}}let l=S(s,p.join("node_modules",t));if(l){if(require$$0$3.statSync(l).isDirectory()){const c=p.join(l,"package.json");if(D(c)?l=d(c):l=p.join(l,"tsconfig.json"),D(l))return l}else if(l.endsWith(".json"))return l}if(!t.endsWith(".json")&&(t+=".json",l=S(s,p.join("node_modules",t)),l))return l;throw new Error(`File '${n}' not found.`)}const an=(n,s)=>{var t;const e=mn(n,s),i=J(e);if(delete i.references,(t=i.compilerOptions)!=null&&t.baseUrl){const{compilerOptions:l}=i;l.baseUrl=p.relative(s,p.join(p.dirname(e),l.baseUrl))||"./";}return i.files&&(i.files=i.files.map(l=>p.relative(s,p.join(p.dirname(e),l)))),i.include&&(i.include=i.include.map(l=>p.relative(s,p.join(p.dirname(e),l)))),i},J=n=>{let s;try{s=require$$0$3.realpathSync(n);}catch{throw new Error(`Cannot resolve tsconfig at path: ${n}`)}const t=p.dirname(s);let e=q(s)||{};if(typeof e!="object")throw new SyntaxError(`Failed to parse tsconfig at: ${n}`);if(e.extends){const i=Array.isArray(e.extends)?e.extends:[e.extends];delete e.extends;for(const l of i.reverse()){const c=an(l,t),a={...c,...e,compilerOptions:{...c.compilerOptions,...e.compilerOptions}};c.watchOptions&&(a.watchOptions={...c.watchOptions,...e.watchOptions}),e=a;}}if(e.compilerOptions){const{compilerOptions:i}=e;i.baseUrl&&(i.baseUrl=M(i.baseUrl)),i.outDir&&(Array.isArray(e.exclude)||(e.exclude=[]),e.exclude.push(i.outDir),i.outDir=M(i.outDir));}else e.compilerOptions={};if(e.files&&(e.files=e.files.map(M)),e.include&&(e.include=e.include.map(L)),e.watchOptions){const{watchOptions:i}=e;i.excludeDirectories&&(i.excludeDirectories=i.excludeDirectories.map(l=>L(p.resolve(t,l))));}return e};function kn(n=process.cwd(),s="tsconfig.json"){const t=S(L(n),s);if(!t)return null;const e=J(t);return {path:t,config:e}}p.posix;process.platform==="win32";
|
|
11113
|
+
var version = "0.31.0";
|
|
11042
11114
|
|
|
11043
|
-
const
|
|
11044
|
-
const
|
|
11045
|
-
const
|
|
11046
|
-
|
|
11047
|
-
|
|
11048
|
-
|
|
11049
|
-
|
|
11050
|
-
|
|
11051
|
-
const errMsgRaw = errMsgRawArr.join("").trim();
|
|
11052
|
-
const [errFilePath, errPos] = errFilePathPos.slice(0, -1).split("(");
|
|
11053
|
-
if (!errFilePath || !errPos)
|
|
11054
|
-
return ["unknown filepath", null];
|
|
11055
|
-
const [errLine, errCol] = errPos.split(",");
|
|
11056
|
-
if (!errLine || !errCol)
|
|
11057
|
-
return [errFilePath, null];
|
|
11058
|
-
const execArr = errCodeRegExp.exec(errMsgRaw);
|
|
11059
|
-
if (!execArr)
|
|
11060
|
-
return [errFilePath, null];
|
|
11061
|
-
const errCodeStr = ((_a = execArr.groups) == null ? void 0 : _a.errCode) ?? "";
|
|
11062
|
-
if (!errCodeStr)
|
|
11063
|
-
return [errFilePath, null];
|
|
11064
|
-
const line = Number(errLine);
|
|
11065
|
-
const col = Number(errCol);
|
|
11066
|
-
const errCode = Number(errCodeStr);
|
|
11067
|
-
return [
|
|
11068
|
-
errFilePath,
|
|
11069
|
-
{
|
|
11070
|
-
filePath: errFilePath,
|
|
11071
|
-
errCode,
|
|
11072
|
-
line,
|
|
11073
|
-
column: col,
|
|
11074
|
-
errMsg: errMsgRaw.slice(`error TS${errCode} `.length)
|
|
11075
|
-
}
|
|
11076
|
-
];
|
|
11115
|
+
const comma = ','.charCodeAt(0);
|
|
11116
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
11117
|
+
const intToChar = new Uint8Array(64); // 64 possible chars.
|
|
11118
|
+
const charToInt = new Uint8Array(128); // z is 122 in ASCII
|
|
11119
|
+
for (let i = 0; i < chars.length; i++) {
|
|
11120
|
+
const c = chars.charCodeAt(i);
|
|
11121
|
+
intToChar[i] = c;
|
|
11122
|
+
charToInt[c] = i;
|
|
11077
11123
|
}
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11082
|
-
|
|
11083
|
-
|
|
11084
|
-
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11124
|
+
function decode(mappings) {
|
|
11125
|
+
const state = new Int32Array(5);
|
|
11126
|
+
const decoded = [];
|
|
11127
|
+
let index = 0;
|
|
11128
|
+
do {
|
|
11129
|
+
const semi = indexOf(mappings, index);
|
|
11130
|
+
const line = [];
|
|
11131
|
+
let sorted = true;
|
|
11132
|
+
let lastCol = 0;
|
|
11133
|
+
state[0] = 0;
|
|
11134
|
+
for (let i = index; i < semi; i++) {
|
|
11135
|
+
let seg;
|
|
11136
|
+
i = decodeInteger(mappings, i, state, 0); // genColumn
|
|
11137
|
+
const col = state[0];
|
|
11138
|
+
if (col < lastCol)
|
|
11139
|
+
sorted = false;
|
|
11140
|
+
lastCol = col;
|
|
11141
|
+
if (hasMoreVlq(mappings, i, semi)) {
|
|
11142
|
+
i = decodeInteger(mappings, i, state, 1); // sourcesIndex
|
|
11143
|
+
i = decodeInteger(mappings, i, state, 2); // sourceLine
|
|
11144
|
+
i = decodeInteger(mappings, i, state, 3); // sourceColumn
|
|
11145
|
+
if (hasMoreVlq(mappings, i, semi)) {
|
|
11146
|
+
i = decodeInteger(mappings, i, state, 4); // namesIndex
|
|
11147
|
+
seg = [col, state[1], state[2], state[3], state[4]];
|
|
11148
|
+
}
|
|
11149
|
+
else {
|
|
11150
|
+
seg = [col, state[1], state[2], state[3]];
|
|
11151
|
+
}
|
|
11152
|
+
}
|
|
11153
|
+
else {
|
|
11154
|
+
seg = [col];
|
|
11155
|
+
}
|
|
11156
|
+
line.push(seg);
|
|
11157
|
+
}
|
|
11158
|
+
if (!sorted)
|
|
11159
|
+
sort(line);
|
|
11160
|
+
decoded.push(line);
|
|
11161
|
+
index = semi + 1;
|
|
11162
|
+
} while (index <= mappings.length);
|
|
11163
|
+
return decoded;
|
|
11100
11164
|
}
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
tscErrorStdout.split(newLineRegExp).reduce((prev, next) => {
|
|
11105
|
-
if (!next)
|
|
11106
|
-
return prev;
|
|
11107
|
-
else if (!next.startsWith(" "))
|
|
11108
|
-
prev.push(next);
|
|
11109
|
-
else
|
|
11110
|
-
prev[prev.length - 1] += `
|
|
11111
|
-
${next}`;
|
|
11112
|
-
return prev;
|
|
11113
|
-
}, []).map((errInfoLine) => makeTscErrorInfo(errInfoLine))
|
|
11114
|
-
);
|
|
11115
|
-
infos.forEach(([errFilePath, errInfo]) => {
|
|
11116
|
-
var _a;
|
|
11117
|
-
if (!errInfo)
|
|
11118
|
-
return;
|
|
11119
|
-
if (!rawErrsMap.has(errFilePath))
|
|
11120
|
-
rawErrsMap.set(errFilePath, [errInfo]);
|
|
11121
|
-
else
|
|
11122
|
-
(_a = rawErrsMap.get(errFilePath)) == null ? void 0 : _a.push(errInfo);
|
|
11123
|
-
});
|
|
11124
|
-
return rawErrsMap;
|
|
11165
|
+
function indexOf(mappings, index) {
|
|
11166
|
+
const idx = mappings.indexOf(';', index);
|
|
11167
|
+
return idx === -1 ? mappings.length : idx;
|
|
11125
11168
|
}
|
|
11126
|
-
|
|
11127
|
-
|
|
11128
|
-
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11132
|
-
|
|
11133
|
-
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11169
|
+
function decodeInteger(mappings, pos, state, j) {
|
|
11170
|
+
let value = 0;
|
|
11171
|
+
let shift = 0;
|
|
11172
|
+
let integer = 0;
|
|
11173
|
+
do {
|
|
11174
|
+
const c = mappings.charCodeAt(pos++);
|
|
11175
|
+
integer = charToInt[c];
|
|
11176
|
+
value |= (integer & 31) << shift;
|
|
11177
|
+
shift += 5;
|
|
11178
|
+
} while (integer & 32);
|
|
11179
|
+
const shouldNegate = value & 1;
|
|
11180
|
+
value >>>= 1;
|
|
11181
|
+
if (shouldNegate) {
|
|
11182
|
+
value = -0x80000000 | -value;
|
|
11139
11183
|
}
|
|
11140
|
-
|
|
11141
|
-
|
|
11184
|
+
state[j] += value;
|
|
11185
|
+
return pos;
|
|
11186
|
+
}
|
|
11187
|
+
function hasMoreVlq(mappings, i, length) {
|
|
11188
|
+
if (i >= length)
|
|
11189
|
+
return false;
|
|
11190
|
+
return mappings.charCodeAt(i) !== comma;
|
|
11191
|
+
}
|
|
11192
|
+
function sort(line) {
|
|
11193
|
+
line.sort(sortComparator$1);
|
|
11194
|
+
}
|
|
11195
|
+
function sortComparator$1(a, b) {
|
|
11196
|
+
return a[0] - b[0];
|
|
11142
11197
|
}
|
|
11143
11198
|
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
|
|
11148
|
-
|
|
11149
|
-
|
|
11150
|
-
|
|
11151
|
-
|
|
11152
|
-
|
|
11153
|
-
|
|
11154
|
-
|
|
11155
|
-
|
|
11156
|
-
|
|
11157
|
-
|
|
11158
|
-
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
11165
|
-
|
|
11166
|
-
|
|
11167
|
-
|
|
11168
|
-
|
|
11169
|
-
|
|
11170
|
-
|
|
11171
|
-
|
|
11172
|
-
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
|
|
11176
|
-
|
|
11177
|
-
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11181
|
-
|
|
11182
|
-
|
|
11183
|
-
|
|
11184
|
-
|
|
11185
|
-
|
|
11186
|
-
|
|
11187
|
-
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
|
|
11195
|
-
|
|
11196
|
-
|
|
11197
|
-
|
|
11198
|
-
|
|
11199
|
-
|
|
11200
|
-
|
|
11199
|
+
// Matches the scheme of a URL, eg "http://"
|
|
11200
|
+
const schemeRegex = /^[\w+.-]+:\/\//;
|
|
11201
|
+
/**
|
|
11202
|
+
* Matches the parts of a URL:
|
|
11203
|
+
* 1. Scheme, including ":", guaranteed.
|
|
11204
|
+
* 2. User/password, including "@", optional.
|
|
11205
|
+
* 3. Host, guaranteed.
|
|
11206
|
+
* 4. Port, including ":", optional.
|
|
11207
|
+
* 5. Path, including "/", optional.
|
|
11208
|
+
* 6. Query, including "?", optional.
|
|
11209
|
+
* 7. Hash, including "#", optional.
|
|
11210
|
+
*/
|
|
11211
|
+
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
|
|
11212
|
+
/**
|
|
11213
|
+
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
|
|
11214
|
+
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
|
|
11215
|
+
*
|
|
11216
|
+
* 1. Host, optional.
|
|
11217
|
+
* 2. Path, which may include "/", guaranteed.
|
|
11218
|
+
* 3. Query, including "?", optional.
|
|
11219
|
+
* 4. Hash, including "#", optional.
|
|
11220
|
+
*/
|
|
11221
|
+
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
|
|
11222
|
+
var UrlType;
|
|
11223
|
+
(function (UrlType) {
|
|
11224
|
+
UrlType[UrlType["Empty"] = 1] = "Empty";
|
|
11225
|
+
UrlType[UrlType["Hash"] = 2] = "Hash";
|
|
11226
|
+
UrlType[UrlType["Query"] = 3] = "Query";
|
|
11227
|
+
UrlType[UrlType["RelativePath"] = 4] = "RelativePath";
|
|
11228
|
+
UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath";
|
|
11229
|
+
UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative";
|
|
11230
|
+
UrlType[UrlType["Absolute"] = 7] = "Absolute";
|
|
11231
|
+
})(UrlType || (UrlType = {}));
|
|
11232
|
+
function isAbsoluteUrl(input) {
|
|
11233
|
+
return schemeRegex.test(input);
|
|
11234
|
+
}
|
|
11235
|
+
function isSchemeRelativeUrl(input) {
|
|
11236
|
+
return input.startsWith('//');
|
|
11237
|
+
}
|
|
11238
|
+
function isAbsolutePath(input) {
|
|
11239
|
+
return input.startsWith('/');
|
|
11240
|
+
}
|
|
11241
|
+
function isFileUrl(input) {
|
|
11242
|
+
return input.startsWith('file:');
|
|
11243
|
+
}
|
|
11244
|
+
function isRelative(input) {
|
|
11245
|
+
return /^[.?#]/.test(input);
|
|
11246
|
+
}
|
|
11247
|
+
function parseAbsoluteUrl(input) {
|
|
11248
|
+
const match = urlRegex.exec(input);
|
|
11249
|
+
return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
|
|
11250
|
+
}
|
|
11251
|
+
function parseFileUrl(input) {
|
|
11252
|
+
const match = fileRegex.exec(input);
|
|
11253
|
+
const path = match[2];
|
|
11254
|
+
return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
|
|
11255
|
+
}
|
|
11256
|
+
function makeUrl(scheme, user, host, port, path, query, hash) {
|
|
11257
|
+
return {
|
|
11258
|
+
scheme,
|
|
11259
|
+
user,
|
|
11260
|
+
host,
|
|
11261
|
+
port,
|
|
11262
|
+
path,
|
|
11263
|
+
query,
|
|
11264
|
+
hash,
|
|
11265
|
+
type: UrlType.Absolute,
|
|
11266
|
+
};
|
|
11267
|
+
}
|
|
11268
|
+
function parseUrl(input) {
|
|
11269
|
+
if (isSchemeRelativeUrl(input)) {
|
|
11270
|
+
const url = parseAbsoluteUrl('http:' + input);
|
|
11271
|
+
url.scheme = '';
|
|
11272
|
+
url.type = UrlType.SchemeRelative;
|
|
11273
|
+
return url;
|
|
11201
11274
|
}
|
|
11202
|
-
|
|
11203
|
-
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
return lastSuite;
|
|
11209
|
-
};
|
|
11210
|
-
definitions.sort((a, b) => a.start - b.start).forEach((definition) => {
|
|
11211
|
-
const latestSuite = updateLatestSuite(definition.start);
|
|
11212
|
-
let mode = definition.mode;
|
|
11213
|
-
if (latestSuite.mode !== "run")
|
|
11214
|
-
mode = latestSuite.mode;
|
|
11215
|
-
if (definition.type === "suite") {
|
|
11216
|
-
const task2 = {
|
|
11217
|
-
type: definition.type,
|
|
11218
|
-
id: "",
|
|
11219
|
-
suite: latestSuite,
|
|
11220
|
-
file,
|
|
11221
|
-
tasks: [],
|
|
11222
|
-
mode,
|
|
11223
|
-
name: definition.name,
|
|
11224
|
-
end: definition.end,
|
|
11225
|
-
start: definition.start,
|
|
11226
|
-
meta: {
|
|
11227
|
-
typecheck: true
|
|
11228
|
-
}
|
|
11229
|
-
};
|
|
11230
|
-
definition.task = task2;
|
|
11231
|
-
latestSuite.tasks.push(task2);
|
|
11232
|
-
lastSuite = task2;
|
|
11233
|
-
return;
|
|
11275
|
+
if (isAbsolutePath(input)) {
|
|
11276
|
+
const url = parseAbsoluteUrl('http://foo.com' + input);
|
|
11277
|
+
url.scheme = '';
|
|
11278
|
+
url.host = '';
|
|
11279
|
+
url.type = UrlType.AbsolutePath;
|
|
11280
|
+
return url;
|
|
11234
11281
|
}
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
|
|
11243
|
-
|
|
11244
|
-
|
|
11245
|
-
|
|
11246
|
-
|
|
11247
|
-
|
|
11248
|
-
|
|
11249
|
-
|
|
11250
|
-
definition.task = task;
|
|
11251
|
-
latestSuite.tasks.push(task);
|
|
11252
|
-
});
|
|
11253
|
-
calculateSuiteHash(file);
|
|
11254
|
-
const hasOnly = someTasksAreOnly(file);
|
|
11255
|
-
interpretTaskModes(file, ctx.config.testNamePattern, hasOnly, false, ctx.config.allowOnly);
|
|
11256
|
-
return {
|
|
11257
|
-
file,
|
|
11258
|
-
parsed: request.code,
|
|
11259
|
-
filepath,
|
|
11260
|
-
map: request.map,
|
|
11261
|
-
definitions
|
|
11262
|
-
};
|
|
11282
|
+
if (isFileUrl(input))
|
|
11283
|
+
return parseFileUrl(input);
|
|
11284
|
+
if (isAbsoluteUrl(input))
|
|
11285
|
+
return parseAbsoluteUrl(input);
|
|
11286
|
+
const url = parseAbsoluteUrl('http://foo.com/' + input);
|
|
11287
|
+
url.scheme = '';
|
|
11288
|
+
url.host = '';
|
|
11289
|
+
url.type = input
|
|
11290
|
+
? input.startsWith('?')
|
|
11291
|
+
? UrlType.Query
|
|
11292
|
+
: input.startsWith('#')
|
|
11293
|
+
? UrlType.Hash
|
|
11294
|
+
: UrlType.RelativePath
|
|
11295
|
+
: UrlType.Empty;
|
|
11296
|
+
return url;
|
|
11263
11297
|
}
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
}
|
|
11298
|
+
function stripPathFilename(path) {
|
|
11299
|
+
// If a path ends with a parent directory "..", then it's a relative path with excess parent
|
|
11300
|
+
// paths. It's not a file, so we can't strip it.
|
|
11301
|
+
if (path.endsWith('/..'))
|
|
11302
|
+
return path;
|
|
11303
|
+
const index = path.lastIndexOf('/');
|
|
11304
|
+
return path.slice(0, index + 1);
|
|
11272
11305
|
}
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
onParseStart(fn) {
|
|
11284
|
-
this._onParseStart = fn;
|
|
11285
|
-
}
|
|
11286
|
-
onParseEnd(fn) {
|
|
11287
|
-
this._onParseEnd = fn;
|
|
11288
|
-
}
|
|
11289
|
-
onWatcherRerun(fn) {
|
|
11290
|
-
this._onWatcherRerun = fn;
|
|
11291
|
-
}
|
|
11292
|
-
async collectFileTests(filepath) {
|
|
11293
|
-
return collectTests(this.ctx, filepath);
|
|
11294
|
-
}
|
|
11295
|
-
getFiles() {
|
|
11296
|
-
return this.files.filter((filename) => {
|
|
11297
|
-
const extension = extname(filename);
|
|
11298
|
-
return extension !== ".js" || this.allowJs;
|
|
11299
|
-
});
|
|
11300
|
-
}
|
|
11301
|
-
async collectTests() {
|
|
11302
|
-
const tests = (await Promise.all(
|
|
11303
|
-
this.getFiles().map((filepath) => this.collectFileTests(filepath))
|
|
11304
|
-
)).reduce((acc, data) => {
|
|
11305
|
-
if (!data)
|
|
11306
|
-
return acc;
|
|
11307
|
-
acc[data.filepath] = data;
|
|
11308
|
-
return acc;
|
|
11309
|
-
}, {});
|
|
11310
|
-
this._tests = tests;
|
|
11311
|
-
return tests;
|
|
11312
|
-
}
|
|
11313
|
-
markPassed(file) {
|
|
11314
|
-
var _a;
|
|
11315
|
-
if (!((_a = file.result) == null ? void 0 : _a.state)) {
|
|
11316
|
-
file.result = {
|
|
11317
|
-
state: "pass"
|
|
11318
|
-
};
|
|
11306
|
+
function mergePaths(url, base) {
|
|
11307
|
+
normalizePath(base, base.type);
|
|
11308
|
+
// If the path is just a "/", then it was an empty path to begin with (remember, we're a relative
|
|
11309
|
+
// path).
|
|
11310
|
+
if (url.path === '/') {
|
|
11311
|
+
url.path = base.path;
|
|
11312
|
+
}
|
|
11313
|
+
else {
|
|
11314
|
+
// Resolution happens relative to the base path's directory, not the file.
|
|
11315
|
+
url.path = stripPathFilename(base.path) + url.path;
|
|
11319
11316
|
}
|
|
11320
|
-
const markTasks = (tasks) => {
|
|
11321
|
-
var _a2;
|
|
11322
|
-
for (const task of tasks) {
|
|
11323
|
-
if ("tasks" in task)
|
|
11324
|
-
markTasks(task.tasks);
|
|
11325
|
-
if (!((_a2 = task.result) == null ? void 0 : _a2.state) && task.mode === "run") {
|
|
11326
|
-
task.result = {
|
|
11327
|
-
state: "pass"
|
|
11328
|
-
};
|
|
11329
|
-
}
|
|
11330
|
-
}
|
|
11331
|
-
};
|
|
11332
|
-
markTasks(file.tasks);
|
|
11333
|
-
}
|
|
11334
|
-
async prepareResults(output) {
|
|
11335
|
-
const typeErrors = await this.parseTscLikeOutput(output);
|
|
11336
|
-
const testFiles = new Set(this.getFiles());
|
|
11337
|
-
if (!this._tests)
|
|
11338
|
-
this._tests = await this.collectTests();
|
|
11339
|
-
const sourceErrors = [];
|
|
11340
|
-
const files = [];
|
|
11341
|
-
testFiles.forEach((path) => {
|
|
11342
|
-
const { file, definitions, map, parsed } = this._tests[path];
|
|
11343
|
-
const errors = typeErrors.get(path);
|
|
11344
|
-
files.push(file);
|
|
11345
|
-
if (!errors) {
|
|
11346
|
-
this.markPassed(file);
|
|
11347
|
-
return;
|
|
11348
|
-
}
|
|
11349
|
-
const sortedDefinitions = [...definitions.sort((a, b) => b.start - a.start)];
|
|
11350
|
-
const mapConsumer = map && new SourceMapConsumer(map);
|
|
11351
|
-
const indexMap = createIndexMap(parsed);
|
|
11352
|
-
const markState = (task, state) => {
|
|
11353
|
-
task.result = {
|
|
11354
|
-
state: task.mode === "run" || task.mode === "only" ? state : task.mode
|
|
11355
|
-
};
|
|
11356
|
-
if (task.suite)
|
|
11357
|
-
markState(task.suite, state);
|
|
11358
|
-
};
|
|
11359
|
-
errors.forEach(({ error, originalError }) => {
|
|
11360
|
-
var _a;
|
|
11361
|
-
const processedPos = (mapConsumer == null ? void 0 : mapConsumer.generatedPositionFor({
|
|
11362
|
-
line: originalError.line,
|
|
11363
|
-
column: originalError.column,
|
|
11364
|
-
source: basename(path)
|
|
11365
|
-
})) || originalError;
|
|
11366
|
-
const line = processedPos.line ?? originalError.line;
|
|
11367
|
-
const column = processedPos.column ?? originalError.column;
|
|
11368
|
-
const index = indexMap.get(`${line}:${column}`);
|
|
11369
|
-
const definition = index != null && sortedDefinitions.find((def) => def.start <= index && def.end >= index);
|
|
11370
|
-
const suite = definition ? definition.task : file;
|
|
11371
|
-
const state = suite.mode === "run" || suite.mode === "only" ? "fail" : suite.mode;
|
|
11372
|
-
const errors2 = ((_a = suite.result) == null ? void 0 : _a.errors) || [];
|
|
11373
|
-
suite.result = {
|
|
11374
|
-
state,
|
|
11375
|
-
errors: errors2
|
|
11376
|
-
};
|
|
11377
|
-
errors2.push(error);
|
|
11378
|
-
if (state === "fail" && suite.suite)
|
|
11379
|
-
markState(suite.suite, "fail");
|
|
11380
|
-
});
|
|
11381
|
-
this.markPassed(file);
|
|
11382
|
-
});
|
|
11383
|
-
typeErrors.forEach((errors, path) => {
|
|
11384
|
-
if (!testFiles.has(path))
|
|
11385
|
-
sourceErrors.push(...errors.map(({ error }) => error));
|
|
11386
|
-
});
|
|
11387
|
-
return {
|
|
11388
|
-
files,
|
|
11389
|
-
sourceErrors
|
|
11390
|
-
};
|
|
11391
|
-
}
|
|
11392
|
-
async parseTscLikeOutput(output) {
|
|
11393
|
-
const errorsMap = await getRawErrsMapFromTsCompile(output);
|
|
11394
|
-
const typesErrors = /* @__PURE__ */ new Map();
|
|
11395
|
-
errorsMap.forEach((errors, path) => {
|
|
11396
|
-
const filepath = resolve$2(this.ctx.config.root, path);
|
|
11397
|
-
const suiteErrors = errors.map((info) => {
|
|
11398
|
-
const limit = Error.stackTraceLimit;
|
|
11399
|
-
Error.stackTraceLimit = 0;
|
|
11400
|
-
const error = new TypeCheckError(info.errMsg, [
|
|
11401
|
-
{
|
|
11402
|
-
file: filepath,
|
|
11403
|
-
line: info.line,
|
|
11404
|
-
column: info.column,
|
|
11405
|
-
method: ""
|
|
11406
|
-
}
|
|
11407
|
-
]);
|
|
11408
|
-
Error.stackTraceLimit = limit;
|
|
11409
|
-
return {
|
|
11410
|
-
originalError: info,
|
|
11411
|
-
error
|
|
11412
|
-
};
|
|
11413
|
-
});
|
|
11414
|
-
typesErrors.set(filepath, suiteErrors);
|
|
11415
|
-
});
|
|
11416
|
-
return typesErrors;
|
|
11417
|
-
}
|
|
11418
|
-
async clear() {
|
|
11419
|
-
if (this.tempConfigPath)
|
|
11420
|
-
await rm(this.tempConfigPath, { force: true });
|
|
11421
|
-
}
|
|
11422
|
-
async stop() {
|
|
11423
|
-
var _a;
|
|
11424
|
-
await this.clear();
|
|
11425
|
-
(_a = this.process) == null ? void 0 : _a.kill();
|
|
11426
|
-
}
|
|
11427
|
-
async ensurePackageInstalled(root, checker) {
|
|
11428
|
-
if (checker !== "tsc" && checker !== "vue-tsc")
|
|
11429
|
-
return;
|
|
11430
|
-
const packageName = checker === "tsc" ? "typescript" : "vue-tsc";
|
|
11431
|
-
await ensurePackageInstalled(packageName, root);
|
|
11432
|
-
}
|
|
11433
|
-
async prepare() {
|
|
11434
|
-
const { root, typecheck } = this.ctx.config;
|
|
11435
|
-
await this.ensurePackageInstalled(root, typecheck.checker);
|
|
11436
|
-
const { config, path } = await getTsconfig(root, typecheck);
|
|
11437
|
-
this.tempConfigPath = path;
|
|
11438
|
-
this.allowJs = typecheck.allowJs || config.allowJs || false;
|
|
11439
|
-
}
|
|
11440
|
-
async start() {
|
|
11441
|
-
var _a, _b, _c;
|
|
11442
|
-
if (!this.tempConfigPath)
|
|
11443
|
-
throw new Error("tsconfig was not initialized");
|
|
11444
|
-
const { root, watch, typecheck } = this.ctx.config;
|
|
11445
|
-
const args = ["--noEmit", "--pretty", "false", "-p", this.tempConfigPath];
|
|
11446
|
-
if (watch)
|
|
11447
|
-
args.push("--watch");
|
|
11448
|
-
if (typecheck.allowJs)
|
|
11449
|
-
args.push("--allowJs", "--checkJs");
|
|
11450
|
-
let output = "";
|
|
11451
|
-
const child = execa(typecheck.checker, args, {
|
|
11452
|
-
cwd: root,
|
|
11453
|
-
stdout: "pipe",
|
|
11454
|
-
reject: false
|
|
11455
|
-
});
|
|
11456
|
-
this.process = child;
|
|
11457
|
-
await ((_a = this._onParseStart) == null ? void 0 : _a.call(this));
|
|
11458
|
-
let rerunTriggered = false;
|
|
11459
|
-
(_b = child.stdout) == null ? void 0 : _b.on("data", (chunk) => {
|
|
11460
|
-
var _a2;
|
|
11461
|
-
output += chunk;
|
|
11462
|
-
if (!watch)
|
|
11463
|
-
return;
|
|
11464
|
-
if (output.includes("File change detected") && !rerunTriggered) {
|
|
11465
|
-
(_a2 = this._onWatcherRerun) == null ? void 0 : _a2.call(this);
|
|
11466
|
-
this._result.sourceErrors = [];
|
|
11467
|
-
this._result.files = [];
|
|
11468
|
-
this._tests = null;
|
|
11469
|
-
rerunTriggered = true;
|
|
11470
|
-
}
|
|
11471
|
-
if (/Found \w+ errors*. Watching for/.test(output)) {
|
|
11472
|
-
rerunTriggered = false;
|
|
11473
|
-
this.prepareResults(output).then((result) => {
|
|
11474
|
-
var _a3;
|
|
11475
|
-
this._result = result;
|
|
11476
|
-
(_a3 = this._onParseEnd) == null ? void 0 : _a3.call(this, result);
|
|
11477
|
-
});
|
|
11478
|
-
output = "";
|
|
11479
|
-
}
|
|
11480
|
-
});
|
|
11481
|
-
if (!watch) {
|
|
11482
|
-
await child;
|
|
11483
|
-
this._result = await this.prepareResults(output);
|
|
11484
|
-
await ((_c = this._onParseEnd) == null ? void 0 : _c.call(this, this._result));
|
|
11485
|
-
}
|
|
11486
|
-
}
|
|
11487
|
-
getResult() {
|
|
11488
|
-
return this._result;
|
|
11489
|
-
}
|
|
11490
|
-
getTestFiles() {
|
|
11491
|
-
return Object.values(this._tests || {}).map((i) => i.file);
|
|
11492
|
-
}
|
|
11493
|
-
getTestPacks() {
|
|
11494
|
-
return Object.values(this._tests || {}).map(({ file }) => getTasks(file)).flat().map((i) => [i.id, void 0]);
|
|
11495
|
-
}
|
|
11496
|
-
}
|
|
11497
|
-
|
|
11498
|
-
async function printError(error, ctx, options = {}) {
|
|
11499
|
-
const { showCodeFrame = true, fullStack = false, type } = options;
|
|
11500
|
-
let e = error;
|
|
11501
|
-
if (isPrimitive(e)) {
|
|
11502
|
-
e = {
|
|
11503
|
-
message: String(error).split(/\n/g)[0],
|
|
11504
|
-
stack: String(error)
|
|
11505
|
-
};
|
|
11506
|
-
}
|
|
11507
|
-
if (!e) {
|
|
11508
|
-
const error2 = new Error("unknown error");
|
|
11509
|
-
e = {
|
|
11510
|
-
message: e ?? error2.message,
|
|
11511
|
-
stack: error2.stack
|
|
11512
|
-
};
|
|
11513
|
-
}
|
|
11514
|
-
if (!ctx.config)
|
|
11515
|
-
return printErrorMessage(e, ctx.logger);
|
|
11516
|
-
const stacks = parseErrorStacktrace(e, fullStack ? [] : void 0);
|
|
11517
|
-
const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find(
|
|
11518
|
-
(stack) => ctx.getModuleProjects(stack.file).length && existsSync(stack.file)
|
|
11519
|
-
);
|
|
11520
|
-
const errorProperties = getErrorProperties(e);
|
|
11521
|
-
if (type)
|
|
11522
|
-
printErrorType(type, ctx);
|
|
11523
|
-
printErrorMessage(e, ctx.logger);
|
|
11524
|
-
if (e.frame) {
|
|
11525
|
-
ctx.logger.error(c.yellow(e.frame));
|
|
11526
|
-
} else {
|
|
11527
|
-
printStack(ctx, stacks, nearest, errorProperties, (s) => {
|
|
11528
|
-
if (showCodeFrame && s === nearest && nearest) {
|
|
11529
|
-
const sourceCode = readFileSync(nearest.file, "utf-8");
|
|
11530
|
-
ctx.logger.error(c.yellow(generateCodeFrame(sourceCode, 4, s.line, s.column)));
|
|
11531
|
-
}
|
|
11532
|
-
});
|
|
11533
|
-
}
|
|
11534
|
-
const testPath = e.VITEST_TEST_PATH;
|
|
11535
|
-
const testName = e.VITEST_TEST_NAME;
|
|
11536
|
-
const afterEnvTeardown = e.VITEST_AFTER_ENV_TEARDOWN;
|
|
11537
|
-
if (testPath)
|
|
11538
|
-
ctx.logger.error(c.red(`This error originated in "${c.bold(testPath)}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`));
|
|
11539
|
-
if (testName) {
|
|
11540
|
-
ctx.logger.error(c.red(`The latest test that might've caused the error is "${c.bold(testName)}". It might mean one of the following:
|
|
11541
|
-
- The error was thrown, while Vitest was running this test.
|
|
11542
|
-
- This was the last recorded test before the error was thrown, if error originated after test finished its execution.`));
|
|
11543
|
-
}
|
|
11544
|
-
if (afterEnvTeardown) {
|
|
11545
|
-
ctx.logger.error(c.red("This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:\n- cancel timeouts using clearTimeout and clearInterval\n- wait for promises to resolve using the await keyword"));
|
|
11546
|
-
}
|
|
11547
|
-
if (typeof e.cause === "object" && e.cause && "name" in e.cause) {
|
|
11548
|
-
e.cause.name = `Caused by: ${e.cause.name}`;
|
|
11549
|
-
await printError(e.cause, ctx, { fullStack, showCodeFrame: false });
|
|
11550
|
-
}
|
|
11551
|
-
handleImportOutsideModuleError(e.stack || e.stackStr || "", ctx);
|
|
11552
|
-
if (e.diff)
|
|
11553
|
-
displayDiff(e.diff, ctx.logger.console);
|
|
11554
|
-
}
|
|
11555
|
-
function printErrorType(type, ctx) {
|
|
11556
|
-
ctx.logger.error(`
|
|
11557
|
-
${c.red(divider(c.bold(c.inverse(` ${type} `))))}`);
|
|
11558
|
-
}
|
|
11559
|
-
const skipErrorProperties = /* @__PURE__ */ new Set([
|
|
11560
|
-
"nameStr",
|
|
11561
|
-
"stack",
|
|
11562
|
-
"cause",
|
|
11563
|
-
"stacks",
|
|
11564
|
-
"stackStr",
|
|
11565
|
-
"type",
|
|
11566
|
-
"showDiff",
|
|
11567
|
-
"diff",
|
|
11568
|
-
"actual",
|
|
11569
|
-
"expected",
|
|
11570
|
-
"VITEST_TEST_NAME",
|
|
11571
|
-
"VITEST_TEST_PATH",
|
|
11572
|
-
"VITEST_AFTER_ENV_TEARDOWN",
|
|
11573
|
-
...Object.getOwnPropertyNames(Error.prototype),
|
|
11574
|
-
...Object.getOwnPropertyNames(Object.prototype)
|
|
11575
|
-
]);
|
|
11576
|
-
function getErrorProperties(e) {
|
|
11577
|
-
const errorObject = /* @__PURE__ */ Object.create(null);
|
|
11578
|
-
if (e.name === "AssertionError")
|
|
11579
|
-
return errorObject;
|
|
11580
|
-
for (const key of Object.getOwnPropertyNames(e)) {
|
|
11581
|
-
if (!skipErrorProperties.has(key))
|
|
11582
|
-
errorObject[key] = e[key];
|
|
11583
|
-
}
|
|
11584
|
-
return errorObject;
|
|
11585
|
-
}
|
|
11586
|
-
const esmErrors = [
|
|
11587
|
-
"Cannot use import statement outside a module",
|
|
11588
|
-
"Unexpected token 'export'"
|
|
11589
|
-
];
|
|
11590
|
-
function handleImportOutsideModuleError(stack, ctx) {
|
|
11591
|
-
if (!esmErrors.some((e) => stack.includes(e)))
|
|
11592
|
-
return;
|
|
11593
|
-
const path = normalize(stack.split("\n")[0].trim());
|
|
11594
|
-
let name = path.split("/node_modules/").pop() || "";
|
|
11595
|
-
if (name == null ? void 0 : name.startsWith("@"))
|
|
11596
|
-
name = name.split("/").slice(0, 2).join("/");
|
|
11597
|
-
else
|
|
11598
|
-
name = name.split("/")[0];
|
|
11599
|
-
ctx.logger.error(c.yellow(
|
|
11600
|
-
`Module ${path} seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package ${c.bold(`"${name}"`)} asking them to ship the file in .mjs extension or add "type": "module" in their package.json.
|
|
11601
|
-
|
|
11602
|
-
As a temporary workaround you can try to inline the package by updating your config:
|
|
11603
|
-
|
|
11604
|
-
` + c.gray(c.dim("// vitest.config.js")) + "\n" + c.green(`export default {
|
|
11605
|
-
test: {
|
|
11606
|
-
deps: {
|
|
11607
|
-
inline: [
|
|
11608
|
-
${c.yellow(c.bold(`"${name}"`))}
|
|
11609
|
-
]
|
|
11610
|
-
}
|
|
11611
|
-
}
|
|
11612
|
-
}
|
|
11613
|
-
`)
|
|
11614
|
-
));
|
|
11615
|
-
}
|
|
11616
|
-
function displayDiff(diff, console) {
|
|
11617
|
-
console.error(diff);
|
|
11618
|
-
}
|
|
11619
|
-
function printErrorMessage(error, logger) {
|
|
11620
|
-
const errorName = error.name || error.nameStr || "Unknown Error";
|
|
11621
|
-
logger.error(c.red(`${c.bold(errorName)}: ${error.message}`));
|
|
11622
|
-
}
|
|
11623
|
-
function printStack(ctx, stack, highlight, errorProperties, onStack) {
|
|
11624
|
-
const logger = ctx.logger;
|
|
11625
|
-
for (const frame of stack) {
|
|
11626
|
-
const color = frame === highlight ? c.yellow : c.gray;
|
|
11627
|
-
const path = relative(ctx.config.root, frame.file);
|
|
11628
|
-
logger.error(color(` ${c.dim(F_POINTER)} ${[frame.method, c.dim(`${path}:${frame.line}:${frame.column}`)].filter(Boolean).join(" ")}`));
|
|
11629
|
-
onStack == null ? void 0 : onStack(frame);
|
|
11630
|
-
}
|
|
11631
|
-
if (stack.length)
|
|
11632
|
-
logger.error();
|
|
11633
|
-
const hasProperties = Object.keys(errorProperties).length > 0;
|
|
11634
|
-
if (hasProperties) {
|
|
11635
|
-
logger.error(c.red(c.dim(divider())));
|
|
11636
|
-
const propertiesString = stringify$5(errorProperties, 10, { printBasicPrototype: false });
|
|
11637
|
-
logger.error(c.red(c.bold("Serialized Error:")), c.gray(propertiesString));
|
|
11638
|
-
}
|
|
11639
|
-
}
|
|
11640
|
-
function generateCodeFrame(source, indent = 0, lineNumber, columnNumber, range = 2) {
|
|
11641
|
-
var _a;
|
|
11642
|
-
const start = positionToOffset(source, lineNumber, columnNumber);
|
|
11643
|
-
const end = start;
|
|
11644
|
-
const lines = source.split(lineSplitRE);
|
|
11645
|
-
let count = 0;
|
|
11646
|
-
let res = [];
|
|
11647
|
-
const columns = ((_a = process.stdout) == null ? void 0 : _a.columns) || 80;
|
|
11648
|
-
function lineNo(no = "") {
|
|
11649
|
-
return c.gray(`${String(no).padStart(3, " ")}| `);
|
|
11650
|
-
}
|
|
11651
|
-
for (let i = 0; i < lines.length; i++) {
|
|
11652
|
-
count += lines[i].length + 1;
|
|
11653
|
-
if (count >= start) {
|
|
11654
|
-
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
11655
|
-
if (j < 0 || j >= lines.length)
|
|
11656
|
-
continue;
|
|
11657
|
-
const lineLength = lines[j].length;
|
|
11658
|
-
if (lineLength > 200)
|
|
11659
|
-
return "";
|
|
11660
|
-
res.push(lineNo(j + 1) + cliTruncate(lines[j].replace(/\t/g, " "), columns - 5 - indent));
|
|
11661
|
-
if (j === i) {
|
|
11662
|
-
const pad = start - (count - lineLength);
|
|
11663
|
-
const length = Math.max(1, end > count ? lineLength - pad : end - start);
|
|
11664
|
-
res.push(lineNo() + " ".repeat(pad) + c.red("^".repeat(length)));
|
|
11665
|
-
} else if (j > i) {
|
|
11666
|
-
if (end > count) {
|
|
11667
|
-
const length = Math.max(1, Math.min(end - count, lineLength));
|
|
11668
|
-
res.push(lineNo() + c.red("^".repeat(length)));
|
|
11669
|
-
}
|
|
11670
|
-
count += lineLength + 1;
|
|
11671
|
-
}
|
|
11672
|
-
}
|
|
11673
|
-
break;
|
|
11674
|
-
}
|
|
11675
|
-
}
|
|
11676
|
-
if (indent)
|
|
11677
|
-
res = res.map((line) => " ".repeat(indent) + line);
|
|
11678
|
-
return res.join("\n");
|
|
11679
|
-
}
|
|
11680
|
-
|
|
11681
|
-
class Logger {
|
|
11682
|
-
constructor(ctx, console = globalThis.console) {
|
|
11683
|
-
this.ctx = ctx;
|
|
11684
|
-
this.console = console;
|
|
11685
|
-
this.outputStream = process.stdout;
|
|
11686
|
-
this.errorStream = process.stderr;
|
|
11687
|
-
this.logUpdate = createLogUpdate(process.stdout);
|
|
11688
|
-
}
|
|
11689
|
-
log(...args) {
|
|
11690
|
-
this._clearScreen();
|
|
11691
|
-
this.console.log(...args);
|
|
11692
|
-
}
|
|
11693
|
-
error(...args) {
|
|
11694
|
-
this._clearScreen();
|
|
11695
|
-
this.console.error(...args);
|
|
11696
|
-
}
|
|
11697
|
-
warn(...args) {
|
|
11698
|
-
this._clearScreen();
|
|
11699
|
-
this.console.warn(...args);
|
|
11700
|
-
}
|
|
11701
|
-
clearFullScreen(message) {
|
|
11702
|
-
if (this.ctx.server.config.clearScreen === false) {
|
|
11703
|
-
this.console.log(message);
|
|
11704
|
-
return;
|
|
11705
|
-
}
|
|
11706
|
-
this.console.log(`\x1Bc${message}`);
|
|
11707
|
-
}
|
|
11708
|
-
clearScreen(message, force = false) {
|
|
11709
|
-
if (this.ctx.server.config.clearScreen === false) {
|
|
11710
|
-
this.console.log(message);
|
|
11711
|
-
return;
|
|
11712
|
-
}
|
|
11713
|
-
this._clearScreenPending = message;
|
|
11714
|
-
if (force)
|
|
11715
|
-
this._clearScreen();
|
|
11716
|
-
}
|
|
11717
|
-
_clearScreen() {
|
|
11718
|
-
if (this._clearScreenPending == null)
|
|
11719
|
-
return;
|
|
11720
|
-
const log = this._clearScreenPending;
|
|
11721
|
-
this._clearScreenPending = void 0;
|
|
11722
|
-
this.console.log(`\x1B[1;1H\x1B[J${log}`);
|
|
11723
|
-
}
|
|
11724
|
-
printError(err, fullStack = false, type) {
|
|
11725
|
-
return printError(err, this.ctx, {
|
|
11726
|
-
fullStack,
|
|
11727
|
-
type,
|
|
11728
|
-
showCodeFrame: true
|
|
11729
|
-
});
|
|
11730
|
-
}
|
|
11731
|
-
printNoTestFound(filters) {
|
|
11732
|
-
const config = this.ctx.config;
|
|
11733
|
-
const comma = c.dim(", ");
|
|
11734
|
-
if (filters == null ? void 0 : filters.length)
|
|
11735
|
-
this.console.error(c.dim("filter: ") + c.yellow(filters.join(comma)));
|
|
11736
|
-
if (config.include)
|
|
11737
|
-
this.console.error(c.dim("include: ") + c.yellow(config.include.join(comma)));
|
|
11738
|
-
if (config.exclude)
|
|
11739
|
-
this.console.error(c.dim("exclude: ") + c.yellow(config.exclude.join(comma)));
|
|
11740
|
-
if (config.watchExclude)
|
|
11741
|
-
this.console.error(c.dim("watch exclude: ") + c.yellow(config.watchExclude.join(comma)));
|
|
11742
|
-
if (config.passWithNoTests)
|
|
11743
|
-
this.log(`No ${config.mode} files found, exiting with code 0
|
|
11744
|
-
`);
|
|
11745
|
-
else
|
|
11746
|
-
this.error(c.red(`
|
|
11747
|
-
No ${config.mode} files found, exiting with code 1`));
|
|
11748
|
-
}
|
|
11749
|
-
printBanner() {
|
|
11750
|
-
var _a, _b;
|
|
11751
|
-
this.log();
|
|
11752
|
-
const versionTest = this.ctx.config.watch ? c.blue(`v${version}`) : c.cyan(`v${version}`);
|
|
11753
|
-
const mode = this.ctx.config.watch ? c.blue(" DEV ") : c.cyan(" RUN ");
|
|
11754
|
-
this.log(`${c.inverse(c.bold(mode))} ${versionTest} ${c.gray(this.ctx.config.root)}`);
|
|
11755
|
-
if (this.ctx.config.sequence.sequencer === RandomSequencer)
|
|
11756
|
-
this.log(c.gray(` Running tests with seed "${this.ctx.config.sequence.seed}"`));
|
|
11757
|
-
this.ctx.projects.forEach((project) => {
|
|
11758
|
-
var _a2;
|
|
11759
|
-
if (!project.browser)
|
|
11760
|
-
return;
|
|
11761
|
-
const name = project.getName();
|
|
11762
|
-
const output = project.isCore() ? "" : ` [${name}]`;
|
|
11763
|
-
this.log(c.dim(c.green(` ${output} Browser runner started at http://${((_a2 = project.config.browser.api) == null ? void 0 : _a2.host) || "localhost"}:${c.bold(`${project.browser.config.server.port}`)}`)));
|
|
11764
|
-
});
|
|
11765
|
-
if (this.ctx.config.ui)
|
|
11766
|
-
this.log(c.dim(c.green(` UI started at http://${((_a = this.ctx.config.api) == null ? void 0 : _a.host) || "localhost"}:${c.bold(`${this.ctx.server.config.server.port}`)}${this.ctx.config.uiBase}`)));
|
|
11767
|
-
else if (this.ctx.config.api)
|
|
11768
|
-
this.log(c.dim(c.green(` API started at http://${((_b = this.ctx.config.api) == null ? void 0 : _b.host) || "localhost"}:${c.bold(`${this.ctx.config.api.port}`)}`)));
|
|
11769
|
-
if (this.ctx.coverageProvider)
|
|
11770
|
-
this.log(c.dim(" Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name));
|
|
11771
|
-
this.log();
|
|
11772
|
-
}
|
|
11773
|
-
async printUnhandledErrors(errors) {
|
|
11774
|
-
const errorMessage = c.red(c.bold(
|
|
11775
|
-
`
|
|
11776
|
-
Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
|
|
11777
|
-
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`
|
|
11778
|
-
));
|
|
11779
|
-
this.log(c.red(divider(c.bold(c.inverse(" Unhandled Errors ")))));
|
|
11780
|
-
this.log(errorMessage);
|
|
11781
|
-
await Promise.all(errors.map(async (err) => {
|
|
11782
|
-
await this.printError(err, true, err.type || "Unhandled Error");
|
|
11783
|
-
}));
|
|
11784
|
-
this.log(c.red(divider()));
|
|
11785
|
-
}
|
|
11786
|
-
async printSourceTypeErrors(errors) {
|
|
11787
|
-
const errorMessage = c.red(c.bold(
|
|
11788
|
-
`
|
|
11789
|
-
Vitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related to your test files.`
|
|
11790
|
-
));
|
|
11791
|
-
this.log(c.red(divider(c.bold(c.inverse(" Source Errors ")))));
|
|
11792
|
-
this.log(errorMessage);
|
|
11793
|
-
await Promise.all(errors.map(async (err) => {
|
|
11794
|
-
await this.printError(err, true);
|
|
11795
|
-
}));
|
|
11796
|
-
this.log(c.red(divider()));
|
|
11797
|
-
}
|
|
11798
|
-
}
|
|
11799
|
-
|
|
11800
|
-
function CoverageTransform(ctx) {
|
|
11801
|
-
return {
|
|
11802
|
-
name: "vitest:coverage-transform",
|
|
11803
|
-
transform(srcCode, id) {
|
|
11804
|
-
var _a, _b;
|
|
11805
|
-
return (_b = (_a = ctx.coverageProvider) == null ? void 0 : _a.onFileTransform) == null ? void 0 : _b.call(_a, srcCode, normalizeRequestId(id), this);
|
|
11806
|
-
}
|
|
11807
|
-
};
|
|
11808
|
-
}
|
|
11809
|
-
|
|
11810
|
-
async function createBrowserServer(project, options) {
|
|
11811
|
-
const root = project.config.root;
|
|
11812
|
-
await ensurePackageInstalled("@vitest/browser", root);
|
|
11813
|
-
const configPath = options.config === false ? false : options.config ? resolve$2(root, options.config) : await findUp(configFiles, { cwd: root });
|
|
11814
|
-
const server = await createServer({
|
|
11815
|
-
logLevel: "error",
|
|
11816
|
-
mode: project.config.mode,
|
|
11817
|
-
configFile: configPath,
|
|
11818
|
-
// watch is handled by Vitest
|
|
11819
|
-
server: {
|
|
11820
|
-
hmr: false,
|
|
11821
|
-
watch: {
|
|
11822
|
-
ignored: ["**/**"]
|
|
11823
|
-
}
|
|
11824
|
-
},
|
|
11825
|
-
plugins: [
|
|
11826
|
-
(await import('@vitest/browser')).default("/"),
|
|
11827
|
-
CoverageTransform(project.ctx),
|
|
11828
|
-
{
|
|
11829
|
-
enforce: "post",
|
|
11830
|
-
name: "vitest:browser:config",
|
|
11831
|
-
async config(config) {
|
|
11832
|
-
var _a, _b;
|
|
11833
|
-
const server2 = resolveApiServerConfig(((_a = config.test) == null ? void 0 : _a.browser) || {}) || {
|
|
11834
|
-
port: defaultBrowserPort
|
|
11835
|
-
};
|
|
11836
|
-
config.server = server2;
|
|
11837
|
-
config.server.fs = { strict: false };
|
|
11838
|
-
return {
|
|
11839
|
-
resolve: {
|
|
11840
|
-
alias: (_b = config.test) == null ? void 0 : _b.alias
|
|
11841
|
-
}
|
|
11842
|
-
};
|
|
11843
|
-
}
|
|
11844
|
-
}
|
|
11845
|
-
]
|
|
11846
|
-
});
|
|
11847
|
-
await server.listen();
|
|
11848
|
-
await server.watcher.close();
|
|
11849
|
-
(await import('./chunk-api-setup.c93e5069.js')).setup(project, server);
|
|
11850
|
-
return server;
|
|
11851
|
-
}
|
|
11852
|
-
|
|
11853
|
-
const playwrightBrowsers = ["firefox", "webkit", "chromium"];
|
|
11854
|
-
class PlaywrightBrowserProvider {
|
|
11855
|
-
constructor() {
|
|
11856
|
-
this.name = "playwright";
|
|
11857
|
-
this.cachedBrowser = null;
|
|
11858
|
-
}
|
|
11859
|
-
getSupportedBrowsers() {
|
|
11860
|
-
return playwrightBrowsers;
|
|
11861
|
-
}
|
|
11862
|
-
async initialize(ctx, { browser }) {
|
|
11863
|
-
this.ctx = ctx;
|
|
11864
|
-
this.browser = browser;
|
|
11865
|
-
const root = this.ctx.config.root;
|
|
11866
|
-
if (!await ensurePackageInstalled("playwright", root))
|
|
11867
|
-
throw new Error('Cannot find "playwright" package. Please install it manually.');
|
|
11868
|
-
}
|
|
11869
|
-
async openBrowser() {
|
|
11870
|
-
if (this.cachedBrowser)
|
|
11871
|
-
return this.cachedBrowser;
|
|
11872
|
-
const options = this.ctx.config.browser;
|
|
11873
|
-
const playwright = await import('playwright');
|
|
11874
|
-
const playwrightInstance = await playwright[this.browser].launch({ headless: options.headless });
|
|
11875
|
-
this.cachedBrowser = await playwrightInstance.newPage();
|
|
11876
|
-
this.cachedBrowser.on("close", () => {
|
|
11877
|
-
playwrightInstance.close();
|
|
11878
|
-
});
|
|
11879
|
-
return this.cachedBrowser;
|
|
11880
|
-
}
|
|
11881
|
-
async openPage(url) {
|
|
11882
|
-
const browserInstance = await this.openBrowser();
|
|
11883
|
-
await browserInstance.goto(url);
|
|
11884
|
-
}
|
|
11885
|
-
async close() {
|
|
11886
|
-
var _a;
|
|
11887
|
-
await ((_a = this.cachedBrowser) == null ? void 0 : _a.close());
|
|
11888
|
-
process.exit();
|
|
11889
|
-
}
|
|
11890
|
-
}
|
|
11891
|
-
|
|
11892
|
-
const webdriverBrowsers = ["firefox", "chrome", "edge", "safari"];
|
|
11893
|
-
class WebdriverBrowserProvider {
|
|
11894
|
-
constructor() {
|
|
11895
|
-
this.name = "webdriverio";
|
|
11896
|
-
this.cachedBrowser = null;
|
|
11897
|
-
this.stopSafari = () => {
|
|
11898
|
-
};
|
|
11899
|
-
}
|
|
11900
|
-
getSupportedBrowsers() {
|
|
11901
|
-
return webdriverBrowsers;
|
|
11902
|
-
}
|
|
11903
|
-
async initialize(ctx, { browser }) {
|
|
11904
|
-
this.ctx = ctx;
|
|
11905
|
-
this.browser = browser;
|
|
11906
|
-
const root = this.ctx.config.root;
|
|
11907
|
-
if (!await ensurePackageInstalled("webdriverio", root))
|
|
11908
|
-
throw new Error('Cannot find "webdriverio" package. Please install it manually.');
|
|
11909
|
-
if (browser === "safari" && !await ensurePackageInstalled("safaridriver", root))
|
|
11910
|
-
throw new Error('Cannot find "safaridriver" package. Please install it manually.');
|
|
11911
|
-
}
|
|
11912
|
-
async openBrowser() {
|
|
11913
|
-
if (this.cachedBrowser)
|
|
11914
|
-
return this.cachedBrowser;
|
|
11915
|
-
const options = this.ctx.config.browser;
|
|
11916
|
-
if (this.browser === "safari") {
|
|
11917
|
-
const safaridriver = await import('safaridriver');
|
|
11918
|
-
safaridriver.start({ diagnose: true });
|
|
11919
|
-
this.stopSafari = () => safaridriver.stop();
|
|
11920
|
-
process.on("beforeExit", () => {
|
|
11921
|
-
safaridriver.stop();
|
|
11922
|
-
});
|
|
11923
|
-
}
|
|
11924
|
-
const { remote } = await import('webdriverio');
|
|
11925
|
-
this.cachedBrowser = await remote({
|
|
11926
|
-
logLevel: "error",
|
|
11927
|
-
capabilities: {
|
|
11928
|
-
"browserName": this.browser,
|
|
11929
|
-
"wdio:devtoolsOptions": { headless: options.headless }
|
|
11930
|
-
}
|
|
11931
|
-
});
|
|
11932
|
-
return this.cachedBrowser;
|
|
11933
|
-
}
|
|
11934
|
-
async openPage(url) {
|
|
11935
|
-
const browserInstance = await this.openBrowser();
|
|
11936
|
-
await browserInstance.url(url);
|
|
11937
|
-
}
|
|
11938
|
-
async close() {
|
|
11939
|
-
var _a, _b, _c;
|
|
11940
|
-
await Promise.all([
|
|
11941
|
-
this.stopSafari(),
|
|
11942
|
-
((_a = this.cachedBrowser) == null ? void 0 : _a.sessionId) ? (_c = (_b = this.cachedBrowser) == null ? void 0 : _b.deleteSession) == null ? void 0 : _c.call(_b) : null
|
|
11943
|
-
]);
|
|
11944
|
-
process.exit();
|
|
11945
|
-
}
|
|
11946
|
-
}
|
|
11947
|
-
|
|
11948
|
-
async function getBrowserProvider(options, loader) {
|
|
11949
|
-
switch (options.provider) {
|
|
11950
|
-
case void 0:
|
|
11951
|
-
case "webdriverio":
|
|
11952
|
-
return WebdriverBrowserProvider;
|
|
11953
|
-
case "playwright":
|
|
11954
|
-
return PlaywrightBrowserProvider;
|
|
11955
|
-
}
|
|
11956
|
-
let customProviderModule;
|
|
11957
|
-
try {
|
|
11958
|
-
customProviderModule = await loader.executeId(options.provider);
|
|
11959
|
-
} catch (error) {
|
|
11960
|
-
throw new Error(`Failed to load custom BrowserProvider from ${options.provider}`, { cause: error });
|
|
11961
|
-
}
|
|
11962
|
-
if (customProviderModule.default == null)
|
|
11963
|
-
throw new Error(`Custom BrowserProvider loaded from ${options.provider} was not the default export`);
|
|
11964
|
-
return customProviderModule.default;
|
|
11965
|
-
}
|
|
11966
|
-
|
|
11967
|
-
function generateCssFilenameHash(filepath) {
|
|
11968
|
-
return createHash("md5").update(filepath).digest("hex").slice(0, 6);
|
|
11969
|
-
}
|
|
11970
|
-
function generateScopedClassName(strategy, name, filename) {
|
|
11971
|
-
if (strategy === "scoped")
|
|
11972
|
-
return null;
|
|
11973
|
-
if (strategy === "non-scoped")
|
|
11974
|
-
return name;
|
|
11975
|
-
const hash = generateCssFilenameHash(filename);
|
|
11976
|
-
return `_${name}_${hash}`;
|
|
11977
|
-
}
|
|
11978
|
-
|
|
11979
|
-
const cssLangs = "\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)";
|
|
11980
|
-
const cssLangRE = new RegExp(cssLangs);
|
|
11981
|
-
const cssModuleRE = new RegExp(`\\.module${cssLangs}`);
|
|
11982
|
-
function isCSS(id) {
|
|
11983
|
-
return cssLangRE.test(id);
|
|
11984
|
-
}
|
|
11985
|
-
function isCSSModule(id) {
|
|
11986
|
-
return cssModuleRE.test(id);
|
|
11987
|
-
}
|
|
11988
|
-
function getCSSModuleProxyReturn(strategy, filename) {
|
|
11989
|
-
if (strategy === "non-scoped")
|
|
11990
|
-
return "style";
|
|
11991
|
-
const hash = generateCssFilenameHash(filename);
|
|
11992
|
-
return `\`_\${style}_${hash}\``;
|
|
11993
|
-
}
|
|
11994
|
-
function CSSEnablerPlugin(ctx) {
|
|
11995
|
-
const shouldProcessCSS = (id) => {
|
|
11996
|
-
const { css } = ctx.config;
|
|
11997
|
-
if (typeof css === "boolean")
|
|
11998
|
-
return css;
|
|
11999
|
-
if (toArray(css.exclude).some((re) => re.test(id)))
|
|
12000
|
-
return false;
|
|
12001
|
-
if (toArray(css.include).some((re) => re.test(id)))
|
|
12002
|
-
return true;
|
|
12003
|
-
return false;
|
|
12004
|
-
};
|
|
12005
|
-
return [
|
|
12006
|
-
{
|
|
12007
|
-
name: "vitest:css-disable",
|
|
12008
|
-
enforce: "pre",
|
|
12009
|
-
transform(code, id) {
|
|
12010
|
-
if (!isCSS(id))
|
|
12011
|
-
return;
|
|
12012
|
-
if (!shouldProcessCSS(id))
|
|
12013
|
-
return { code: "" };
|
|
12014
|
-
}
|
|
12015
|
-
},
|
|
12016
|
-
{
|
|
12017
|
-
name: "vitest:css-empty-post",
|
|
12018
|
-
enforce: "post",
|
|
12019
|
-
transform(_, id) {
|
|
12020
|
-
var _a;
|
|
12021
|
-
if (!isCSS(id) || shouldProcessCSS(id))
|
|
12022
|
-
return;
|
|
12023
|
-
if (isCSSModule(id)) {
|
|
12024
|
-
const scopeStrategy = typeof ctx.config.css !== "boolean" && ((_a = ctx.config.css.modules) == null ? void 0 : _a.classNameStrategy) || "stable";
|
|
12025
|
-
const proxyReturn = getCSSModuleProxyReturn(scopeStrategy, relative(ctx.config.root, id));
|
|
12026
|
-
const code = `export default new Proxy(Object.create(null), {
|
|
12027
|
-
get(_, style) {
|
|
12028
|
-
return ${proxyReturn};
|
|
12029
|
-
},
|
|
12030
|
-
})`;
|
|
12031
|
-
return { code };
|
|
12032
|
-
}
|
|
12033
|
-
return { code: 'export default ""' };
|
|
12034
|
-
}
|
|
12035
|
-
}
|
|
12036
|
-
];
|
|
12037
|
-
}
|
|
12038
|
-
|
|
12039
|
-
function EnvReplacerPlugin() {
|
|
12040
|
-
return {
|
|
12041
|
-
name: "vitest:env-replacer",
|
|
12042
|
-
enforce: "pre",
|
|
12043
|
-
transform(code, id) {
|
|
12044
|
-
if (!/\bimport\.meta\.env\b/g.test(code))
|
|
12045
|
-
return null;
|
|
12046
|
-
let s = null;
|
|
12047
|
-
const envs = stripLiteral(code).matchAll(/\bimport\.meta\.env\b/g);
|
|
12048
|
-
for (const env of envs) {
|
|
12049
|
-
s || (s = new MagicString(code));
|
|
12050
|
-
const startIndex = env.index;
|
|
12051
|
-
const endIndex = startIndex + env[0].length;
|
|
12052
|
-
s.overwrite(startIndex, endIndex, "process.env");
|
|
12053
|
-
}
|
|
12054
|
-
if (s) {
|
|
12055
|
-
return {
|
|
12056
|
-
code: s.toString(),
|
|
12057
|
-
map: s.generateMap({
|
|
12058
|
-
hires: true,
|
|
12059
|
-
// Remove possible query parameters, e.g. vue's "?vue&type=script&src=true&lang.ts"
|
|
12060
|
-
source: cleanUrl(id)
|
|
12061
|
-
})
|
|
12062
|
-
};
|
|
12063
|
-
}
|
|
12064
|
-
}
|
|
12065
|
-
};
|
|
12066
|
-
}
|
|
12067
|
-
|
|
12068
|
-
async function loadGlobalSetupFiles(project) {
|
|
12069
|
-
var _a;
|
|
12070
|
-
const server = project.server;
|
|
12071
|
-
const runner = project.runner;
|
|
12072
|
-
const globalSetupFiles = toArray((_a = server.config.test) == null ? void 0 : _a.globalSetup);
|
|
12073
|
-
return Promise.all(globalSetupFiles.map((file) => loadGlobalSetupFile(file, runner)));
|
|
12074
|
-
}
|
|
12075
|
-
async function loadGlobalSetupFile(file, runner) {
|
|
12076
|
-
const m = await runner.executeFile(file);
|
|
12077
|
-
for (const exp of ["default", "setup", "teardown"]) {
|
|
12078
|
-
if (m[exp] != null && typeof m[exp] !== "function")
|
|
12079
|
-
throw new Error(`invalid export in globalSetup file ${file}: ${exp} must be a function`);
|
|
12080
|
-
}
|
|
12081
|
-
if (m.default) {
|
|
12082
|
-
return {
|
|
12083
|
-
file,
|
|
12084
|
-
setup: m.default
|
|
12085
|
-
};
|
|
12086
|
-
} else if (m.setup || m.teardown) {
|
|
12087
|
-
return {
|
|
12088
|
-
file,
|
|
12089
|
-
setup: m.setup,
|
|
12090
|
-
teardown: m.teardown
|
|
12091
|
-
};
|
|
12092
|
-
} else {
|
|
12093
|
-
throw new Error(`invalid globalSetup file ${file}. Must export setup, teardown or have a default export`);
|
|
12094
|
-
}
|
|
12095
11317
|
}
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
|
|
12101
|
-
|
|
12102
|
-
|
|
12103
|
-
|
|
12104
|
-
|
|
12105
|
-
|
|
12106
|
-
|
|
12107
|
-
|
|
12108
|
-
|
|
12109
|
-
|
|
11318
|
+
/**
|
|
11319
|
+
* The path can have empty directories "//", unneeded parents "foo/..", or current directory
|
|
11320
|
+
* "foo/.". We need to normalize to a standard representation.
|
|
11321
|
+
*/
|
|
11322
|
+
function normalizePath(url, type) {
|
|
11323
|
+
const rel = type <= UrlType.RelativePath;
|
|
11324
|
+
const pieces = url.path.split('/');
|
|
11325
|
+
// We need to preserve the first piece always, so that we output a leading slash. The item at
|
|
11326
|
+
// pieces[0] is an empty string.
|
|
11327
|
+
let pointer = 1;
|
|
11328
|
+
// Positive is the number of real directories we've output, used for popping a parent directory.
|
|
11329
|
+
// Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
|
|
11330
|
+
let positive = 0;
|
|
11331
|
+
// We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
|
|
11332
|
+
// generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
|
|
11333
|
+
// real directory, we won't need to append, unless the other conditions happen again.
|
|
11334
|
+
let addTrailingSlash = false;
|
|
11335
|
+
for (let i = 1; i < pieces.length; i++) {
|
|
11336
|
+
const piece = pieces[i];
|
|
11337
|
+
// An empty directory, could be a trailing slash, or just a double "//" in the path.
|
|
11338
|
+
if (!piece) {
|
|
11339
|
+
addTrailingSlash = true;
|
|
12110
11340
|
continue;
|
|
12111
|
-
if (typeof teardown !== "function")
|
|
12112
|
-
throw new Error(`invalid return value in globalSetup file ${globalSetupFile.file}. Must return a function`);
|
|
12113
|
-
globalSetupFile.teardown = teardown;
|
|
12114
11341
|
}
|
|
12115
|
-
|
|
12116
|
-
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
|
|
12120
|
-
|
|
12121
|
-
|
|
12122
|
-
|
|
12123
|
-
|
|
12124
|
-
|
|
12125
|
-
|
|
12126
|
-
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
11342
|
+
// If we encounter a real directory, then we don't need to append anymore.
|
|
11343
|
+
addTrailingSlash = false;
|
|
11344
|
+
// A current directory, which we can always drop.
|
|
11345
|
+
if (piece === '.')
|
|
11346
|
+
continue;
|
|
11347
|
+
// A parent directory, we need to see if there are any real directories we can pop. Else, we
|
|
11348
|
+
// have an excess of parents, and we'll need to keep the "..".
|
|
11349
|
+
if (piece === '..') {
|
|
11350
|
+
if (positive) {
|
|
11351
|
+
addTrailingSlash = true;
|
|
11352
|
+
positive--;
|
|
11353
|
+
pointer--;
|
|
11354
|
+
}
|
|
11355
|
+
else if (rel) {
|
|
11356
|
+
// If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
|
|
11357
|
+
// URL, protocol relative URL, or an absolute path, we don't need to keep excess.
|
|
11358
|
+
pieces[pointer++] = piece;
|
|
11359
|
+
}
|
|
11360
|
+
continue;
|
|
12131
11361
|
}
|
|
12132
|
-
|
|
11362
|
+
// We've encountered a real directory. Move it to the next insertion pointer, which accounts for
|
|
11363
|
+
// any popped or dropped directories.
|
|
11364
|
+
pieces[pointer++] = piece;
|
|
11365
|
+
positive++;
|
|
12133
11366
|
}
|
|
12134
|
-
|
|
11367
|
+
let path = '';
|
|
11368
|
+
for (let i = 1; i < pointer; i++) {
|
|
11369
|
+
path += '/' + pieces[i];
|
|
11370
|
+
}
|
|
11371
|
+
if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
|
|
11372
|
+
path += '/';
|
|
11373
|
+
}
|
|
11374
|
+
url.path = path;
|
|
12135
11375
|
}
|
|
12136
|
-
|
|
12137
|
-
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
env[envKey] = replacement;
|
|
12168
|
-
delete viteConfig.define[key];
|
|
12169
|
-
}
|
|
12170
|
-
}
|
|
12171
|
-
const testConfig = viteConfig.test || {};
|
|
12172
|
-
const root = testConfig.root || viteConfig.root || options.root;
|
|
12173
|
-
let name = testConfig.name;
|
|
12174
|
-
if (!name) {
|
|
12175
|
-
if (typeof options.workspacePath === "string")
|
|
12176
|
-
name = dirname(options.workspacePath).split("/").pop();
|
|
12177
|
-
else
|
|
12178
|
-
name = options.workspacePath.toString();
|
|
12179
|
-
}
|
|
12180
|
-
const config = {
|
|
12181
|
-
root,
|
|
12182
|
-
resolve: {
|
|
12183
|
-
// by default Vite resolves `module` field, which not always a native ESM module
|
|
12184
|
-
// setting this option can bypass that and fallback to cjs version
|
|
12185
|
-
mainFields: [],
|
|
12186
|
-
alias: testConfig.alias,
|
|
12187
|
-
conditions: ["node"],
|
|
12188
|
-
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
|
|
12189
|
-
// @ts-ignore we support Vite ^3.0, but browserField is available in Vite ^3.2
|
|
12190
|
-
browserField: false
|
|
12191
|
-
},
|
|
12192
|
-
esbuild: {
|
|
12193
|
-
sourcemap: "external",
|
|
12194
|
-
// Enables using ignore hint for coverage providers with @preserve keyword
|
|
12195
|
-
legalComments: "inline"
|
|
12196
|
-
},
|
|
12197
|
-
server: {
|
|
12198
|
-
// disable watch mode in workspaces,
|
|
12199
|
-
// because it is handled by the top-level watcher
|
|
12200
|
-
watch: {
|
|
12201
|
-
ignored: ["**/*"],
|
|
12202
|
-
depth: 0,
|
|
12203
|
-
persistent: false
|
|
12204
|
-
},
|
|
12205
|
-
open: false,
|
|
12206
|
-
hmr: false,
|
|
12207
|
-
preTransformRequests: false
|
|
12208
|
-
},
|
|
12209
|
-
test: {
|
|
12210
|
-
env,
|
|
12211
|
-
name
|
|
12212
|
-
}
|
|
12213
|
-
};
|
|
12214
|
-
const classNameStrategy = typeof testConfig.css !== "boolean" && ((_b = (_a = testConfig.css) == null ? void 0 : _a.modules) == null ? void 0 : _b.classNameStrategy) || "stable";
|
|
12215
|
-
if (classNameStrategy !== "scoped") {
|
|
12216
|
-
config.css ?? (config.css = {});
|
|
12217
|
-
(_c = config.css).modules ?? (_c.modules = {});
|
|
12218
|
-
if (config.css.modules) {
|
|
12219
|
-
config.css.modules.generateScopedName = (name2, filename) => {
|
|
12220
|
-
const root2 = project.config.root;
|
|
12221
|
-
return generateScopedClassName(classNameStrategy, name2, relative(root2, filename));
|
|
12222
|
-
};
|
|
12223
|
-
}
|
|
11376
|
+
/**
|
|
11377
|
+
* Attempts to resolve `input` URL/path relative to `base`.
|
|
11378
|
+
*/
|
|
11379
|
+
function resolve$1(input, base) {
|
|
11380
|
+
if (!input && !base)
|
|
11381
|
+
return '';
|
|
11382
|
+
const url = parseUrl(input);
|
|
11383
|
+
let inputType = url.type;
|
|
11384
|
+
if (base && inputType !== UrlType.Absolute) {
|
|
11385
|
+
const baseUrl = parseUrl(base);
|
|
11386
|
+
const baseType = baseUrl.type;
|
|
11387
|
+
switch (inputType) {
|
|
11388
|
+
case UrlType.Empty:
|
|
11389
|
+
url.hash = baseUrl.hash;
|
|
11390
|
+
// fall through
|
|
11391
|
+
case UrlType.Hash:
|
|
11392
|
+
url.query = baseUrl.query;
|
|
11393
|
+
// fall through
|
|
11394
|
+
case UrlType.Query:
|
|
11395
|
+
case UrlType.RelativePath:
|
|
11396
|
+
mergePaths(url, baseUrl);
|
|
11397
|
+
// fall through
|
|
11398
|
+
case UrlType.AbsolutePath:
|
|
11399
|
+
// The host, user, and port are joined, you can't copy one without the others.
|
|
11400
|
+
url.user = baseUrl.user;
|
|
11401
|
+
url.host = baseUrl.host;
|
|
11402
|
+
url.port = baseUrl.port;
|
|
11403
|
+
// fall through
|
|
11404
|
+
case UrlType.SchemeRelative:
|
|
11405
|
+
// The input doesn't have a schema at least, so we need to copy at least that over.
|
|
11406
|
+
url.scheme = baseUrl.scheme;
|
|
12224
11407
|
}
|
|
12225
|
-
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12230
|
-
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12234
|
-
|
|
12235
|
-
|
|
12236
|
-
|
|
12237
|
-
|
|
11408
|
+
if (baseType > inputType)
|
|
11409
|
+
inputType = baseType;
|
|
11410
|
+
}
|
|
11411
|
+
normalizePath(url, inputType);
|
|
11412
|
+
const queryHash = url.query + url.hash;
|
|
11413
|
+
switch (inputType) {
|
|
11414
|
+
// This is impossible, because of the empty checks at the start of the function.
|
|
11415
|
+
// case UrlType.Empty:
|
|
11416
|
+
case UrlType.Hash:
|
|
11417
|
+
case UrlType.Query:
|
|
11418
|
+
return queryHash;
|
|
11419
|
+
case UrlType.RelativePath: {
|
|
11420
|
+
// The first char is always a "/", and we need it to be relative.
|
|
11421
|
+
const path = url.path.slice(1);
|
|
11422
|
+
if (!path)
|
|
11423
|
+
return queryHash || '.';
|
|
11424
|
+
if (isRelative(base || input) && !isRelative(path)) {
|
|
11425
|
+
// If base started with a leading ".", or there is no base and input started with a ".",
|
|
11426
|
+
// then we need to ensure that the relative path starts with a ".". We don't know if
|
|
11427
|
+
// relative starts with a "..", though, so check before prepending.
|
|
11428
|
+
return './' + path + queryHash;
|
|
11429
|
+
}
|
|
11430
|
+
return path + queryHash;
|
|
12238
11431
|
}
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
CoverageTransform(project.ctx),
|
|
12245
|
-
GlobalSetupPlugin(project, project.ctx.logger)
|
|
12246
|
-
];
|
|
11432
|
+
case UrlType.AbsolutePath:
|
|
11433
|
+
return url.path + queryHash;
|
|
11434
|
+
default:
|
|
11435
|
+
return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
|
|
11436
|
+
}
|
|
12247
11437
|
}
|
|
12248
11438
|
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
intToChar[i] = c;
|
|
12257
|
-
charToInt[c] = i;
|
|
11439
|
+
function resolve(input, base) {
|
|
11440
|
+
// The base is always treated as a directory, if it's not empty.
|
|
11441
|
+
// https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327
|
|
11442
|
+
// https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401
|
|
11443
|
+
if (base && !base.endsWith('/'))
|
|
11444
|
+
base += '/';
|
|
11445
|
+
return resolve$1(input, base);
|
|
12258
11446
|
}
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12266
|
-
|
|
12267
|
-
|
|
12268
|
-
|
|
12269
|
-
|
|
12270
|
-
|
|
12271
|
-
|
|
12272
|
-
|
|
12273
|
-
|
|
12274
|
-
|
|
12275
|
-
|
|
12276
|
-
|
|
12277
|
-
|
|
12278
|
-
|
|
12279
|
-
|
|
12280
|
-
|
|
12281
|
-
|
|
12282
|
-
do
|
|
12283
|
-
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
|
|
12293
|
-
|
|
12294
|
-
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
|
|
12301
|
-
seg = [col, state[1], state[2], state[3], state[4]];
|
|
12302
|
-
}
|
|
12303
|
-
else {
|
|
12304
|
-
seg = [col, state[1], state[2], state[3]];
|
|
12305
|
-
}
|
|
12306
|
-
}
|
|
12307
|
-
else {
|
|
12308
|
-
seg = [col];
|
|
12309
|
-
}
|
|
12310
|
-
line.push(seg);
|
|
11447
|
+
|
|
11448
|
+
/**
|
|
11449
|
+
* Removes everything after the last "/", but leaves the slash.
|
|
11450
|
+
*/
|
|
11451
|
+
function stripFilename(path) {
|
|
11452
|
+
if (!path)
|
|
11453
|
+
return '';
|
|
11454
|
+
const index = path.lastIndexOf('/');
|
|
11455
|
+
return path.slice(0, index + 1);
|
|
11456
|
+
}
|
|
11457
|
+
|
|
11458
|
+
const COLUMN = 0;
|
|
11459
|
+
const SOURCES_INDEX = 1;
|
|
11460
|
+
const SOURCE_LINE = 2;
|
|
11461
|
+
const SOURCE_COLUMN = 3;
|
|
11462
|
+
const REV_GENERATED_LINE = 1;
|
|
11463
|
+
const REV_GENERATED_COLUMN = 2;
|
|
11464
|
+
|
|
11465
|
+
function maybeSort(mappings, owned) {
|
|
11466
|
+
const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
|
|
11467
|
+
if (unsortedIndex === mappings.length)
|
|
11468
|
+
return mappings;
|
|
11469
|
+
// If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If
|
|
11470
|
+
// not, we do not want to modify the consumer's input array.
|
|
11471
|
+
if (!owned)
|
|
11472
|
+
mappings = mappings.slice();
|
|
11473
|
+
for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) {
|
|
11474
|
+
mappings[i] = sortSegments(mappings[i], owned);
|
|
11475
|
+
}
|
|
11476
|
+
return mappings;
|
|
11477
|
+
}
|
|
11478
|
+
function nextUnsortedSegmentLine(mappings, start) {
|
|
11479
|
+
for (let i = start; i < mappings.length; i++) {
|
|
11480
|
+
if (!isSorted(mappings[i]))
|
|
11481
|
+
return i;
|
|
11482
|
+
}
|
|
11483
|
+
return mappings.length;
|
|
11484
|
+
}
|
|
11485
|
+
function isSorted(line) {
|
|
11486
|
+
for (let j = 1; j < line.length; j++) {
|
|
11487
|
+
if (line[j][COLUMN] < line[j - 1][COLUMN]) {
|
|
11488
|
+
return false;
|
|
12311
11489
|
}
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
decoded.push(line);
|
|
12315
|
-
index = semi + 1;
|
|
12316
|
-
} while (index <= mappings.length);
|
|
12317
|
-
return decoded;
|
|
11490
|
+
}
|
|
11491
|
+
return true;
|
|
12318
11492
|
}
|
|
12319
|
-
function
|
|
12320
|
-
|
|
12321
|
-
|
|
11493
|
+
function sortSegments(line, owned) {
|
|
11494
|
+
if (!owned)
|
|
11495
|
+
line = line.slice();
|
|
11496
|
+
return line.sort(sortComparator);
|
|
12322
11497
|
}
|
|
12323
|
-
function
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
|
|
12332
|
-
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
11498
|
+
function sortComparator(a, b) {
|
|
11499
|
+
return a[COLUMN] - b[COLUMN];
|
|
11500
|
+
}
|
|
11501
|
+
|
|
11502
|
+
let found = false;
|
|
11503
|
+
/**
|
|
11504
|
+
* A binary search implementation that returns the index if a match is found.
|
|
11505
|
+
* If no match is found, then the left-index (the index associated with the item that comes just
|
|
11506
|
+
* before the desired index) is returned. To maintain proper sort order, a splice would happen at
|
|
11507
|
+
* the next index:
|
|
11508
|
+
*
|
|
11509
|
+
* ```js
|
|
11510
|
+
* const array = [1, 3];
|
|
11511
|
+
* const needle = 2;
|
|
11512
|
+
* const index = binarySearch(array, needle, (item, needle) => item - needle);
|
|
11513
|
+
*
|
|
11514
|
+
* assert.equal(index, 0);
|
|
11515
|
+
* array.splice(index + 1, 0, needle);
|
|
11516
|
+
* assert.deepEqual(array, [1, 2, 3]);
|
|
11517
|
+
* ```
|
|
11518
|
+
*/
|
|
11519
|
+
function binarySearch(haystack, needle, low, high) {
|
|
11520
|
+
while (low <= high) {
|
|
11521
|
+
const mid = low + ((high - low) >> 1);
|
|
11522
|
+
const cmp = haystack[mid][COLUMN] - needle;
|
|
11523
|
+
if (cmp === 0) {
|
|
11524
|
+
found = true;
|
|
11525
|
+
return mid;
|
|
11526
|
+
}
|
|
11527
|
+
if (cmp < 0) {
|
|
11528
|
+
low = mid + 1;
|
|
11529
|
+
}
|
|
11530
|
+
else {
|
|
11531
|
+
high = mid - 1;
|
|
11532
|
+
}
|
|
12337
11533
|
}
|
|
12338
|
-
|
|
12339
|
-
return
|
|
11534
|
+
found = false;
|
|
11535
|
+
return low - 1;
|
|
12340
11536
|
}
|
|
12341
|
-
function
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
11537
|
+
function upperBound(haystack, needle, index) {
|
|
11538
|
+
for (let i = index + 1; i < haystack.length; index = i++) {
|
|
11539
|
+
if (haystack[i][COLUMN] !== needle)
|
|
11540
|
+
break;
|
|
11541
|
+
}
|
|
11542
|
+
return index;
|
|
12345
11543
|
}
|
|
12346
|
-
function
|
|
12347
|
-
|
|
11544
|
+
function lowerBound(haystack, needle, index) {
|
|
11545
|
+
for (let i = index - 1; i >= 0; index = i--) {
|
|
11546
|
+
if (haystack[i][COLUMN] !== needle)
|
|
11547
|
+
break;
|
|
11548
|
+
}
|
|
11549
|
+
return index;
|
|
12348
11550
|
}
|
|
12349
|
-
function
|
|
12350
|
-
return
|
|
11551
|
+
function memoizedState() {
|
|
11552
|
+
return {
|
|
11553
|
+
lastKey: -1,
|
|
11554
|
+
lastNeedle: -1,
|
|
11555
|
+
lastIndex: -1,
|
|
11556
|
+
};
|
|
12351
11557
|
}
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
const
|
|
12358
|
-
let
|
|
12359
|
-
let
|
|
11558
|
+
/**
|
|
11559
|
+
* This overly complicated beast is just to record the last tested line/column and the resulting
|
|
11560
|
+
* index, allowing us to skip a few tests if mappings are monotonically increasing.
|
|
11561
|
+
*/
|
|
11562
|
+
function memoizedBinarySearch(haystack, needle, state, key) {
|
|
11563
|
+
const { lastKey, lastNeedle, lastIndex } = state;
|
|
11564
|
+
let low = 0;
|
|
11565
|
+
let high = haystack.length - 1;
|
|
11566
|
+
if (key === lastKey) {
|
|
11567
|
+
if (needle === lastNeedle) {
|
|
11568
|
+
found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
|
|
11569
|
+
return lastIndex;
|
|
11570
|
+
}
|
|
11571
|
+
if (needle >= lastNeedle) {
|
|
11572
|
+
// lastIndex may be -1 if the previous needle was not found.
|
|
11573
|
+
low = lastIndex === -1 ? 0 : lastIndex;
|
|
11574
|
+
}
|
|
11575
|
+
else {
|
|
11576
|
+
high = lastIndex;
|
|
11577
|
+
}
|
|
11578
|
+
}
|
|
11579
|
+
state.lastKey = key;
|
|
11580
|
+
state.lastNeedle = needle;
|
|
11581
|
+
return (state.lastIndex = binarySearch(haystack, needle, low, high));
|
|
11582
|
+
}
|
|
11583
|
+
|
|
11584
|
+
// Rebuilds the original source files, with mappings that are ordered by source line/column instead
|
|
11585
|
+
// of generated line/column.
|
|
11586
|
+
function buildBySources(decoded, memos) {
|
|
11587
|
+
const sources = memos.map(buildNullArray);
|
|
12360
11588
|
for (let i = 0; i < decoded.length; i++) {
|
|
12361
11589
|
const line = decoded[i];
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
11590
|
+
for (let j = 0; j < line.length; j++) {
|
|
11591
|
+
const seg = line[j];
|
|
11592
|
+
if (seg.length === 1)
|
|
11593
|
+
continue;
|
|
11594
|
+
const sourceIndex = seg[SOURCES_INDEX];
|
|
11595
|
+
const sourceLine = seg[SOURCE_LINE];
|
|
11596
|
+
const sourceColumn = seg[SOURCE_COLUMN];
|
|
11597
|
+
const originalSource = sources[sourceIndex];
|
|
11598
|
+
const originalLine = (originalSource[sourceLine] || (originalSource[sourceLine] = []));
|
|
11599
|
+
const memo = memos[sourceIndex];
|
|
11600
|
+
// The binary search either found a match, or it found the left-index just before where the
|
|
11601
|
+
// segment should go. Either way, we want to insert after that. And there may be multiple
|
|
11602
|
+
// generated segments associated with an original location, so there may need to move several
|
|
11603
|
+
// indexes before we find where we need to insert.
|
|
11604
|
+
const index = upperBound(originalLine, sourceColumn, memoizedBinarySearch(originalLine, sourceColumn, memo, sourceLine));
|
|
11605
|
+
insert(originalLine, (memo.lastIndex = index + 1), [sourceColumn, i, seg[COLUMN]]);
|
|
11606
|
+
}
|
|
11607
|
+
}
|
|
11608
|
+
return sources;
|
|
11609
|
+
}
|
|
11610
|
+
function insert(array, index, value) {
|
|
11611
|
+
for (let i = array.length; i > index; i--) {
|
|
11612
|
+
array[i] = array[i - 1];
|
|
11613
|
+
}
|
|
11614
|
+
array[index] = value;
|
|
11615
|
+
}
|
|
11616
|
+
// Null arrays allow us to use ordered index keys without actually allocating contiguous memory like
|
|
11617
|
+
// a real array. We use a null-prototype object to avoid prototype pollution and deoptimizations.
|
|
11618
|
+
// Numeric properties on objects are magically sorted in ascending order by the engine regardless of
|
|
11619
|
+
// the insertion order. So, by setting any numeric keys, even out of order, we'll get ascending
|
|
11620
|
+
// order when iterating with for-in.
|
|
11621
|
+
function buildNullArray() {
|
|
11622
|
+
return { __proto__: null };
|
|
11623
|
+
}
|
|
11624
|
+
|
|
11625
|
+
const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)';
|
|
11626
|
+
const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)';
|
|
11627
|
+
const LEAST_UPPER_BOUND = -1;
|
|
11628
|
+
const GREATEST_LOWER_BOUND = 1;
|
|
11629
|
+
/**
|
|
11630
|
+
* Returns the decoded (array of lines of segments) form of the SourceMap's mappings field.
|
|
11631
|
+
*/
|
|
11632
|
+
let decodedMappings;
|
|
11633
|
+
/**
|
|
11634
|
+
* Finds the generated line/column position of the provided source/line/column source position.
|
|
11635
|
+
*/
|
|
11636
|
+
let generatedPositionFor;
|
|
11637
|
+
class TraceMap {
|
|
11638
|
+
constructor(map, mapUrl) {
|
|
11639
|
+
const isString = typeof map === 'string';
|
|
11640
|
+
if (!isString && map._decodedMemo)
|
|
11641
|
+
return map;
|
|
11642
|
+
const parsed = (isString ? JSON.parse(map) : map);
|
|
11643
|
+
const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
|
|
11644
|
+
this.version = version;
|
|
11645
|
+
this.file = file;
|
|
11646
|
+
this.names = names;
|
|
11647
|
+
this.sourceRoot = sourceRoot;
|
|
11648
|
+
this.sources = sources;
|
|
11649
|
+
this.sourcesContent = sourcesContent;
|
|
11650
|
+
const from = resolve(sourceRoot || '', stripFilename(mapUrl));
|
|
11651
|
+
this.resolvedSources = sources.map((s) => resolve(s || '', from));
|
|
11652
|
+
const { mappings } = parsed;
|
|
11653
|
+
if (typeof mappings === 'string') {
|
|
11654
|
+
this._encoded = mappings;
|
|
11655
|
+
this._decoded = undefined;
|
|
12368
11656
|
}
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
for (let j = 0; j < line.length; j++) {
|
|
12373
|
-
const segment = line[j];
|
|
12374
|
-
// We can push up to 5 ints, each int can take at most 7 chars, and we
|
|
12375
|
-
// may push a comma.
|
|
12376
|
-
if (pos > subLength) {
|
|
12377
|
-
out += td.decode(sub);
|
|
12378
|
-
buf.copyWithin(0, subLength, pos);
|
|
12379
|
-
pos -= subLength;
|
|
12380
|
-
}
|
|
12381
|
-
if (j > 0)
|
|
12382
|
-
buf[pos++] = comma;
|
|
12383
|
-
pos = encodeInteger(buf, pos, state, segment, 0); // genColumn
|
|
12384
|
-
if (segment.length === 1)
|
|
12385
|
-
continue;
|
|
12386
|
-
pos = encodeInteger(buf, pos, state, segment, 1); // sourcesIndex
|
|
12387
|
-
pos = encodeInteger(buf, pos, state, segment, 2); // sourceLine
|
|
12388
|
-
pos = encodeInteger(buf, pos, state, segment, 3); // sourceColumn
|
|
12389
|
-
if (segment.length === 4)
|
|
12390
|
-
continue;
|
|
12391
|
-
pos = encodeInteger(buf, pos, state, segment, 4); // namesIndex
|
|
11657
|
+
else {
|
|
11658
|
+
this._encoded = undefined;
|
|
11659
|
+
this._decoded = maybeSort(mappings, isString);
|
|
12392
11660
|
}
|
|
11661
|
+
this._decodedMemo = memoizedState();
|
|
11662
|
+
this._bySources = undefined;
|
|
11663
|
+
this._bySourceMemos = undefined;
|
|
12393
11664
|
}
|
|
12394
|
-
return out + td.decode(buf.subarray(0, pos));
|
|
12395
11665
|
}
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
11666
|
+
(() => {
|
|
11667
|
+
decodedMappings = (map) => {
|
|
11668
|
+
return (map._decoded || (map._decoded = decode(map._encoded)));
|
|
11669
|
+
};
|
|
11670
|
+
generatedPositionFor = (map, { source, line, column, bias }) => {
|
|
11671
|
+
return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false);
|
|
11672
|
+
};
|
|
11673
|
+
function generatedPosition(map, source, line, column, bias, all) {
|
|
11674
|
+
line--;
|
|
11675
|
+
if (line < 0)
|
|
11676
|
+
throw new Error(LINE_GTR_ZERO);
|
|
11677
|
+
if (column < 0)
|
|
11678
|
+
throw new Error(COL_GTR_EQ_ZERO);
|
|
11679
|
+
const { sources, resolvedSources } = map;
|
|
11680
|
+
let sourceIndex = sources.indexOf(source);
|
|
11681
|
+
if (sourceIndex === -1)
|
|
11682
|
+
sourceIndex = resolvedSources.indexOf(source);
|
|
11683
|
+
if (sourceIndex === -1)
|
|
11684
|
+
return all ? [] : GMapping(null, null);
|
|
11685
|
+
const generated = (map._bySources || (map._bySources = buildBySources(decodedMappings(map), (map._bySourceMemos = sources.map(memoizedState)))));
|
|
11686
|
+
const segments = generated[sourceIndex][line];
|
|
11687
|
+
if (segments == null)
|
|
11688
|
+
return all ? [] : GMapping(null, null);
|
|
11689
|
+
const memo = map._bySourceMemos[sourceIndex];
|
|
11690
|
+
if (all)
|
|
11691
|
+
return sliceGeneratedPositions(segments, memo, line, column, bias);
|
|
11692
|
+
const index = traceSegmentInternal(segments, memo, line, column, bias);
|
|
11693
|
+
if (index === -1)
|
|
11694
|
+
return GMapping(null, null);
|
|
11695
|
+
const segment = segments[index];
|
|
11696
|
+
return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]);
|
|
11697
|
+
}
|
|
11698
|
+
})();
|
|
11699
|
+
function GMapping(line, column) {
|
|
11700
|
+
return { line, column };
|
|
12409
11701
|
}
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
|
|
12413
|
-
|
|
12414
|
-
|
|
12415
|
-
|
|
12416
|
-
|
|
12417
|
-
|
|
12418
|
-
|
|
12419
|
-
|
|
12420
|
-
* 6. Query, including "?", optional.
|
|
12421
|
-
* 7. Hash, including "#", optional.
|
|
12422
|
-
*/
|
|
12423
|
-
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
|
|
12424
|
-
/**
|
|
12425
|
-
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
|
|
12426
|
-
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
|
|
12427
|
-
*
|
|
12428
|
-
* 1. Host, optional.
|
|
12429
|
-
* 2. Path, which may include "/", guaranteed.
|
|
12430
|
-
* 3. Query, including "?", optional.
|
|
12431
|
-
* 4. Hash, including "#", optional.
|
|
12432
|
-
*/
|
|
12433
|
-
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
|
|
12434
|
-
var UrlType;
|
|
12435
|
-
(function (UrlType) {
|
|
12436
|
-
UrlType[UrlType["Empty"] = 1] = "Empty";
|
|
12437
|
-
UrlType[UrlType["Hash"] = 2] = "Hash";
|
|
12438
|
-
UrlType[UrlType["Query"] = 3] = "Query";
|
|
12439
|
-
UrlType[UrlType["RelativePath"] = 4] = "RelativePath";
|
|
12440
|
-
UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath";
|
|
12441
|
-
UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative";
|
|
12442
|
-
UrlType[UrlType["Absolute"] = 7] = "Absolute";
|
|
12443
|
-
})(UrlType || (UrlType = {}));
|
|
12444
|
-
function isAbsoluteUrl(input) {
|
|
12445
|
-
return schemeRegex.test(input);
|
|
11702
|
+
function traceSegmentInternal(segments, memo, line, column, bias) {
|
|
11703
|
+
let index = memoizedBinarySearch(segments, column, memo, line);
|
|
11704
|
+
if (found) {
|
|
11705
|
+
index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index);
|
|
11706
|
+
}
|
|
11707
|
+
else if (bias === LEAST_UPPER_BOUND)
|
|
11708
|
+
index++;
|
|
11709
|
+
if (index === -1 || index === segments.length)
|
|
11710
|
+
return -1;
|
|
11711
|
+
return index;
|
|
12446
11712
|
}
|
|
12447
|
-
function
|
|
12448
|
-
|
|
11713
|
+
function sliceGeneratedPositions(segments, memo, line, column, bias) {
|
|
11714
|
+
let min = traceSegmentInternal(segments, memo, line, column, GREATEST_LOWER_BOUND);
|
|
11715
|
+
// We ignored the bias when tracing the segment so that we're guarnateed to find the first (in
|
|
11716
|
+
// insertion order) segment that matched. Even if we did respect the bias when tracing, we would
|
|
11717
|
+
// still need to call `lowerBound()` to find the first segment, which is slower than just looking
|
|
11718
|
+
// for the GREATEST_LOWER_BOUND to begin with. The only difference that matters for us is when the
|
|
11719
|
+
// binary search didn't match, in which case GREATEST_LOWER_BOUND just needs to increment to
|
|
11720
|
+
// match LEAST_UPPER_BOUND.
|
|
11721
|
+
if (!found && bias === LEAST_UPPER_BOUND)
|
|
11722
|
+
min++;
|
|
11723
|
+
if (min === -1 || min === segments.length)
|
|
11724
|
+
return [];
|
|
11725
|
+
// We may have found the segment that started at an earlier column. If this is the case, then we
|
|
11726
|
+
// need to slice all generated segments that match _that_ column, because all such segments span
|
|
11727
|
+
// to our desired column.
|
|
11728
|
+
const matchedColumn = found ? column : segments[min][COLUMN];
|
|
11729
|
+
// The binary search is not guaranteed to find the lower bound when a match wasn't found.
|
|
11730
|
+
if (!found)
|
|
11731
|
+
min = lowerBound(segments, matchedColumn, min);
|
|
11732
|
+
const max = upperBound(segments, matchedColumn, min);
|
|
11733
|
+
const result = [];
|
|
11734
|
+
for (; min <= max; min++) {
|
|
11735
|
+
const segment = segments[min];
|
|
11736
|
+
result.push(GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]));
|
|
11737
|
+
}
|
|
11738
|
+
return result;
|
|
12449
11739
|
}
|
|
12450
|
-
|
|
12451
|
-
|
|
11740
|
+
|
|
11741
|
+
function L(n){return /^\\\\\?\\/.test(n)?n:n.replace(/\\/g,"/")}function S(n,s){for(;;){const t=p.posix.join(n,s);if(require$$0$3.existsSync(t))return t;const e=p.dirname(n);if(e===n)return;n=e;}}const W=/^\.{1,2}(\/.*)?$/,M=n=>L(W.test(n)?n:`./${n}`);function un(n,s=!1){const t=n.length;let e=0,i="",l=0,c=16,a=0,g=0,v=0,k=0,r=0;function F(o,f){let u=0,j=0;for(;u<o||!f;){let T=n.charCodeAt(e);if(T>=48&&T<=57)j=j*16+T-48;else if(T>=65&&T<=70)j=j*16+T-65+10;else if(T>=97&&T<=102)j=j*16+T-97+10;else break;e++,u++;}return u<o&&(j=-1),j}function U(o){e=o,i="",l=0,c=16,r=0;}function A(){let o=e;if(n.charCodeAt(e)===48)e++;else for(e++;e<n.length&&_(n.charCodeAt(e));)e++;if(e<n.length&&n.charCodeAt(e)===46)if(e++,e<n.length&&_(n.charCodeAt(e)))for(e++;e<n.length&&_(n.charCodeAt(e));)e++;else return r=3,n.substring(o,e);let f=e;if(e<n.length&&(n.charCodeAt(e)===69||n.charCodeAt(e)===101))if(e++,(e<n.length&&n.charCodeAt(e)===43||n.charCodeAt(e)===45)&&e++,e<n.length&&_(n.charCodeAt(e))){for(e++;e<n.length&&_(n.charCodeAt(e));)e++;f=e;}else r=3;return n.substring(o,f)}function b(){let o="",f=e;for(;;){if(e>=t){o+=n.substring(f,e),r=2;break}const u=n.charCodeAt(e);if(u===34){o+=n.substring(f,e),e++;break}if(u===92){if(o+=n.substring(f,e),e++,e>=t){r=2;break}switch(n.charCodeAt(e++)){case 34:o+='"';break;case 92:o+="\\";break;case 47:o+="/";break;case 98:o+="\b";break;case 102:o+="\f";break;case 110:o+=`
|
|
11742
|
+
`;break;case 114:o+="\r";break;case 116:o+=" ";break;case 117:const T=F(4,!0);T>=0?o+=String.fromCharCode(T):r=4;break;default:r=5;}f=e;continue}if(u>=0&&u<=31)if(N(u)){o+=n.substring(f,e),r=2;break}else r=6;e++;}return o}function O(){if(i="",r=0,l=e,g=a,k=v,e>=t)return l=t,c=17;let o=n.charCodeAt(e);if(R(o)){do e++,i+=String.fromCharCode(o),o=n.charCodeAt(e);while(R(o));return c=15}if(N(o))return e++,i+=String.fromCharCode(o),o===13&&n.charCodeAt(e)===10&&(e++,i+=`
|
|
11743
|
+
`),a++,v=e,c=14;switch(o){case 123:return e++,c=1;case 125:return e++,c=2;case 91:return e++,c=3;case 93:return e++,c=4;case 58:return e++,c=6;case 44:return e++,c=5;case 34:return e++,i=b(),c=10;case 47:const f=e-1;if(n.charCodeAt(e+1)===47){for(e+=2;e<t&&!N(n.charCodeAt(e));)e++;return i=n.substring(f,e),c=12}if(n.charCodeAt(e+1)===42){e+=2;const u=t-1;let j=!1;for(;e<u;){const T=n.charCodeAt(e);if(T===42&&n.charCodeAt(e+1)===47){e+=2,j=!0;break}e++,N(T)&&(T===13&&n.charCodeAt(e)===10&&e++,a++,v=e);}return j||(e++,r=1),i=n.substring(f,e),c=13}return i+=String.fromCharCode(o),e++,c=16;case 45:if(i+=String.fromCharCode(o),e++,e===t||!_(n.charCodeAt(e)))return c=16;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return i+=A(),c=11;default:for(;e<t&&E(o);)e++,o=n.charCodeAt(e);if(l!==e){switch(i=n.substring(l,e),i){case"true":return c=8;case"false":return c=9;case"null":return c=7}return c=16}return i+=String.fromCharCode(o),e++,c=16}}function E(o){if(R(o)||N(o))return !1;switch(o){case 125:case 93:case 123:case 91:case 34:case 58:case 44:case 47:return !1}return !0}function $(){let o;do o=O();while(o>=12&&o<=15);return o}return {setPosition:U,getPosition:()=>e,scan:s?$:O,getToken:()=>c,getTokenValue:()=>i,getTokenOffset:()=>l,getTokenLength:()=>e-l,getTokenStartLine:()=>g,getTokenStartCharacter:()=>l-k,getTokenError:()=>r}}function R(n){return n===32||n===9}function N(n){return n===10||n===13}function _(n){return n>=48&&n<=57}var P;(function(n){n[n.lineFeed=10]="lineFeed",n[n.carriageReturn=13]="carriageReturn",n[n.space=32]="space",n[n._0=48]="_0",n[n._1=49]="_1",n[n._2=50]="_2",n[n._3=51]="_3",n[n._4=52]="_4",n[n._5=53]="_5",n[n._6=54]="_6",n[n._7=55]="_7",n[n._8=56]="_8",n[n._9=57]="_9",n[n.a=97]="a",n[n.b=98]="b",n[n.c=99]="c",n[n.d=100]="d",n[n.e=101]="e",n[n.f=102]="f",n[n.g=103]="g",n[n.h=104]="h",n[n.i=105]="i",n[n.j=106]="j",n[n.k=107]="k",n[n.l=108]="l",n[n.m=109]="m",n[n.n=110]="n",n[n.o=111]="o",n[n.p=112]="p",n[n.q=113]="q",n[n.r=114]="r",n[n.s=115]="s",n[n.t=116]="t",n[n.u=117]="u",n[n.v=118]="v",n[n.w=119]="w",n[n.x=120]="x",n[n.y=121]="y",n[n.z=122]="z",n[n.A=65]="A",n[n.B=66]="B",n[n.C=67]="C",n[n.D=68]="D",n[n.E=69]="E",n[n.F=70]="F",n[n.G=71]="G",n[n.H=72]="H",n[n.I=73]="I",n[n.J=74]="J",n[n.K=75]="K",n[n.L=76]="L",n[n.M=77]="M",n[n.N=78]="N",n[n.O=79]="O",n[n.P=80]="P",n[n.Q=81]="Q",n[n.R=82]="R",n[n.S=83]="S",n[n.T=84]="T",n[n.U=85]="U",n[n.V=86]="V",n[n.W=87]="W",n[n.X=88]="X",n[n.Y=89]="Y",n[n.Z=90]="Z",n[n.asterisk=42]="asterisk",n[n.backslash=92]="backslash",n[n.closeBrace=125]="closeBrace",n[n.closeBracket=93]="closeBracket",n[n.colon=58]="colon",n[n.comma=44]="comma",n[n.dot=46]="dot",n[n.doubleQuote=34]="doubleQuote",n[n.minus=45]="minus",n[n.openBrace=123]="openBrace",n[n.openBracket=91]="openBracket",n[n.plus=43]="plus",n[n.slash=47]="slash",n[n.formFeed=12]="formFeed",n[n.tab=9]="tab";})(P||(P={}));var h;(function(n){n.DEFAULT={allowTrailingComma:!1};})(h||(h={}));function fn(n,s=[],t=h.DEFAULT){let e=null,i=[];const l=[];function c(g){Array.isArray(i)?i.push(g):e!==null&&(i[e]=g);}return rn(n,{onObjectBegin:()=>{const g={};c(g),l.push(i),i=g,e=null;},onObjectProperty:g=>{e=g;},onObjectEnd:()=>{i=l.pop();},onArrayBegin:()=>{const g=[];c(g),l.push(i),i=g,e=null;},onArrayEnd:()=>{i=l.pop();},onLiteralValue:c,onError:(g,v,k)=>{s.push({error:g,offset:v,length:k});}},t),i[0]}function rn(n,s,t=h.DEFAULT){const e=un(n,!1),i=[];function l(m){return m?()=>m(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function c(m){return m?()=>m(e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>i.slice()):()=>!0}function a(m){return m?w=>m(w,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter()):()=>!0}function g(m){return m?w=>m(w,e.getTokenOffset(),e.getTokenLength(),e.getTokenStartLine(),e.getTokenStartCharacter(),()=>i.slice()):()=>!0}const v=c(s.onObjectBegin),k=g(s.onObjectProperty),r=l(s.onObjectEnd),F=c(s.onArrayBegin),U=l(s.onArrayEnd),A=g(s.onLiteralValue),b=a(s.onSeparator),O=l(s.onComment),E=a(s.onError),$=t&&t.disallowComments,o=t&&t.allowTrailingComma;function f(){for(;;){const m=e.scan();switch(e.getTokenError()){case 4:u(14);break;case 5:u(15);break;case 3:u(13);break;case 1:$||u(11);break;case 2:u(12);break;case 6:u(16);break}switch(m){case 12:case 13:$?u(10):O();break;case 16:u(1);break;case 15:case 14:break;default:return m}}}function u(m,w=[],H=[]){if(E(m),w.length+H.length>0){let I=e.getToken();for(;I!==17;){if(w.indexOf(I)!==-1){f();break}else if(H.indexOf(I)!==-1)break;I=f();}}}function j(m){const w=e.getTokenValue();return m?A(w):(k(w),i.push(w)),f(),!0}function T(){switch(e.getToken()){case 11:const m=e.getTokenValue();let w=Number(m);isNaN(w)&&(u(2),w=0),A(w);break;case 7:A(null);break;case 8:A(!0);break;case 9:A(!1);break;default:return !1}return f(),!0}function sn(){return e.getToken()!==10?(u(3,[],[2,5]),!1):(j(!1),e.getToken()===6?(b(":"),f(),V()||u(4,[],[2,5])):u(5,[],[2,5]),i.pop(),!0)}function on(){v(),f();let m=!1;for(;e.getToken()!==2&&e.getToken()!==17;){if(e.getToken()===5){if(m||u(4,[],[]),b(","),f(),e.getToken()===2&&o)break}else m&&u(6,[],[]);sn()||u(4,[],[2,5]),m=!0;}return r(),e.getToken()!==2?u(7,[2],[]):f(),!0}function ln(){F(),f();let m=!0,w=!1;for(;e.getToken()!==4&&e.getToken()!==17;){if(e.getToken()===5){if(w||u(4,[],[]),b(","),f(),e.getToken()===4&&o)break}else w&&u(6,[],[]);m?(i.push(0),m=!1):i[i.length-1]++,V()||u(4,[],[4,5]),w=!0;}return U(),m||i.pop(),e.getToken()!==4?u(8,[4],[]):f(),!0}function V(){switch(e.getToken()){case 3:return ln();case 1:return on();case 10:return j(!0);default:return T()}}return f(),e.getToken()===17?t.allowEmptyContent?!0:(u(4,[],[]),!1):V()?(e.getToken()!==17&&u(9,[],[]),!0):(u(4,[],[]),!1)}var X;(function(n){n[n.None=0]="None",n[n.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=2]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",n[n.InvalidUnicode=4]="InvalidUnicode",n[n.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",n[n.InvalidCharacter=6]="InvalidCharacter";})(X||(X={}));var Y;(function(n){n[n.OpenBraceToken=1]="OpenBraceToken",n[n.CloseBraceToken=2]="CloseBraceToken",n[n.OpenBracketToken=3]="OpenBracketToken",n[n.CloseBracketToken=4]="CloseBracketToken",n[n.CommaToken=5]="CommaToken",n[n.ColonToken=6]="ColonToken",n[n.NullKeyword=7]="NullKeyword",n[n.TrueKeyword=8]="TrueKeyword",n[n.FalseKeyword=9]="FalseKeyword",n[n.StringLiteral=10]="StringLiteral",n[n.NumericLiteral=11]="NumericLiteral",n[n.LineCommentTrivia=12]="LineCommentTrivia",n[n.BlockCommentTrivia=13]="BlockCommentTrivia",n[n.LineBreakTrivia=14]="LineBreakTrivia",n[n.Trivia=15]="Trivia",n[n.Unknown=16]="Unknown",n[n.EOF=17]="EOF";})(Y||(Y={}));const pn=fn;var Z;(function(n){n[n.InvalidSymbol=1]="InvalidSymbol",n[n.InvalidNumberFormat=2]="InvalidNumberFormat",n[n.PropertyNameExpected=3]="PropertyNameExpected",n[n.ValueExpected=4]="ValueExpected",n[n.ColonExpected=5]="ColonExpected",n[n.CommaExpected=6]="CommaExpected",n[n.CloseBraceExpected=7]="CloseBraceExpected",n[n.CloseBracketExpected=8]="CloseBracketExpected",n[n.EndOfFileExpected=9]="EndOfFileExpected",n[n.InvalidCommentToken=10]="InvalidCommentToken",n[n.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",n[n.UnexpectedEndOfString=12]="UnexpectedEndOfString",n[n.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",n[n.InvalidUnicode=14]="InvalidUnicode",n[n.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",n[n.InvalidCharacter=16]="InvalidCharacter";})(Z||(Z={}));const q=n=>pn(require$$0$3.readFileSync(n,"utf8")),{existsSync:D}=require$$0$3,gn=()=>{const{findPnpApi:n}=cn;return n&&n(process.cwd())};function d(n){const s=q(n);return p.join(n,"..",s&&"tsconfig"in s?s.tsconfig:"tsconfig.json")}function mn(n,s){let t=n;const e=n[0]===".";if(e||p.isAbsolute(n)){if(e&&(t===".."&&(t+="/tsconfig.json"),t=p.resolve(s,t)),D(t)&&require$$0$3.statSync(t).isFile()||!t.endsWith(".json")&&(t+=".json",D(t)))return t;throw new Error(`File '${n}' not found.`)}const i=gn();if(i){const{resolveRequest:c}=i,[a,g]=n.split("/"),v=a.startsWith("@")?`${a}/${g}`:a;try{if(v===n){const k=c(p.join(v,"package.json"),s);if(k){const r=d(k);if(D(r))return r}}else {let k;try{k=c(n,s,{extensions:[".json"]});}catch{k=c(p.join(n,"tsconfig.json"),s);}if(k)return k}}catch{}}let l=S(s,p.join("node_modules",t));if(l){if(require$$0$3.statSync(l).isDirectory()){const c=p.join(l,"package.json");if(D(c)?l=d(c):l=p.join(l,"tsconfig.json"),D(l))return l}else if(l.endsWith(".json"))return l}if(!t.endsWith(".json")&&(t+=".json",l=S(s,p.join("node_modules",t)),l))return l;throw new Error(`File '${n}' not found.`)}const an=(n,s)=>{var t;const e=mn(n,s),i=J(e);if(delete i.references,(t=i.compilerOptions)!=null&&t.baseUrl){const{compilerOptions:l}=i;l.baseUrl=p.relative(s,p.join(p.dirname(e),l.baseUrl))||"./";}return i.files&&(i.files=i.files.map(l=>p.relative(s,p.join(p.dirname(e),l)))),i.include&&(i.include=i.include.map(l=>p.relative(s,p.join(p.dirname(e),l)))),i},J=n=>{let s;try{s=require$$0$3.realpathSync(n);}catch{throw new Error(`Cannot resolve tsconfig at path: ${n}`)}const t=p.dirname(s);let e=q(s)||{};if(typeof e!="object")throw new SyntaxError(`Failed to parse tsconfig at: ${n}`);if(e.extends){const i=Array.isArray(e.extends)?e.extends:[e.extends];delete e.extends;for(const l of i.reverse()){const c=an(l,t),a={...c,...e,compilerOptions:{...c.compilerOptions,...e.compilerOptions}};c.watchOptions&&(a.watchOptions={...c.watchOptions,...e.watchOptions}),e=a;}}if(e.compilerOptions){const{compilerOptions:i}=e;i.baseUrl&&(i.baseUrl=M(i.baseUrl)),i.outDir&&(Array.isArray(e.exclude)||(e.exclude=[]),e.exclude.push(i.outDir),i.outDir=M(i.outDir));}else e.compilerOptions={};if(e.files&&(e.files=e.files.map(M)),e.include&&(e.include=e.include.map(L)),e.watchOptions){const{watchOptions:i}=e;i.excludeDirectories&&(i.excludeDirectories=i.excludeDirectories.map(l=>L(p.resolve(t,l))));}return e};function kn(n=process.cwd(),s="tsconfig.json"){const t=S(L(n),s);if(!t)return null;const e=J(t);return {path:t,config:e}}p.posix;process.platform==="win32";
|
|
11744
|
+
|
|
11745
|
+
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
11746
|
+
const newLineRegExp = /\r?\n/;
|
|
11747
|
+
const errCodeRegExp = /error TS(?<errCode>\d+)/;
|
|
11748
|
+
async function makeTscErrorInfo(errInfo) {
|
|
11749
|
+
var _a;
|
|
11750
|
+
const [errFilePathPos = "", ...errMsgRawArr] = errInfo.split(":");
|
|
11751
|
+
if (!errFilePathPos || errMsgRawArr.length === 0 || errMsgRawArr.join("").length === 0)
|
|
11752
|
+
return ["unknown filepath", null];
|
|
11753
|
+
const errMsgRaw = errMsgRawArr.join("").trim();
|
|
11754
|
+
const [errFilePath, errPos] = errFilePathPos.slice(0, -1).split("(");
|
|
11755
|
+
if (!errFilePath || !errPos)
|
|
11756
|
+
return ["unknown filepath", null];
|
|
11757
|
+
const [errLine, errCol] = errPos.split(",");
|
|
11758
|
+
if (!errLine || !errCol)
|
|
11759
|
+
return [errFilePath, null];
|
|
11760
|
+
const execArr = errCodeRegExp.exec(errMsgRaw);
|
|
11761
|
+
if (!execArr)
|
|
11762
|
+
return [errFilePath, null];
|
|
11763
|
+
const errCodeStr = ((_a = execArr.groups) == null ? void 0 : _a.errCode) ?? "";
|
|
11764
|
+
if (!errCodeStr)
|
|
11765
|
+
return [errFilePath, null];
|
|
11766
|
+
const line = Number(errLine);
|
|
11767
|
+
const col = Number(errCol);
|
|
11768
|
+
const errCode = Number(errCodeStr);
|
|
11769
|
+
return [
|
|
11770
|
+
errFilePath,
|
|
11771
|
+
{
|
|
11772
|
+
filePath: errFilePath,
|
|
11773
|
+
errCode,
|
|
11774
|
+
line,
|
|
11775
|
+
column: col,
|
|
11776
|
+
errMsg: errMsgRaw.slice(`error TS${errCode} `.length)
|
|
11777
|
+
}
|
|
11778
|
+
];
|
|
12452
11779
|
}
|
|
12453
|
-
function
|
|
12454
|
-
|
|
11780
|
+
async function getTsconfig(root, config) {
|
|
11781
|
+
var _a;
|
|
11782
|
+
const configName = ((_a = config.tsconfig) == null ? void 0 : _a.includes("jsconfig.json")) ? "jsconfig.json" : void 0;
|
|
11783
|
+
const tsconfig = kn(config.tsconfig || root, configName);
|
|
11784
|
+
if (!tsconfig)
|
|
11785
|
+
throw new Error("no tsconfig.json found");
|
|
11786
|
+
const tempConfigPath = join(dirname(tsconfig.path), "tsconfig.vitest-temp.json");
|
|
11787
|
+
try {
|
|
11788
|
+
const tmpTsConfig = { ...tsconfig.config };
|
|
11789
|
+
tmpTsConfig.compilerOptions = tmpTsConfig.compilerOptions || {};
|
|
11790
|
+
tmpTsConfig.compilerOptions.emitDeclarationOnly = false;
|
|
11791
|
+
tmpTsConfig.compilerOptions.incremental = true;
|
|
11792
|
+
tmpTsConfig.compilerOptions.tsBuildInfoFile = join(
|
|
11793
|
+
__dirname,
|
|
11794
|
+
"tsconfig.tmp.tsbuildinfo"
|
|
11795
|
+
);
|
|
11796
|
+
const tsconfigFinalContent = JSON.stringify(tmpTsConfig, null, 2);
|
|
11797
|
+
await writeFile(tempConfigPath, tsconfigFinalContent);
|
|
11798
|
+
return { path: tempConfigPath, config: tmpTsConfig };
|
|
11799
|
+
} catch (err) {
|
|
11800
|
+
throw new Error("failed to write tsconfig.temp.json", { cause: err });
|
|
11801
|
+
}
|
|
12455
11802
|
}
|
|
12456
|
-
function
|
|
12457
|
-
|
|
11803
|
+
async function getRawErrsMapFromTsCompile(tscErrorStdout) {
|
|
11804
|
+
const rawErrsMap = /* @__PURE__ */ new Map();
|
|
11805
|
+
const infos = await Promise.all(
|
|
11806
|
+
tscErrorStdout.split(newLineRegExp).reduce((prev, next) => {
|
|
11807
|
+
if (!next)
|
|
11808
|
+
return prev;
|
|
11809
|
+
else if (!next.startsWith(" "))
|
|
11810
|
+
prev.push(next);
|
|
11811
|
+
else
|
|
11812
|
+
prev[prev.length - 1] += `
|
|
11813
|
+
${next}`;
|
|
11814
|
+
return prev;
|
|
11815
|
+
}, []).map((errInfoLine) => makeTscErrorInfo(errInfoLine))
|
|
11816
|
+
);
|
|
11817
|
+
infos.forEach(([errFilePath, errInfo]) => {
|
|
11818
|
+
var _a;
|
|
11819
|
+
if (!errInfo)
|
|
11820
|
+
return;
|
|
11821
|
+
if (!rawErrsMap.has(errFilePath))
|
|
11822
|
+
rawErrsMap.set(errFilePath, [errInfo]);
|
|
11823
|
+
else
|
|
11824
|
+
(_a = rawErrsMap.get(errFilePath)) == null ? void 0 : _a.push(errInfo);
|
|
11825
|
+
});
|
|
11826
|
+
return rawErrsMap;
|
|
12458
11827
|
}
|
|
12459
|
-
|
|
12460
|
-
|
|
12461
|
-
|
|
11828
|
+
|
|
11829
|
+
function createIndexMap(source) {
|
|
11830
|
+
const map = /* @__PURE__ */ new Map();
|
|
11831
|
+
let index = 0;
|
|
11832
|
+
let line = 1;
|
|
11833
|
+
let column = 1;
|
|
11834
|
+
for (const char of source) {
|
|
11835
|
+
map.set(`${line}:${column}`, index++);
|
|
11836
|
+
if (char === "\n" || char === "\r\n") {
|
|
11837
|
+
line++;
|
|
11838
|
+
column = 0;
|
|
11839
|
+
} else {
|
|
11840
|
+
column++;
|
|
11841
|
+
}
|
|
11842
|
+
}
|
|
11843
|
+
return map;
|
|
11844
|
+
}
|
|
11845
|
+
|
|
11846
|
+
async function collectTests(ctx, filepath) {
|
|
11847
|
+
const request = await ctx.vitenode.transformRequest(filepath, filepath);
|
|
11848
|
+
if (!request)
|
|
11849
|
+
return null;
|
|
11850
|
+
const ast = parse$4(request.code, {
|
|
11851
|
+
ecmaVersion: "latest",
|
|
11852
|
+
allowAwaitOutsideFunction: true
|
|
11853
|
+
});
|
|
11854
|
+
const testFilepath = relative(ctx.config.root, filepath);
|
|
11855
|
+
const file = {
|
|
11856
|
+
filepath,
|
|
11857
|
+
type: "suite",
|
|
11858
|
+
id: generateHash(`${testFilepath}${ctx.config.name || ""}`),
|
|
11859
|
+
name: testFilepath,
|
|
11860
|
+
mode: "run",
|
|
11861
|
+
tasks: [],
|
|
11862
|
+
start: ast.start,
|
|
11863
|
+
end: ast.end,
|
|
11864
|
+
meta: { typecheck: true }
|
|
11865
|
+
};
|
|
11866
|
+
const definitions = [];
|
|
11867
|
+
const getName = (callee) => {
|
|
11868
|
+
var _a, _b, _c;
|
|
11869
|
+
if (!callee)
|
|
11870
|
+
return null;
|
|
11871
|
+
if (callee.type === "Identifier")
|
|
11872
|
+
return callee.name;
|
|
11873
|
+
if (callee.type === "MemberExpression") {
|
|
11874
|
+
if ((_b = (_a = callee.object) == null ? void 0 : _a.name) == null ? void 0 : _b.startsWith("__vite_ssr_"))
|
|
11875
|
+
return getName(callee.property);
|
|
11876
|
+
return getName((_c = callee.object) == null ? void 0 : _c.property);
|
|
11877
|
+
}
|
|
11878
|
+
return null;
|
|
11879
|
+
};
|
|
11880
|
+
ancestor(ast, {
|
|
11881
|
+
CallExpression(node) {
|
|
11882
|
+
var _a;
|
|
11883
|
+
const { callee } = node;
|
|
11884
|
+
const name = getName(callee);
|
|
11885
|
+
if (!name)
|
|
11886
|
+
return;
|
|
11887
|
+
if (!["it", "test", "describe", "suite"].includes(name))
|
|
11888
|
+
return;
|
|
11889
|
+
const { arguments: [{ value: message }] } = node;
|
|
11890
|
+
const property = (_a = callee == null ? void 0 : callee.property) == null ? void 0 : _a.name;
|
|
11891
|
+
let mode = !property || property === name ? "run" : property;
|
|
11892
|
+
if (!["run", "skip", "todo", "only", "skipIf", "runIf"].includes(mode))
|
|
11893
|
+
throw new Error(`${name}.${mode} syntax is not supported when testing types`);
|
|
11894
|
+
if (mode === "skipIf" || mode === "runIf")
|
|
11895
|
+
mode = "skip";
|
|
11896
|
+
definitions.push({
|
|
11897
|
+
start: node.start,
|
|
11898
|
+
end: node.end,
|
|
11899
|
+
name: message,
|
|
11900
|
+
type: name === "it" || name === "test" ? "test" : "suite",
|
|
11901
|
+
mode
|
|
11902
|
+
});
|
|
11903
|
+
}
|
|
11904
|
+
});
|
|
11905
|
+
let lastSuite = file;
|
|
11906
|
+
const updateLatestSuite = (index) => {
|
|
11907
|
+
const suite = lastSuite;
|
|
11908
|
+
while (lastSuite !== file && lastSuite.end < index)
|
|
11909
|
+
lastSuite = suite.suite;
|
|
11910
|
+
return lastSuite;
|
|
11911
|
+
};
|
|
11912
|
+
definitions.sort((a, b) => a.start - b.start).forEach((definition) => {
|
|
11913
|
+
const latestSuite = updateLatestSuite(definition.start);
|
|
11914
|
+
let mode = definition.mode;
|
|
11915
|
+
if (latestSuite.mode !== "run")
|
|
11916
|
+
mode = latestSuite.mode;
|
|
11917
|
+
if (definition.type === "suite") {
|
|
11918
|
+
const task2 = {
|
|
11919
|
+
type: definition.type,
|
|
11920
|
+
id: "",
|
|
11921
|
+
suite: latestSuite,
|
|
11922
|
+
file,
|
|
11923
|
+
tasks: [],
|
|
11924
|
+
mode,
|
|
11925
|
+
name: definition.name,
|
|
11926
|
+
end: definition.end,
|
|
11927
|
+
start: definition.start,
|
|
11928
|
+
meta: {
|
|
11929
|
+
typecheck: true
|
|
11930
|
+
}
|
|
11931
|
+
};
|
|
11932
|
+
definition.task = task2;
|
|
11933
|
+
latestSuite.tasks.push(task2);
|
|
11934
|
+
lastSuite = task2;
|
|
11935
|
+
return;
|
|
11936
|
+
}
|
|
11937
|
+
const task = {
|
|
11938
|
+
type: definition.type,
|
|
11939
|
+
id: "",
|
|
11940
|
+
suite: latestSuite,
|
|
11941
|
+
file,
|
|
11942
|
+
mode,
|
|
11943
|
+
context: {},
|
|
11944
|
+
// not used in typecheck
|
|
11945
|
+
name: definition.name,
|
|
11946
|
+
end: definition.end,
|
|
11947
|
+
start: definition.start,
|
|
11948
|
+
meta: {
|
|
11949
|
+
typecheck: true
|
|
11950
|
+
}
|
|
11951
|
+
};
|
|
11952
|
+
definition.task = task;
|
|
11953
|
+
latestSuite.tasks.push(task);
|
|
11954
|
+
});
|
|
11955
|
+
calculateSuiteHash(file);
|
|
11956
|
+
const hasOnly = someTasksAreOnly(file);
|
|
11957
|
+
interpretTaskModes(file, ctx.config.testNamePattern, hasOnly, false, ctx.config.allowOnly);
|
|
11958
|
+
return {
|
|
11959
|
+
file,
|
|
11960
|
+
parsed: request.code,
|
|
11961
|
+
filepath,
|
|
11962
|
+
map: request.map,
|
|
11963
|
+
definitions
|
|
11964
|
+
};
|
|
12462
11965
|
}
|
|
12463
|
-
|
|
12464
|
-
|
|
12465
|
-
|
|
12466
|
-
|
|
11966
|
+
|
|
11967
|
+
class TypeCheckError extends Error {
|
|
11968
|
+
constructor(message, stacks) {
|
|
11969
|
+
super(message);
|
|
11970
|
+
this.message = message;
|
|
11971
|
+
this.stacks = stacks;
|
|
11972
|
+
this.name = "TypeCheckError";
|
|
11973
|
+
}
|
|
12467
11974
|
}
|
|
12468
|
-
|
|
12469
|
-
|
|
12470
|
-
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
query,
|
|
12476
|
-
hash,
|
|
12477
|
-
type: UrlType.Absolute,
|
|
11975
|
+
class Typechecker {
|
|
11976
|
+
constructor(ctx, files) {
|
|
11977
|
+
this.ctx = ctx;
|
|
11978
|
+
this.files = files;
|
|
11979
|
+
this._result = {
|
|
11980
|
+
files: [],
|
|
11981
|
+
sourceErrors: []
|
|
12478
11982
|
};
|
|
12479
|
-
}
|
|
12480
|
-
|
|
12481
|
-
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
|
|
12485
|
-
|
|
11983
|
+
this._tests = {};
|
|
11984
|
+
}
|
|
11985
|
+
onParseStart(fn) {
|
|
11986
|
+
this._onParseStart = fn;
|
|
11987
|
+
}
|
|
11988
|
+
onParseEnd(fn) {
|
|
11989
|
+
this._onParseEnd = fn;
|
|
11990
|
+
}
|
|
11991
|
+
onWatcherRerun(fn) {
|
|
11992
|
+
this._onWatcherRerun = fn;
|
|
11993
|
+
}
|
|
11994
|
+
async collectFileTests(filepath) {
|
|
11995
|
+
return collectTests(this.ctx, filepath);
|
|
11996
|
+
}
|
|
11997
|
+
getFiles() {
|
|
11998
|
+
return this.files.filter((filename) => {
|
|
11999
|
+
const extension = extname(filename);
|
|
12000
|
+
return extension !== ".js" || this.allowJs;
|
|
12001
|
+
});
|
|
12002
|
+
}
|
|
12003
|
+
async collectTests() {
|
|
12004
|
+
const tests = (await Promise.all(
|
|
12005
|
+
this.getFiles().map((filepath) => this.collectFileTests(filepath))
|
|
12006
|
+
)).reduce((acc, data) => {
|
|
12007
|
+
if (!data)
|
|
12008
|
+
return acc;
|
|
12009
|
+
acc[data.filepath] = data;
|
|
12010
|
+
return acc;
|
|
12011
|
+
}, {});
|
|
12012
|
+
this._tests = tests;
|
|
12013
|
+
return tests;
|
|
12014
|
+
}
|
|
12015
|
+
markPassed(file) {
|
|
12016
|
+
var _a;
|
|
12017
|
+
if (!((_a = file.result) == null ? void 0 : _a.state)) {
|
|
12018
|
+
file.result = {
|
|
12019
|
+
state: "pass"
|
|
12020
|
+
};
|
|
12486
12021
|
}
|
|
12487
|
-
|
|
12488
|
-
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
|
|
12022
|
+
const markTasks = (tasks) => {
|
|
12023
|
+
var _a2;
|
|
12024
|
+
for (const task of tasks) {
|
|
12025
|
+
if ("tasks" in task)
|
|
12026
|
+
markTasks(task.tasks);
|
|
12027
|
+
if (!((_a2 = task.result) == null ? void 0 : _a2.state) && task.mode === "run") {
|
|
12028
|
+
task.result = {
|
|
12029
|
+
state: "pass"
|
|
12030
|
+
};
|
|
12031
|
+
}
|
|
12032
|
+
}
|
|
12033
|
+
};
|
|
12034
|
+
markTasks(file.tasks);
|
|
12035
|
+
}
|
|
12036
|
+
async prepareResults(output) {
|
|
12037
|
+
const typeErrors = await this.parseTscLikeOutput(output);
|
|
12038
|
+
const testFiles = new Set(this.getFiles());
|
|
12039
|
+
if (!this._tests)
|
|
12040
|
+
this._tests = await this.collectTests();
|
|
12041
|
+
const sourceErrors = [];
|
|
12042
|
+
const files = [];
|
|
12043
|
+
testFiles.forEach((path) => {
|
|
12044
|
+
const { file, definitions, map, parsed } = this._tests[path];
|
|
12045
|
+
const errors = typeErrors.get(path);
|
|
12046
|
+
files.push(file);
|
|
12047
|
+
if (!errors) {
|
|
12048
|
+
this.markPassed(file);
|
|
12049
|
+
return;
|
|
12050
|
+
}
|
|
12051
|
+
const sortedDefinitions = [...definitions.sort((a, b) => b.start - a.start)];
|
|
12052
|
+
const traceMap = map && new TraceMap(map);
|
|
12053
|
+
const indexMap = createIndexMap(parsed);
|
|
12054
|
+
const markState = (task, state) => {
|
|
12055
|
+
task.result = {
|
|
12056
|
+
state: task.mode === "run" || task.mode === "only" ? state : task.mode
|
|
12057
|
+
};
|
|
12058
|
+
if (task.suite)
|
|
12059
|
+
markState(task.suite, state);
|
|
12060
|
+
};
|
|
12061
|
+
errors.forEach(({ error, originalError }) => {
|
|
12062
|
+
var _a;
|
|
12063
|
+
const processedPos = traceMap ? generatedPositionFor(traceMap, {
|
|
12064
|
+
line: originalError.line,
|
|
12065
|
+
column: originalError.column,
|
|
12066
|
+
source: basename(path)
|
|
12067
|
+
}) : originalError;
|
|
12068
|
+
const line = processedPos.line ?? originalError.line;
|
|
12069
|
+
const column = processedPos.column ?? originalError.column;
|
|
12070
|
+
const index = indexMap.get(`${line}:${column}`);
|
|
12071
|
+
const definition = index != null && sortedDefinitions.find((def) => def.start <= index && def.end >= index);
|
|
12072
|
+
const suite = definition ? definition.task : file;
|
|
12073
|
+
const state = suite.mode === "run" || suite.mode === "only" ? "fail" : suite.mode;
|
|
12074
|
+
const errors2 = ((_a = suite.result) == null ? void 0 : _a.errors) || [];
|
|
12075
|
+
suite.result = {
|
|
12076
|
+
state,
|
|
12077
|
+
errors: errors2
|
|
12078
|
+
};
|
|
12079
|
+
errors2.push(error);
|
|
12080
|
+
if (state === "fail" && suite.suite)
|
|
12081
|
+
markState(suite.suite, "fail");
|
|
12082
|
+
});
|
|
12083
|
+
this.markPassed(file);
|
|
12084
|
+
});
|
|
12085
|
+
typeErrors.forEach((errors, path) => {
|
|
12086
|
+
if (!testFiles.has(path))
|
|
12087
|
+
sourceErrors.push(...errors.map(({ error }) => error));
|
|
12088
|
+
});
|
|
12089
|
+
return {
|
|
12090
|
+
files,
|
|
12091
|
+
sourceErrors
|
|
12092
|
+
};
|
|
12093
|
+
}
|
|
12094
|
+
async parseTscLikeOutput(output) {
|
|
12095
|
+
const errorsMap = await getRawErrsMapFromTsCompile(output);
|
|
12096
|
+
const typesErrors = /* @__PURE__ */ new Map();
|
|
12097
|
+
errorsMap.forEach((errors, path) => {
|
|
12098
|
+
const filepath = resolve$2(this.ctx.config.root, path);
|
|
12099
|
+
const suiteErrors = errors.map((info) => {
|
|
12100
|
+
const limit = Error.stackTraceLimit;
|
|
12101
|
+
Error.stackTraceLimit = 0;
|
|
12102
|
+
const error = new TypeCheckError(info.errMsg, [
|
|
12103
|
+
{
|
|
12104
|
+
file: filepath,
|
|
12105
|
+
line: info.line,
|
|
12106
|
+
column: info.column,
|
|
12107
|
+
method: ""
|
|
12108
|
+
}
|
|
12109
|
+
]);
|
|
12110
|
+
Error.stackTraceLimit = limit;
|
|
12111
|
+
return {
|
|
12112
|
+
originalError: info,
|
|
12113
|
+
error
|
|
12114
|
+
};
|
|
12115
|
+
});
|
|
12116
|
+
typesErrors.set(filepath, suiteErrors);
|
|
12117
|
+
});
|
|
12118
|
+
return typesErrors;
|
|
12119
|
+
}
|
|
12120
|
+
async clear() {
|
|
12121
|
+
if (this.tempConfigPath)
|
|
12122
|
+
await rm(this.tempConfigPath, { force: true });
|
|
12123
|
+
}
|
|
12124
|
+
async stop() {
|
|
12125
|
+
var _a;
|
|
12126
|
+
await this.clear();
|
|
12127
|
+
(_a = this.process) == null ? void 0 : _a.kill();
|
|
12128
|
+
}
|
|
12129
|
+
async ensurePackageInstalled(root, checker) {
|
|
12130
|
+
if (checker !== "tsc" && checker !== "vue-tsc")
|
|
12131
|
+
return;
|
|
12132
|
+
const packageName = checker === "tsc" ? "typescript" : "vue-tsc";
|
|
12133
|
+
await ensurePackageInstalled(packageName, root);
|
|
12134
|
+
}
|
|
12135
|
+
async prepare() {
|
|
12136
|
+
const { root, typecheck } = this.ctx.config;
|
|
12137
|
+
await this.ensurePackageInstalled(root, typecheck.checker);
|
|
12138
|
+
const { config, path } = await getTsconfig(root, typecheck);
|
|
12139
|
+
this.tempConfigPath = path;
|
|
12140
|
+
this.allowJs = typecheck.allowJs || config.allowJs || false;
|
|
12141
|
+
}
|
|
12142
|
+
async start() {
|
|
12143
|
+
var _a, _b, _c;
|
|
12144
|
+
if (!this.tempConfigPath)
|
|
12145
|
+
throw new Error("tsconfig was not initialized");
|
|
12146
|
+
const { root, watch, typecheck } = this.ctx.config;
|
|
12147
|
+
const args = ["--noEmit", "--pretty", "false", "-p", this.tempConfigPath];
|
|
12148
|
+
if (watch)
|
|
12149
|
+
args.push("--watch");
|
|
12150
|
+
if (typecheck.allowJs)
|
|
12151
|
+
args.push("--allowJs", "--checkJs");
|
|
12152
|
+
let output = "";
|
|
12153
|
+
const child = execa(typecheck.checker, args, {
|
|
12154
|
+
cwd: root,
|
|
12155
|
+
stdout: "pipe",
|
|
12156
|
+
reject: false
|
|
12157
|
+
});
|
|
12158
|
+
this.process = child;
|
|
12159
|
+
await ((_a = this._onParseStart) == null ? void 0 : _a.call(this));
|
|
12160
|
+
let rerunTriggered = false;
|
|
12161
|
+
(_b = child.stdout) == null ? void 0 : _b.on("data", (chunk) => {
|
|
12162
|
+
var _a2;
|
|
12163
|
+
output += chunk;
|
|
12164
|
+
if (!watch)
|
|
12165
|
+
return;
|
|
12166
|
+
if (output.includes("File change detected") && !rerunTriggered) {
|
|
12167
|
+
(_a2 = this._onWatcherRerun) == null ? void 0 : _a2.call(this);
|
|
12168
|
+
this._result.sourceErrors = [];
|
|
12169
|
+
this._result.files = [];
|
|
12170
|
+
this._tests = null;
|
|
12171
|
+
rerunTriggered = true;
|
|
12172
|
+
}
|
|
12173
|
+
if (/Found \w+ errors*. Watching for/.test(output)) {
|
|
12174
|
+
rerunTriggered = false;
|
|
12175
|
+
this.prepareResults(output).then((result) => {
|
|
12176
|
+
var _a3;
|
|
12177
|
+
this._result = result;
|
|
12178
|
+
(_a3 = this._onParseEnd) == null ? void 0 : _a3.call(this, result);
|
|
12179
|
+
});
|
|
12180
|
+
output = "";
|
|
12181
|
+
}
|
|
12182
|
+
});
|
|
12183
|
+
if (!watch) {
|
|
12184
|
+
await child;
|
|
12185
|
+
this._result = await this.prepareResults(output);
|
|
12186
|
+
await ((_c = this._onParseEnd) == null ? void 0 : _c.call(this, this._result));
|
|
12493
12187
|
}
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
|
|
12497
|
-
|
|
12498
|
-
|
|
12499
|
-
|
|
12500
|
-
|
|
12501
|
-
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
: input.startsWith('#')
|
|
12505
|
-
? UrlType.Hash
|
|
12506
|
-
: UrlType.RelativePath
|
|
12507
|
-
: UrlType.Empty;
|
|
12508
|
-
return url;
|
|
12509
|
-
}
|
|
12510
|
-
function stripPathFilename(path) {
|
|
12511
|
-
// If a path ends with a parent directory "..", then it's a relative path with excess parent
|
|
12512
|
-
// paths. It's not a file, so we can't strip it.
|
|
12513
|
-
if (path.endsWith('/..'))
|
|
12514
|
-
return path;
|
|
12515
|
-
const index = path.lastIndexOf('/');
|
|
12516
|
-
return path.slice(0, index + 1);
|
|
12188
|
+
}
|
|
12189
|
+
getResult() {
|
|
12190
|
+
return this._result;
|
|
12191
|
+
}
|
|
12192
|
+
getTestFiles() {
|
|
12193
|
+
return Object.values(this._tests || {}).map((i) => i.file);
|
|
12194
|
+
}
|
|
12195
|
+
getTestPacks() {
|
|
12196
|
+
return Object.values(this._tests || {}).map(({ file }) => getTasks(file)).flat().map((i) => [i.id, void 0]);
|
|
12197
|
+
}
|
|
12517
12198
|
}
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
|
|
12199
|
+
|
|
12200
|
+
async function printError(error, ctx, options = {}) {
|
|
12201
|
+
const { showCodeFrame = true, fullStack = false, type } = options;
|
|
12202
|
+
let e = error;
|
|
12203
|
+
if (isPrimitive(e)) {
|
|
12204
|
+
e = {
|
|
12205
|
+
message: String(error).split(/\n/g)[0],
|
|
12206
|
+
stack: String(error)
|
|
12207
|
+
};
|
|
12208
|
+
}
|
|
12209
|
+
if (!e) {
|
|
12210
|
+
const error2 = new Error("unknown error");
|
|
12211
|
+
e = {
|
|
12212
|
+
message: e ?? error2.message,
|
|
12213
|
+
stack: error2.stack
|
|
12214
|
+
};
|
|
12215
|
+
}
|
|
12216
|
+
if (!ctx.config)
|
|
12217
|
+
return printErrorMessage(e, ctx.logger);
|
|
12218
|
+
const stacks = parseErrorStacktrace(e, fullStack ? [] : void 0);
|
|
12219
|
+
const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find(
|
|
12220
|
+
(stack) => ctx.getModuleProjects(stack.file).length && existsSync(stack.file)
|
|
12221
|
+
);
|
|
12222
|
+
const errorProperties = getErrorProperties(e);
|
|
12223
|
+
if (type)
|
|
12224
|
+
printErrorType(type, ctx);
|
|
12225
|
+
printErrorMessage(e, ctx.logger);
|
|
12226
|
+
if (e.frame) {
|
|
12227
|
+
ctx.logger.error(c.yellow(e.frame));
|
|
12228
|
+
} else {
|
|
12229
|
+
printStack(ctx, stacks, nearest, errorProperties, (s) => {
|
|
12230
|
+
if (showCodeFrame && s === nearest && nearest) {
|
|
12231
|
+
const sourceCode = readFileSync(nearest.file, "utf-8");
|
|
12232
|
+
ctx.logger.error(c.yellow(generateCodeFrame(sourceCode, 4, s.line, s.column)));
|
|
12233
|
+
}
|
|
12234
|
+
});
|
|
12235
|
+
}
|
|
12236
|
+
const testPath = e.VITEST_TEST_PATH;
|
|
12237
|
+
const testName = e.VITEST_TEST_NAME;
|
|
12238
|
+
const afterEnvTeardown = e.VITEST_AFTER_ENV_TEARDOWN;
|
|
12239
|
+
if (testPath)
|
|
12240
|
+
ctx.logger.error(c.red(`This error originated in "${c.bold(testPath)}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`));
|
|
12241
|
+
if (testName) {
|
|
12242
|
+
ctx.logger.error(c.red(`The latest test that might've caused the error is "${c.bold(testName)}". It might mean one of the following:
|
|
12243
|
+
- The error was thrown, while Vitest was running this test.
|
|
12244
|
+
- This was the last recorded test before the error was thrown, if error originated after test finished its execution.`));
|
|
12245
|
+
}
|
|
12246
|
+
if (afterEnvTeardown) {
|
|
12247
|
+
ctx.logger.error(c.red("This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:\n- cancel timeouts using clearTimeout and clearInterval\n- wait for promises to resolve using the await keyword"));
|
|
12248
|
+
}
|
|
12249
|
+
if (typeof e.cause === "object" && e.cause && "name" in e.cause) {
|
|
12250
|
+
e.cause.name = `Caused by: ${e.cause.name}`;
|
|
12251
|
+
await printError(e.cause, ctx, { fullStack, showCodeFrame: false });
|
|
12252
|
+
}
|
|
12253
|
+
handleImportOutsideModuleError(e.stack || e.stackStr || "", ctx);
|
|
12254
|
+
if (e.diff)
|
|
12255
|
+
displayDiff(e.diff, ctx.logger.console);
|
|
12529
12256
|
}
|
|
12530
|
-
|
|
12531
|
-
|
|
12532
|
-
|
|
12533
|
-
*/
|
|
12534
|
-
function normalizePath(url, type) {
|
|
12535
|
-
const rel = type <= UrlType.RelativePath;
|
|
12536
|
-
const pieces = url.path.split('/');
|
|
12537
|
-
// We need to preserve the first piece always, so that we output a leading slash. The item at
|
|
12538
|
-
// pieces[0] is an empty string.
|
|
12539
|
-
let pointer = 1;
|
|
12540
|
-
// Positive is the number of real directories we've output, used for popping a parent directory.
|
|
12541
|
-
// Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
|
|
12542
|
-
let positive = 0;
|
|
12543
|
-
// We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
|
|
12544
|
-
// generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
|
|
12545
|
-
// real directory, we won't need to append, unless the other conditions happen again.
|
|
12546
|
-
let addTrailingSlash = false;
|
|
12547
|
-
for (let i = 1; i < pieces.length; i++) {
|
|
12548
|
-
const piece = pieces[i];
|
|
12549
|
-
// An empty directory, could be a trailing slash, or just a double "//" in the path.
|
|
12550
|
-
if (!piece) {
|
|
12551
|
-
addTrailingSlash = true;
|
|
12552
|
-
continue;
|
|
12553
|
-
}
|
|
12554
|
-
// If we encounter a real directory, then we don't need to append anymore.
|
|
12555
|
-
addTrailingSlash = false;
|
|
12556
|
-
// A current directory, which we can always drop.
|
|
12557
|
-
if (piece === '.')
|
|
12558
|
-
continue;
|
|
12559
|
-
// A parent directory, we need to see if there are any real directories we can pop. Else, we
|
|
12560
|
-
// have an excess of parents, and we'll need to keep the "..".
|
|
12561
|
-
if (piece === '..') {
|
|
12562
|
-
if (positive) {
|
|
12563
|
-
addTrailingSlash = true;
|
|
12564
|
-
positive--;
|
|
12565
|
-
pointer--;
|
|
12566
|
-
}
|
|
12567
|
-
else if (rel) {
|
|
12568
|
-
// If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
|
|
12569
|
-
// URL, protocol relative URL, or an absolute path, we don't need to keep excess.
|
|
12570
|
-
pieces[pointer++] = piece;
|
|
12571
|
-
}
|
|
12572
|
-
continue;
|
|
12573
|
-
}
|
|
12574
|
-
// We've encountered a real directory. Move it to the next insertion pointer, which accounts for
|
|
12575
|
-
// any popped or dropped directories.
|
|
12576
|
-
pieces[pointer++] = piece;
|
|
12577
|
-
positive++;
|
|
12578
|
-
}
|
|
12579
|
-
let path = '';
|
|
12580
|
-
for (let i = 1; i < pointer; i++) {
|
|
12581
|
-
path += '/' + pieces[i];
|
|
12582
|
-
}
|
|
12583
|
-
if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
|
|
12584
|
-
path += '/';
|
|
12585
|
-
}
|
|
12586
|
-
url.path = path;
|
|
12257
|
+
function printErrorType(type, ctx) {
|
|
12258
|
+
ctx.logger.error(`
|
|
12259
|
+
${c.red(divider(c.bold(c.inverse(` ${type} `))))}`);
|
|
12587
12260
|
}
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
url.port = baseUrl.port;
|
|
12615
|
-
// fall through
|
|
12616
|
-
case UrlType.SchemeRelative:
|
|
12617
|
-
// The input doesn't have a schema at least, so we need to copy at least that over.
|
|
12618
|
-
url.scheme = baseUrl.scheme;
|
|
12619
|
-
}
|
|
12620
|
-
if (baseType > inputType)
|
|
12621
|
-
inputType = baseType;
|
|
12622
|
-
}
|
|
12623
|
-
normalizePath(url, inputType);
|
|
12624
|
-
const queryHash = url.query + url.hash;
|
|
12625
|
-
switch (inputType) {
|
|
12626
|
-
// This is impossible, because of the empty checks at the start of the function.
|
|
12627
|
-
// case UrlType.Empty:
|
|
12628
|
-
case UrlType.Hash:
|
|
12629
|
-
case UrlType.Query:
|
|
12630
|
-
return queryHash;
|
|
12631
|
-
case UrlType.RelativePath: {
|
|
12632
|
-
// The first char is always a "/", and we need it to be relative.
|
|
12633
|
-
const path = url.path.slice(1);
|
|
12634
|
-
if (!path)
|
|
12635
|
-
return queryHash || '.';
|
|
12636
|
-
if (isRelative(base || input) && !isRelative(path)) {
|
|
12637
|
-
// If base started with a leading ".", or there is no base and input started with a ".",
|
|
12638
|
-
// then we need to ensure that the relative path starts with a ".". We don't know if
|
|
12639
|
-
// relative starts with a "..", though, so check before prepending.
|
|
12640
|
-
return './' + path + queryHash;
|
|
12641
|
-
}
|
|
12642
|
-
return path + queryHash;
|
|
12643
|
-
}
|
|
12644
|
-
case UrlType.AbsolutePath:
|
|
12645
|
-
return url.path + queryHash;
|
|
12646
|
-
default:
|
|
12647
|
-
return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
|
|
12648
|
-
}
|
|
12261
|
+
const skipErrorProperties = /* @__PURE__ */ new Set([
|
|
12262
|
+
"nameStr",
|
|
12263
|
+
"stack",
|
|
12264
|
+
"cause",
|
|
12265
|
+
"stacks",
|
|
12266
|
+
"stackStr",
|
|
12267
|
+
"type",
|
|
12268
|
+
"showDiff",
|
|
12269
|
+
"diff",
|
|
12270
|
+
"actual",
|
|
12271
|
+
"expected",
|
|
12272
|
+
"VITEST_TEST_NAME",
|
|
12273
|
+
"VITEST_TEST_PATH",
|
|
12274
|
+
"VITEST_AFTER_ENV_TEARDOWN",
|
|
12275
|
+
...Object.getOwnPropertyNames(Error.prototype),
|
|
12276
|
+
...Object.getOwnPropertyNames(Object.prototype)
|
|
12277
|
+
]);
|
|
12278
|
+
function getErrorProperties(e) {
|
|
12279
|
+
const errorObject = /* @__PURE__ */ Object.create(null);
|
|
12280
|
+
if (e.name === "AssertionError")
|
|
12281
|
+
return errorObject;
|
|
12282
|
+
for (const key of Object.getOwnPropertyNames(e)) {
|
|
12283
|
+
if (!skipErrorProperties.has(key))
|
|
12284
|
+
errorObject[key] = e[key];
|
|
12285
|
+
}
|
|
12286
|
+
return errorObject;
|
|
12649
12287
|
}
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12288
|
+
const esmErrors = [
|
|
12289
|
+
"Cannot use import statement outside a module",
|
|
12290
|
+
"Unexpected token 'export'"
|
|
12291
|
+
];
|
|
12292
|
+
function handleImportOutsideModuleError(stack, ctx) {
|
|
12293
|
+
if (!esmErrors.some((e) => stack.includes(e)))
|
|
12294
|
+
return;
|
|
12295
|
+
const path = normalize(stack.split("\n")[0].trim());
|
|
12296
|
+
let name = path.split("/node_modules/").pop() || "";
|
|
12297
|
+
if (name == null ? void 0 : name.startsWith("@"))
|
|
12298
|
+
name = name.split("/").slice(0, 2).join("/");
|
|
12299
|
+
else
|
|
12300
|
+
name = name.split("/")[0];
|
|
12301
|
+
if (name)
|
|
12302
|
+
printModuleWarningForPackage(ctx.logger, path, name);
|
|
12303
|
+
else
|
|
12304
|
+
printModuleWarningForSourceCode(ctx.logger, path);
|
|
12658
12305
|
}
|
|
12306
|
+
function printModuleWarningForPackage(logger, path, name) {
|
|
12307
|
+
logger.error(c.yellow(
|
|
12308
|
+
`Module ${path} seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package ${c.bold(`"${name}"`)} asking them to ship the file in .mjs extension or add "type": "module" in their package.json.
|
|
12659
12309
|
|
|
12660
|
-
|
|
12661
|
-
* Removes everything after the last "/", but leaves the slash.
|
|
12662
|
-
*/
|
|
12663
|
-
function stripFilename(path) {
|
|
12664
|
-
if (!path)
|
|
12665
|
-
return '';
|
|
12666
|
-
const index = path.lastIndexOf('/');
|
|
12667
|
-
return path.slice(0, index + 1);
|
|
12668
|
-
}
|
|
12310
|
+
As a temporary workaround you can try to inline the package by updating your config:
|
|
12669
12311
|
|
|
12670
|
-
|
|
12312
|
+
` + c.gray(c.dim("// vitest.config.js")) + "\n" + c.green(`export default {
|
|
12313
|
+
test: {
|
|
12314
|
+
deps: {
|
|
12315
|
+
inline: [
|
|
12316
|
+
${c.yellow(c.bold(`"${name}"`))}
|
|
12317
|
+
]
|
|
12318
|
+
}
|
|
12319
|
+
}
|
|
12320
|
+
}
|
|
12321
|
+
`)
|
|
12322
|
+
));
|
|
12323
|
+
}
|
|
12324
|
+
function printModuleWarningForSourceCode(logger, path) {
|
|
12325
|
+
logger.error(c.yellow(
|
|
12326
|
+
`Module ${path} seems to be an ES Module but shipped in a CommonJS package. To fix this issue, change the file extension to .mjs or add "type": "module" in your package.json.`
|
|
12327
|
+
));
|
|
12328
|
+
}
|
|
12329
|
+
function displayDiff(diff, console) {
|
|
12330
|
+
console.error(diff);
|
|
12331
|
+
}
|
|
12332
|
+
function printErrorMessage(error, logger) {
|
|
12333
|
+
const errorName = error.name || error.nameStr || "Unknown Error";
|
|
12334
|
+
logger.error(c.red(`${c.bold(errorName)}: ${error.message}`));
|
|
12335
|
+
}
|
|
12336
|
+
function printStack(ctx, stack, highlight, errorProperties, onStack) {
|
|
12337
|
+
const logger = ctx.logger;
|
|
12338
|
+
for (const frame of stack) {
|
|
12339
|
+
const color = frame === highlight ? c.yellow : c.gray;
|
|
12340
|
+
const path = relative(ctx.config.root, frame.file);
|
|
12341
|
+
logger.error(color(` ${c.dim(F_POINTER)} ${[frame.method, c.dim(`${path}:${frame.line}:${frame.column}`)].filter(Boolean).join(" ")}`));
|
|
12342
|
+
onStack == null ? void 0 : onStack(frame);
|
|
12343
|
+
}
|
|
12344
|
+
if (stack.length)
|
|
12345
|
+
logger.error();
|
|
12346
|
+
const hasProperties = Object.keys(errorProperties).length > 0;
|
|
12347
|
+
if (hasProperties) {
|
|
12348
|
+
logger.error(c.red(c.dim(divider())));
|
|
12349
|
+
const propertiesString = stringify$5(errorProperties, 10, { printBasicPrototype: false });
|
|
12350
|
+
logger.error(c.red(c.bold("Serialized Error:")), c.gray(propertiesString));
|
|
12351
|
+
}
|
|
12352
|
+
}
|
|
12353
|
+
function generateCodeFrame(source, indent = 0, lineNumber, columnNumber, range = 2) {
|
|
12354
|
+
var _a;
|
|
12355
|
+
const start = positionToOffset(source, lineNumber, columnNumber);
|
|
12356
|
+
const end = start;
|
|
12357
|
+
const lines = source.split(lineSplitRE);
|
|
12358
|
+
let count = 0;
|
|
12359
|
+
let res = [];
|
|
12360
|
+
const columns = ((_a = process.stdout) == null ? void 0 : _a.columns) || 80;
|
|
12361
|
+
function lineNo(no = "") {
|
|
12362
|
+
return c.gray(`${String(no).padStart(3, " ")}| `);
|
|
12363
|
+
}
|
|
12364
|
+
for (let i = 0; i < lines.length; i++) {
|
|
12365
|
+
count += lines[i].length + 1;
|
|
12366
|
+
if (count >= start) {
|
|
12367
|
+
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
12368
|
+
if (j < 0 || j >= lines.length)
|
|
12369
|
+
continue;
|
|
12370
|
+
const lineLength = lines[j].length;
|
|
12371
|
+
if (lineLength > 200)
|
|
12372
|
+
return "";
|
|
12373
|
+
res.push(lineNo(j + 1) + cliTruncate(lines[j].replace(/\t/g, " "), columns - 5 - indent));
|
|
12374
|
+
if (j === i) {
|
|
12375
|
+
const pad = start - (count - lineLength);
|
|
12376
|
+
const length = Math.max(1, end > count ? lineLength - pad : end - start);
|
|
12377
|
+
res.push(lineNo() + " ".repeat(pad) + c.red("^".repeat(length)));
|
|
12378
|
+
} else if (j > i) {
|
|
12379
|
+
if (end > count) {
|
|
12380
|
+
const length = Math.max(1, Math.min(end - count, lineLength));
|
|
12381
|
+
res.push(lineNo() + c.red("^".repeat(length)));
|
|
12382
|
+
}
|
|
12383
|
+
count += lineLength + 1;
|
|
12384
|
+
}
|
|
12385
|
+
}
|
|
12386
|
+
break;
|
|
12387
|
+
}
|
|
12388
|
+
}
|
|
12389
|
+
if (indent)
|
|
12390
|
+
res = res.map((line) => " ".repeat(indent) + line);
|
|
12391
|
+
return res.join("\n");
|
|
12392
|
+
}
|
|
12671
12393
|
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12394
|
+
class Logger {
|
|
12395
|
+
constructor(ctx, console = globalThis.console) {
|
|
12396
|
+
this.ctx = ctx;
|
|
12397
|
+
this.console = console;
|
|
12398
|
+
this.outputStream = process.stdout;
|
|
12399
|
+
this.errorStream = process.stderr;
|
|
12400
|
+
this.logUpdate = createLogUpdate(process.stdout);
|
|
12401
|
+
}
|
|
12402
|
+
log(...args) {
|
|
12403
|
+
this._clearScreen();
|
|
12404
|
+
this.console.log(...args);
|
|
12405
|
+
}
|
|
12406
|
+
error(...args) {
|
|
12407
|
+
this._clearScreen();
|
|
12408
|
+
this.console.error(...args);
|
|
12409
|
+
}
|
|
12410
|
+
warn(...args) {
|
|
12411
|
+
this._clearScreen();
|
|
12412
|
+
this.console.warn(...args);
|
|
12413
|
+
}
|
|
12414
|
+
clearFullScreen(message) {
|
|
12415
|
+
if (this.ctx.server.config.clearScreen === false) {
|
|
12416
|
+
this.console.log(message);
|
|
12417
|
+
return;
|
|
12682
12418
|
}
|
|
12683
|
-
|
|
12419
|
+
this.console.log(`\x1Bc${message}`);
|
|
12420
|
+
}
|
|
12421
|
+
clearScreen(message, force = false) {
|
|
12422
|
+
if (this.ctx.server.config.clearScreen === false) {
|
|
12423
|
+
this.console.log(message);
|
|
12424
|
+
return;
|
|
12425
|
+
}
|
|
12426
|
+
this._clearScreenPending = message;
|
|
12427
|
+
if (force)
|
|
12428
|
+
this._clearScreen();
|
|
12429
|
+
}
|
|
12430
|
+
_clearScreen() {
|
|
12431
|
+
if (this._clearScreenPending == null)
|
|
12432
|
+
return;
|
|
12433
|
+
const log = this._clearScreenPending;
|
|
12434
|
+
this._clearScreenPending = void 0;
|
|
12435
|
+
this.console.log(`\x1B[1;1H\x1B[J${log}`);
|
|
12436
|
+
}
|
|
12437
|
+
printError(err, fullStack = false, type) {
|
|
12438
|
+
return printError(err, this.ctx, {
|
|
12439
|
+
fullStack,
|
|
12440
|
+
type,
|
|
12441
|
+
showCodeFrame: true
|
|
12442
|
+
});
|
|
12443
|
+
}
|
|
12444
|
+
printNoTestFound(filters) {
|
|
12445
|
+
const config = this.ctx.config;
|
|
12446
|
+
const comma = c.dim(", ");
|
|
12447
|
+
if (filters == null ? void 0 : filters.length)
|
|
12448
|
+
this.console.error(c.dim("filter: ") + c.yellow(filters.join(comma)));
|
|
12449
|
+
if (config.include)
|
|
12450
|
+
this.console.error(c.dim("include: ") + c.yellow(config.include.join(comma)));
|
|
12451
|
+
if (config.exclude)
|
|
12452
|
+
this.console.error(c.dim("exclude: ") + c.yellow(config.exclude.join(comma)));
|
|
12453
|
+
if (config.watchExclude)
|
|
12454
|
+
this.console.error(c.dim("watch exclude: ") + c.yellow(config.watchExclude.join(comma)));
|
|
12455
|
+
if (config.passWithNoTests)
|
|
12456
|
+
this.log(`No ${config.mode} files found, exiting with code 0
|
|
12457
|
+
`);
|
|
12458
|
+
else
|
|
12459
|
+
this.error(c.red(`
|
|
12460
|
+
No ${config.mode} files found, exiting with code 1`));
|
|
12461
|
+
}
|
|
12462
|
+
printBanner() {
|
|
12463
|
+
var _a, _b;
|
|
12464
|
+
this.log();
|
|
12465
|
+
const versionTest = this.ctx.config.watch ? c.blue(`v${version}`) : c.cyan(`v${version}`);
|
|
12466
|
+
const mode = this.ctx.config.watch ? c.blue(" DEV ") : c.cyan(" RUN ");
|
|
12467
|
+
this.log(`${c.inverse(c.bold(mode))} ${versionTest} ${c.gray(this.ctx.config.root)}`);
|
|
12468
|
+
if (this.ctx.config.sequence.sequencer === RandomSequencer)
|
|
12469
|
+
this.log(c.gray(` Running tests with seed "${this.ctx.config.sequence.seed}"`));
|
|
12470
|
+
this.ctx.projects.forEach((project) => {
|
|
12471
|
+
var _a2;
|
|
12472
|
+
if (!project.browser)
|
|
12473
|
+
return;
|
|
12474
|
+
const name = project.getName();
|
|
12475
|
+
const output = project.isCore() ? "" : ` [${name}]`;
|
|
12476
|
+
this.log(c.dim(c.green(` ${output} Browser runner started at http://${((_a2 = project.config.browser.api) == null ? void 0 : _a2.host) || "localhost"}:${c.bold(`${project.browser.config.server.port}`)}`)));
|
|
12477
|
+
});
|
|
12478
|
+
if (this.ctx.config.ui)
|
|
12479
|
+
this.log(c.dim(c.green(` UI started at http://${((_a = this.ctx.config.api) == null ? void 0 : _a.host) || "localhost"}:${c.bold(`${this.ctx.server.config.server.port}`)}${this.ctx.config.uiBase}`)));
|
|
12480
|
+
else if (this.ctx.config.api)
|
|
12481
|
+
this.log(c.dim(c.green(` API started at http://${((_b = this.ctx.config.api) == null ? void 0 : _b.host) || "localhost"}:${c.bold(`${this.ctx.config.api.port}`)}`)));
|
|
12482
|
+
if (this.ctx.coverageProvider)
|
|
12483
|
+
this.log(c.dim(" Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name));
|
|
12484
|
+
this.log();
|
|
12485
|
+
}
|
|
12486
|
+
async printUnhandledErrors(errors) {
|
|
12487
|
+
const errorMessage = c.red(c.bold(
|
|
12488
|
+
`
|
|
12489
|
+
Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
|
|
12490
|
+
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`
|
|
12491
|
+
));
|
|
12492
|
+
this.log(c.red(divider(c.bold(c.inverse(" Unhandled Errors ")))));
|
|
12493
|
+
this.log(errorMessage);
|
|
12494
|
+
await Promise.all(errors.map(async (err) => {
|
|
12495
|
+
await this.printError(err, true, err.type || "Unhandled Error");
|
|
12496
|
+
}));
|
|
12497
|
+
this.log(c.red(divider()));
|
|
12498
|
+
}
|
|
12499
|
+
async printSourceTypeErrors(errors) {
|
|
12500
|
+
const errorMessage = c.red(c.bold(
|
|
12501
|
+
`
|
|
12502
|
+
Vitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related to your test files.`
|
|
12503
|
+
));
|
|
12504
|
+
this.log(c.red(divider(c.bold(c.inverse(" Source Errors ")))));
|
|
12505
|
+
this.log(errorMessage);
|
|
12506
|
+
await Promise.all(errors.map(async (err) => {
|
|
12507
|
+
await this.printError(err, true);
|
|
12508
|
+
}));
|
|
12509
|
+
this.log(c.red(divider()));
|
|
12510
|
+
}
|
|
12684
12511
|
}
|
|
12685
|
-
|
|
12686
|
-
|
|
12687
|
-
|
|
12688
|
-
|
|
12512
|
+
|
|
12513
|
+
function CoverageTransform(ctx) {
|
|
12514
|
+
return {
|
|
12515
|
+
name: "vitest:coverage-transform",
|
|
12516
|
+
transform(srcCode, id) {
|
|
12517
|
+
var _a, _b;
|
|
12518
|
+
return (_b = (_a = ctx.coverageProvider) == null ? void 0 : _a.onFileTransform) == null ? void 0 : _b.call(_a, srcCode, normalizeRequestId(id), this);
|
|
12689
12519
|
}
|
|
12690
|
-
|
|
12520
|
+
};
|
|
12691
12521
|
}
|
|
12692
|
-
|
|
12693
|
-
|
|
12694
|
-
|
|
12695
|
-
|
|
12696
|
-
|
|
12522
|
+
|
|
12523
|
+
const API_NOT_FOUND_ERROR = `There are some problems in resolving the mocks API.
|
|
12524
|
+
You may encounter this issue when importing the mocks API from another module other than 'vitest'.
|
|
12525
|
+
To fix this issue you can either:
|
|
12526
|
+
- import the mocks API directly from 'vitest'
|
|
12527
|
+
- enable the 'globals' options`;
|
|
12528
|
+
const API_NOT_FOUND_CHECK = `
|
|
12529
|
+
if (typeof globalThis.vi === "undefined" && typeof globalThis.vitest === "undefined") { throw new Error(${JSON.stringify(API_NOT_FOUND_ERROR)}) }
|
|
12530
|
+
`;
|
|
12531
|
+
function isIdentifier(node) {
|
|
12532
|
+
return node.type === "Identifier";
|
|
12533
|
+
}
|
|
12534
|
+
function transformImportSpecifiers(node) {
|
|
12535
|
+
const specifiers = node.specifiers;
|
|
12536
|
+
if (specifiers.length === 1 && specifiers[0].type === "ImportNamespaceSpecifier")
|
|
12537
|
+
return specifiers[0].local.name;
|
|
12538
|
+
const dynamicImports = node.specifiers.map((specifier) => {
|
|
12539
|
+
if (specifier.type === "ImportDefaultSpecifier")
|
|
12540
|
+
return `default: ${specifier.local.name}`;
|
|
12541
|
+
if (specifier.type === "ImportSpecifier") {
|
|
12542
|
+
const local = specifier.local.name;
|
|
12543
|
+
const imported = specifier.imported.name;
|
|
12544
|
+
if (local === imported)
|
|
12545
|
+
return local;
|
|
12546
|
+
return `${imported}: ${local}`;
|
|
12697
12547
|
}
|
|
12698
|
-
return
|
|
12699
|
-
}
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
return line.sort(sortComparator);
|
|
12704
|
-
}
|
|
12705
|
-
function sortComparator(a, b) {
|
|
12706
|
-
return a[COLUMN] - b[COLUMN];
|
|
12548
|
+
return null;
|
|
12549
|
+
}).filter(Boolean).join(", ");
|
|
12550
|
+
if (!dynamicImports.length)
|
|
12551
|
+
return "";
|
|
12552
|
+
return `{ ${dynamicImports} }`;
|
|
12707
12553
|
}
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12554
|
+
const regexpHoistable = /^[ \t]*\b(vi|vitest)\s*\.\s*(mock|unmock|hoisted)\(/m;
|
|
12555
|
+
const hashbangRE = /^#!.*\n/;
|
|
12556
|
+
function hoistMocks(code, id, parse) {
|
|
12557
|
+
var _a;
|
|
12558
|
+
const hasMocks = regexpHoistable.test(code);
|
|
12559
|
+
if (!hasMocks)
|
|
12560
|
+
return;
|
|
12561
|
+
const s = new MagicString(code);
|
|
12562
|
+
let ast;
|
|
12563
|
+
try {
|
|
12564
|
+
ast = parse(code, {
|
|
12565
|
+
sourceType: "module",
|
|
12566
|
+
ecmaVersion: "latest",
|
|
12567
|
+
locations: true
|
|
12568
|
+
});
|
|
12569
|
+
} catch (err) {
|
|
12570
|
+
console.error(`Cannot parse ${id}:
|
|
12571
|
+
${err.message}`);
|
|
12572
|
+
return;
|
|
12573
|
+
}
|
|
12574
|
+
const hoistIndex = ((_a = code.match(hashbangRE)) == null ? void 0 : _a[0].length) ?? 0;
|
|
12575
|
+
let hoistedCode = "";
|
|
12576
|
+
let hoistedVitestImports = "";
|
|
12577
|
+
const transformImportDeclaration = (node) => {
|
|
12578
|
+
const source = node.source.value;
|
|
12579
|
+
const specifiers = transformImportSpecifiers(node);
|
|
12580
|
+
const code2 = specifiers ? `const ${specifiers} = await import('${source}')
|
|
12581
|
+
` : `await import('${source}')
|
|
12582
|
+
`;
|
|
12583
|
+
return code2;
|
|
12584
|
+
};
|
|
12585
|
+
function hoistImport(node) {
|
|
12586
|
+
s.remove(node.start, node.end);
|
|
12587
|
+
if (node.source.value === "vitest") {
|
|
12588
|
+
const code3 = `const ${transformImportSpecifiers(node)} = await import('vitest')
|
|
12589
|
+
`;
|
|
12590
|
+
hoistedVitestImports += code3;
|
|
12591
|
+
return;
|
|
12592
|
+
}
|
|
12593
|
+
const code2 = transformImportDeclaration(node);
|
|
12594
|
+
s.appendLeft(hoistIndex, code2);
|
|
12595
|
+
}
|
|
12596
|
+
for (const node of ast.body) {
|
|
12597
|
+
if (node.type === "ImportDeclaration")
|
|
12598
|
+
hoistImport(node);
|
|
12599
|
+
}
|
|
12600
|
+
simple(ast, {
|
|
12601
|
+
CallExpression(_node) {
|
|
12602
|
+
var _a2, _b;
|
|
12603
|
+
const node = _node;
|
|
12604
|
+
if (node.callee.type === "MemberExpression" && isIdentifier(node.callee.object) && (node.callee.object.name === "vi" || node.callee.object.name === "vitest") && isIdentifier(node.callee.property)) {
|
|
12605
|
+
const methodName = node.callee.property.name;
|
|
12606
|
+
if (methodName === "mock" || methodName === "unmock") {
|
|
12607
|
+
hoistedCode += `${code.slice(node.start, node.end)}
|
|
12608
|
+
`;
|
|
12609
|
+
s.remove(node.start, node.end);
|
|
12736
12610
|
}
|
|
12737
|
-
|
|
12738
|
-
|
|
12611
|
+
if (methodName === "hoisted") {
|
|
12612
|
+
const declarationNode = (_a2 = findNodeAround(ast, node.start, "VariableDeclaration")) == null ? void 0 : _a2.node;
|
|
12613
|
+
const init = (_b = declarationNode == null ? void 0 : declarationNode.declarations[0]) == null ? void 0 : _b.init;
|
|
12614
|
+
const isViHoisted = (node2) => {
|
|
12615
|
+
return node2.callee.type === "MemberExpression" && isIdentifier(node2.callee.object) && (node2.callee.object.name === "vi" || node2.callee.object.name === "vitest") && isIdentifier(node2.callee.property) && node2.callee.property.name === "hoisted";
|
|
12616
|
+
};
|
|
12617
|
+
const canMoveDeclaration = init && init.type === "CallExpression" && isViHoisted(init) || init && init.type === "AwaitExpression" && init.argument.type === "CallExpression" && isViHoisted(init.argument);
|
|
12618
|
+
if (canMoveDeclaration) {
|
|
12619
|
+
hoistedCode += `${code.slice(declarationNode.start, declarationNode.end)}
|
|
12620
|
+
`;
|
|
12621
|
+
s.remove(declarationNode.start, declarationNode.end);
|
|
12622
|
+
} else {
|
|
12623
|
+
hoistedCode += `${code.slice(node.start, node.end)}
|
|
12624
|
+
`;
|
|
12625
|
+
s.remove(node.start, node.end);
|
|
12626
|
+
}
|
|
12739
12627
|
}
|
|
12628
|
+
}
|
|
12740
12629
|
}
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12630
|
+
});
|
|
12631
|
+
if (hoistedCode || hoistedVitestImports) {
|
|
12632
|
+
s.prepend(
|
|
12633
|
+
hoistedVitestImports + (!hoistedVitestImports && hoistedCode ? API_NOT_FOUND_CHECK : "") + hoistedCode
|
|
12634
|
+
);
|
|
12635
|
+
}
|
|
12636
|
+
return {
|
|
12637
|
+
ast,
|
|
12638
|
+
code: s.toString(),
|
|
12639
|
+
map: s.generateMap({ hires: true, source: id })
|
|
12640
|
+
};
|
|
12750
12641
|
}
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12642
|
+
|
|
12643
|
+
function MocksPlugin() {
|
|
12644
|
+
return {
|
|
12645
|
+
name: "vite:mocks",
|
|
12646
|
+
enforce: "post",
|
|
12647
|
+
transform(code, id) {
|
|
12648
|
+
return hoistMocks(code, id, this.parse);
|
|
12755
12649
|
}
|
|
12756
|
-
|
|
12757
|
-
}
|
|
12758
|
-
function memoizedState() {
|
|
12759
|
-
return {
|
|
12760
|
-
lastKey: -1,
|
|
12761
|
-
lastNeedle: -1,
|
|
12762
|
-
lastIndex: -1,
|
|
12763
|
-
};
|
|
12650
|
+
};
|
|
12764
12651
|
}
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12652
|
+
|
|
12653
|
+
async function createBrowserServer(project, options) {
|
|
12654
|
+
const root = project.config.root;
|
|
12655
|
+
await ensurePackageInstalled("@vitest/browser", root);
|
|
12656
|
+
const configPath = options.config === false ? false : options.config ? resolve$2(root, options.config) : await findUp(configFiles, { cwd: root });
|
|
12657
|
+
const server = await createServer({
|
|
12658
|
+
logLevel: "error",
|
|
12659
|
+
mode: project.config.mode,
|
|
12660
|
+
configFile: configPath,
|
|
12661
|
+
// watch is handled by Vitest
|
|
12662
|
+
server: {
|
|
12663
|
+
hmr: false,
|
|
12664
|
+
watch: {
|
|
12665
|
+
ignored: ["**/**"]
|
|
12666
|
+
}
|
|
12667
|
+
},
|
|
12668
|
+
plugins: [
|
|
12669
|
+
(await import('@vitest/browser')).default(project, "/"),
|
|
12670
|
+
CoverageTransform(project.ctx),
|
|
12671
|
+
{
|
|
12672
|
+
enforce: "post",
|
|
12673
|
+
name: "vitest:browser:config",
|
|
12674
|
+
async config(config) {
|
|
12675
|
+
var _a, _b, _c;
|
|
12676
|
+
const server2 = resolveApiServerConfig(((_a = config.test) == null ? void 0 : _a.browser) || {}) || {
|
|
12677
|
+
port: defaultBrowserPort
|
|
12678
|
+
};
|
|
12679
|
+
config.server = server2;
|
|
12680
|
+
(_b = config.server).fs ?? (_b.fs = {});
|
|
12681
|
+
config.server.fs.strict = false;
|
|
12682
|
+
return {
|
|
12683
|
+
resolve: {
|
|
12684
|
+
alias: (_c = config.test) == null ? void 0 : _c.alias
|
|
12685
|
+
}
|
|
12686
|
+
};
|
|
12784
12687
|
}
|
|
12785
|
-
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12688
|
+
},
|
|
12689
|
+
MocksPlugin()
|
|
12690
|
+
]
|
|
12691
|
+
});
|
|
12692
|
+
await server.listen();
|
|
12693
|
+
await server.watcher.close();
|
|
12694
|
+
(await import('./chunk-api-setup.df3106cd.js')).setup(project, server);
|
|
12695
|
+
return server;
|
|
12789
12696
|
}
|
|
12790
|
-
|
|
12791
|
-
const
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12801
|
-
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
|
|
12807
|
-
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12811
|
-
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
|
|
12817
|
-
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
12822
|
-
|
|
12823
|
-
|
|
12824
|
-
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
}
|
|
12697
|
+
|
|
12698
|
+
const playwrightBrowsers = ["firefox", "webkit", "chromium"];
|
|
12699
|
+
class PlaywrightBrowserProvider {
|
|
12700
|
+
constructor() {
|
|
12701
|
+
this.name = "playwright";
|
|
12702
|
+
this.cachedBrowser = null;
|
|
12703
|
+
}
|
|
12704
|
+
getSupportedBrowsers() {
|
|
12705
|
+
return playwrightBrowsers;
|
|
12706
|
+
}
|
|
12707
|
+
async initialize(ctx, { browser }) {
|
|
12708
|
+
this.ctx = ctx;
|
|
12709
|
+
this.browser = browser;
|
|
12710
|
+
const root = this.ctx.config.root;
|
|
12711
|
+
if (!await ensurePackageInstalled("playwright", root))
|
|
12712
|
+
throw new Error('Cannot find "playwright" package. Please install it manually.');
|
|
12713
|
+
}
|
|
12714
|
+
async openBrowser() {
|
|
12715
|
+
if (this.cachedBrowser)
|
|
12716
|
+
return this.cachedBrowser;
|
|
12717
|
+
const options = this.ctx.config.browser;
|
|
12718
|
+
const playwright = await import('playwright');
|
|
12719
|
+
const playwrightInstance = await playwright[this.browser].launch({ headless: options.headless });
|
|
12720
|
+
this.cachedBrowser = await playwrightInstance.newPage();
|
|
12721
|
+
this.cachedBrowser.on("close", () => {
|
|
12722
|
+
playwrightInstance.close();
|
|
12723
|
+
});
|
|
12724
|
+
return this.cachedBrowser;
|
|
12725
|
+
}
|
|
12726
|
+
async openPage(url) {
|
|
12727
|
+
const browserInstance = await this.openBrowser();
|
|
12728
|
+
await browserInstance.goto(url);
|
|
12729
|
+
}
|
|
12730
|
+
async close() {
|
|
12731
|
+
var _a;
|
|
12732
|
+
await ((_a = this.cachedBrowser) == null ? void 0 : _a.close());
|
|
12733
|
+
process.exit();
|
|
12734
|
+
}
|
|
12829
12735
|
}
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
// mapping (like a "//# sourceMappingURL=") at the end of the child file.
|
|
12838
|
-
if (line >= decoded.length)
|
|
12839
|
-
return null;
|
|
12840
|
-
const segments = decoded[line];
|
|
12841
|
-
const index = traceSegmentInternal(segments, map._decodedMemo, line, column, GREATEST_LOWER_BOUND);
|
|
12842
|
-
return index === -1 ? null : segments[index];
|
|
12736
|
+
|
|
12737
|
+
const webdriverBrowsers = ["firefox", "chrome", "edge", "safari"];
|
|
12738
|
+
class WebdriverBrowserProvider {
|
|
12739
|
+
constructor() {
|
|
12740
|
+
this.name = "webdriverio";
|
|
12741
|
+
this.cachedBrowser = null;
|
|
12742
|
+
this.stopSafari = () => {
|
|
12843
12743
|
};
|
|
12844
|
-
}
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12744
|
+
}
|
|
12745
|
+
getSupportedBrowsers() {
|
|
12746
|
+
return webdriverBrowsers;
|
|
12747
|
+
}
|
|
12748
|
+
async initialize(ctx, { browser }) {
|
|
12749
|
+
this.ctx = ctx;
|
|
12750
|
+
this.browser = browser;
|
|
12751
|
+
const root = this.ctx.config.root;
|
|
12752
|
+
if (!await ensurePackageInstalled("webdriverio", root))
|
|
12753
|
+
throw new Error('Cannot find "webdriverio" package. Please install it manually.');
|
|
12754
|
+
if (browser === "safari" && !await ensurePackageInstalled("safaridriver", root))
|
|
12755
|
+
throw new Error('Cannot find "safaridriver" package. Please install it manually.');
|
|
12756
|
+
}
|
|
12757
|
+
async openBrowser() {
|
|
12758
|
+
if (this.cachedBrowser)
|
|
12759
|
+
return this.cachedBrowser;
|
|
12760
|
+
const options = this.ctx.config.browser;
|
|
12761
|
+
if (this.browser === "safari") {
|
|
12762
|
+
const safaridriver = await import('safaridriver');
|
|
12763
|
+
safaridriver.start({ diagnose: true });
|
|
12764
|
+
this.stopSafari = () => safaridriver.stop();
|
|
12765
|
+
process.on("beforeExit", () => {
|
|
12766
|
+
safaridriver.stop();
|
|
12767
|
+
});
|
|
12849
12768
|
}
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12769
|
+
const { remote } = await import('webdriverio');
|
|
12770
|
+
this.cachedBrowser = await remote({
|
|
12771
|
+
logLevel: "error",
|
|
12772
|
+
capabilities: {
|
|
12773
|
+
"browserName": this.browser,
|
|
12774
|
+
"wdio:devtoolsOptions": { headless: options.headless }
|
|
12775
|
+
}
|
|
12776
|
+
});
|
|
12777
|
+
return this.cachedBrowser;
|
|
12778
|
+
}
|
|
12779
|
+
async openPage(url) {
|
|
12780
|
+
const browserInstance = await this.openBrowser();
|
|
12781
|
+
await browserInstance.url(url);
|
|
12782
|
+
}
|
|
12783
|
+
async close() {
|
|
12784
|
+
var _a, _b, _c;
|
|
12785
|
+
await Promise.all([
|
|
12786
|
+
this.stopSafari(),
|
|
12787
|
+
((_a = this.cachedBrowser) == null ? void 0 : _a.sessionId) ? (_c = (_b = this.cachedBrowser) == null ? void 0 : _b.deleteSession) == null ? void 0 : _c.call(_b) : null
|
|
12788
|
+
]);
|
|
12789
|
+
process.exit();
|
|
12790
|
+
}
|
|
12855
12791
|
}
|
|
12856
12792
|
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
let
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
class SetArray {
|
|
12875
|
-
constructor() {
|
|
12876
|
-
this._indexes = { __proto__: null };
|
|
12877
|
-
this.array = [];
|
|
12878
|
-
}
|
|
12793
|
+
async function getBrowserProvider(options, loader) {
|
|
12794
|
+
switch (options.provider) {
|
|
12795
|
+
case void 0:
|
|
12796
|
+
case "webdriverio":
|
|
12797
|
+
return WebdriverBrowserProvider;
|
|
12798
|
+
case "playwright":
|
|
12799
|
+
return PlaywrightBrowserProvider;
|
|
12800
|
+
}
|
|
12801
|
+
let customProviderModule;
|
|
12802
|
+
try {
|
|
12803
|
+
customProviderModule = await loader.executeId(options.provider);
|
|
12804
|
+
} catch (error) {
|
|
12805
|
+
throw new Error(`Failed to load custom BrowserProvider from ${options.provider}`, { cause: error });
|
|
12806
|
+
}
|
|
12807
|
+
if (customProviderModule.default == null)
|
|
12808
|
+
throw new Error(`Custom BrowserProvider loaded from ${options.provider} was not the default export`);
|
|
12809
|
+
return customProviderModule.default;
|
|
12879
12810
|
}
|
|
12880
|
-
(() => {
|
|
12881
|
-
get = (strarr, key) => strarr._indexes[key];
|
|
12882
|
-
put = (strarr, key) => {
|
|
12883
|
-
// The key may or may not be present. If it is present, it's a number.
|
|
12884
|
-
const index = get(strarr, key);
|
|
12885
|
-
if (index !== undefined)
|
|
12886
|
-
return index;
|
|
12887
|
-
const { array, _indexes: indexes } = strarr;
|
|
12888
|
-
return (indexes[key] = array.push(key) - 1);
|
|
12889
|
-
};
|
|
12890
|
-
})();
|
|
12891
12811
|
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
* column here are 0-based, unlike `addMapping`.
|
|
12895
|
-
*/
|
|
12896
|
-
let addSegment;
|
|
12897
|
-
/**
|
|
12898
|
-
* Adds/removes the content of the source file to the source map.
|
|
12899
|
-
*/
|
|
12900
|
-
let setSourceContent;
|
|
12901
|
-
/**
|
|
12902
|
-
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
|
|
12903
|
-
* a sourcemap, or to JSON.stringify.
|
|
12904
|
-
*/
|
|
12905
|
-
let decodedMap;
|
|
12906
|
-
/**
|
|
12907
|
-
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
|
|
12908
|
-
* a sourcemap, or to JSON.stringify.
|
|
12909
|
-
*/
|
|
12910
|
-
let encodedMap;
|
|
12911
|
-
/**
|
|
12912
|
-
* Provides the state to generate a sourcemap.
|
|
12913
|
-
*/
|
|
12914
|
-
class GenMapping {
|
|
12915
|
-
constructor({ file, sourceRoot } = {}) {
|
|
12916
|
-
this._names = new SetArray();
|
|
12917
|
-
this._sources = new SetArray();
|
|
12918
|
-
this._sourcesContent = [];
|
|
12919
|
-
this._mappings = [];
|
|
12920
|
-
this.file = file;
|
|
12921
|
-
this.sourceRoot = sourceRoot;
|
|
12922
|
-
}
|
|
12923
|
-
}
|
|
12924
|
-
(() => {
|
|
12925
|
-
addSegment = (map, genLine, genColumn, source, sourceLine, sourceColumn, name) => {
|
|
12926
|
-
const { _mappings: mappings, _sources: sources, _sourcesContent: sourcesContent, _names: names, } = map;
|
|
12927
|
-
const line = getLine(mappings, genLine);
|
|
12928
|
-
if (source == null) {
|
|
12929
|
-
const seg = [genColumn];
|
|
12930
|
-
const index = getColumnIndex(line, genColumn, seg);
|
|
12931
|
-
return insert(line, index, seg);
|
|
12932
|
-
}
|
|
12933
|
-
const sourcesIndex = put(sources, source);
|
|
12934
|
-
const seg = name
|
|
12935
|
-
? [genColumn, sourcesIndex, sourceLine, sourceColumn, put(names, name)]
|
|
12936
|
-
: [genColumn, sourcesIndex, sourceLine, sourceColumn];
|
|
12937
|
-
const index = getColumnIndex(line, genColumn, seg);
|
|
12938
|
-
if (sourcesIndex === sourcesContent.length)
|
|
12939
|
-
sourcesContent[sourcesIndex] = null;
|
|
12940
|
-
insert(line, index, seg);
|
|
12941
|
-
};
|
|
12942
|
-
setSourceContent = (map, source, content) => {
|
|
12943
|
-
const { _sources: sources, _sourcesContent: sourcesContent } = map;
|
|
12944
|
-
sourcesContent[put(sources, source)] = content;
|
|
12945
|
-
};
|
|
12946
|
-
decodedMap = (map) => {
|
|
12947
|
-
const { file, sourceRoot, _mappings: mappings, _sources: sources, _sourcesContent: sourcesContent, _names: names, } = map;
|
|
12948
|
-
return {
|
|
12949
|
-
version: 3,
|
|
12950
|
-
file,
|
|
12951
|
-
names: names.array,
|
|
12952
|
-
sourceRoot: sourceRoot || undefined,
|
|
12953
|
-
sources: sources.array,
|
|
12954
|
-
sourcesContent,
|
|
12955
|
-
mappings,
|
|
12956
|
-
};
|
|
12957
|
-
};
|
|
12958
|
-
encodedMap = (map) => {
|
|
12959
|
-
const decoded = decodedMap(map);
|
|
12960
|
-
return Object.assign(Object.assign({}, decoded), { mappings: encode(decoded.mappings) });
|
|
12961
|
-
};
|
|
12962
|
-
})();
|
|
12963
|
-
function getLine(mappings, index) {
|
|
12964
|
-
for (let i = mappings.length; i <= index; i++) {
|
|
12965
|
-
mappings[i] = [];
|
|
12966
|
-
}
|
|
12967
|
-
return mappings[index];
|
|
12968
|
-
}
|
|
12969
|
-
function getColumnIndex(line, column, seg) {
|
|
12970
|
-
let index = line.length;
|
|
12971
|
-
for (let i = index - 1; i >= 0; i--, index--) {
|
|
12972
|
-
const current = line[i];
|
|
12973
|
-
const col = current[0];
|
|
12974
|
-
if (col > column)
|
|
12975
|
-
continue;
|
|
12976
|
-
if (col < column)
|
|
12977
|
-
break;
|
|
12978
|
-
const cmp = compare(current, seg);
|
|
12979
|
-
if (cmp === 0)
|
|
12980
|
-
return index;
|
|
12981
|
-
if (cmp < 0)
|
|
12982
|
-
break;
|
|
12983
|
-
}
|
|
12984
|
-
return index;
|
|
12985
|
-
}
|
|
12986
|
-
function compare(a, b) {
|
|
12987
|
-
let cmp = compareNum(a.length, b.length);
|
|
12988
|
-
if (cmp !== 0)
|
|
12989
|
-
return cmp;
|
|
12990
|
-
// We've already checked genColumn
|
|
12991
|
-
if (a.length === 1)
|
|
12992
|
-
return 0;
|
|
12993
|
-
cmp = compareNum(a[1], b[1]);
|
|
12994
|
-
if (cmp !== 0)
|
|
12995
|
-
return cmp;
|
|
12996
|
-
cmp = compareNum(a[2], b[2]);
|
|
12997
|
-
if (cmp !== 0)
|
|
12998
|
-
return cmp;
|
|
12999
|
-
cmp = compareNum(a[3], b[3]);
|
|
13000
|
-
if (cmp !== 0)
|
|
13001
|
-
return cmp;
|
|
13002
|
-
if (a.length === 4)
|
|
13003
|
-
return 0;
|
|
13004
|
-
return compareNum(a[4], b[4]);
|
|
13005
|
-
}
|
|
13006
|
-
function compareNum(a, b) {
|
|
13007
|
-
return a - b;
|
|
12812
|
+
function generateCssFilenameHash(filepath) {
|
|
12813
|
+
return createHash("md5").update(filepath).digest("hex").slice(0, 6);
|
|
13008
12814
|
}
|
|
13009
|
-
function
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
|
|
13015
|
-
|
|
12815
|
+
function generateScopedClassName(strategy, name, filename) {
|
|
12816
|
+
if (strategy === "scoped")
|
|
12817
|
+
return null;
|
|
12818
|
+
if (strategy === "non-scoped")
|
|
12819
|
+
return name;
|
|
12820
|
+
const hash = generateCssFilenameHash(filename);
|
|
12821
|
+
return `_${name}_${hash}`;
|
|
13016
12822
|
}
|
|
13017
12823
|
|
|
13018
|
-
const
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
content: null,
|
|
13024
|
-
};
|
|
13025
|
-
const EMPTY_SOURCES = [];
|
|
13026
|
-
function Source(map, sources, source, content) {
|
|
13027
|
-
return {
|
|
13028
|
-
map,
|
|
13029
|
-
sources,
|
|
13030
|
-
source,
|
|
13031
|
-
content,
|
|
13032
|
-
};
|
|
13033
|
-
}
|
|
13034
|
-
/**
|
|
13035
|
-
* MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes
|
|
13036
|
-
* (which may themselves be SourceMapTrees).
|
|
13037
|
-
*/
|
|
13038
|
-
function MapSource(map, sources) {
|
|
13039
|
-
return Source(map, sources, '', null);
|
|
13040
|
-
}
|
|
13041
|
-
/**
|
|
13042
|
-
* A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive
|
|
13043
|
-
* segment tracing ends at the `OriginalSource`.
|
|
13044
|
-
*/
|
|
13045
|
-
function OriginalSource(source, content) {
|
|
13046
|
-
return Source(null, EMPTY_SOURCES, source, content);
|
|
13047
|
-
}
|
|
13048
|
-
/**
|
|
13049
|
-
* traceMappings is only called on the root level SourceMapTree, and begins the process of
|
|
13050
|
-
* resolving each mapping in terms of the original source files.
|
|
13051
|
-
*/
|
|
13052
|
-
function traceMappings(tree) {
|
|
13053
|
-
const gen = new GenMapping({ file: tree.map.file });
|
|
13054
|
-
const { sources: rootSources, map } = tree;
|
|
13055
|
-
const rootNames = map.names;
|
|
13056
|
-
const rootMappings = decodedMappings(map);
|
|
13057
|
-
for (let i = 0; i < rootMappings.length; i++) {
|
|
13058
|
-
const segments = rootMappings[i];
|
|
13059
|
-
let lastSource = null;
|
|
13060
|
-
let lastSourceLine = null;
|
|
13061
|
-
let lastSourceColumn = null;
|
|
13062
|
-
for (let j = 0; j < segments.length; j++) {
|
|
13063
|
-
const segment = segments[j];
|
|
13064
|
-
const genCol = segment[0];
|
|
13065
|
-
let traced = SOURCELESS_MAPPING;
|
|
13066
|
-
// 1-length segments only move the current generated column, there's no source information
|
|
13067
|
-
// to gather from it.
|
|
13068
|
-
if (segment.length !== 1) {
|
|
13069
|
-
const source = rootSources[segment[1]];
|
|
13070
|
-
traced = originalPositionFor(source, segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : '');
|
|
13071
|
-
// If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
|
|
13072
|
-
// respective segment into an original source.
|
|
13073
|
-
if (traced == null)
|
|
13074
|
-
continue;
|
|
13075
|
-
}
|
|
13076
|
-
// So we traced a segment down into its original source file. Now push a
|
|
13077
|
-
// new segment pointing to this location.
|
|
13078
|
-
const { column, line, name, content, source } = traced;
|
|
13079
|
-
if (line === lastSourceLine && column === lastSourceColumn && source === lastSource) {
|
|
13080
|
-
continue;
|
|
13081
|
-
}
|
|
13082
|
-
lastSourceLine = line;
|
|
13083
|
-
lastSourceColumn = column;
|
|
13084
|
-
lastSource = source;
|
|
13085
|
-
// Sigh, TypeScript can't figure out source/line/column are either all null, or all non-null...
|
|
13086
|
-
addSegment(gen, i, genCol, source, line, column, name);
|
|
13087
|
-
if (content != null)
|
|
13088
|
-
setSourceContent(gen, source, content);
|
|
13089
|
-
}
|
|
13090
|
-
}
|
|
13091
|
-
return gen;
|
|
13092
|
-
}
|
|
13093
|
-
/**
|
|
13094
|
-
* originalPositionFor is only called on children SourceMapTrees. It recurses down into its own
|
|
13095
|
-
* child SourceMapTrees, until we find the original source map.
|
|
13096
|
-
*/
|
|
13097
|
-
function originalPositionFor(source, line, column, name) {
|
|
13098
|
-
if (!source.map) {
|
|
13099
|
-
return { column, line, name, source: source.source, content: source.content };
|
|
13100
|
-
}
|
|
13101
|
-
const segment = traceSegment(source.map, line, column);
|
|
13102
|
-
// If we couldn't find a segment, then this doesn't exist in the sourcemap.
|
|
13103
|
-
if (segment == null)
|
|
13104
|
-
return null;
|
|
13105
|
-
// 1-length segments only move the current generated column, there's no source information
|
|
13106
|
-
// to gather from it.
|
|
13107
|
-
if (segment.length === 1)
|
|
13108
|
-
return SOURCELESS_MAPPING;
|
|
13109
|
-
return originalPositionFor(source.sources[segment[1]], segment[2], segment[3], segment.length === 5 ? source.map.names[segment[4]] : name);
|
|
12824
|
+
const cssLangs = "\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)";
|
|
12825
|
+
const cssLangRE = new RegExp(cssLangs);
|
|
12826
|
+
const cssModuleRE = new RegExp(`\\.module${cssLangs}`);
|
|
12827
|
+
function isCSS(id) {
|
|
12828
|
+
return cssLangRE.test(id);
|
|
13110
12829
|
}
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
if (Array.isArray(value))
|
|
13114
|
-
return value;
|
|
13115
|
-
return [value];
|
|
12830
|
+
function isCSSModule(id) {
|
|
12831
|
+
return cssModuleRE.test(id);
|
|
13116
12832
|
}
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
* Every sourcemap is composed of a collection of source files and mappings
|
|
13123
|
-
* into locations of those source files. When we generate a `SourceMapTree` for
|
|
13124
|
-
* the sourcemap, we attempt to load each source file's own sourcemap. If it
|
|
13125
|
-
* does not have an associated sourcemap, it is considered an original,
|
|
13126
|
-
* unmodified source file.
|
|
13127
|
-
*/
|
|
13128
|
-
function buildSourceMapTree(input, loader) {
|
|
13129
|
-
const maps = asArray(input).map((m) => new TraceMap(m, ''));
|
|
13130
|
-
const map = maps.pop();
|
|
13131
|
-
for (let i = 0; i < maps.length; i++) {
|
|
13132
|
-
if (maps[i].sources.length > 1) {
|
|
13133
|
-
throw new Error(`Transformation map ${i} must have exactly one source file.\n` +
|
|
13134
|
-
'Did you specify these with the most recent transformation maps first?');
|
|
13135
|
-
}
|
|
13136
|
-
}
|
|
13137
|
-
let tree = build(map, loader, '', 0);
|
|
13138
|
-
for (let i = maps.length - 1; i >= 0; i--) {
|
|
13139
|
-
tree = MapSource(maps[i], [tree]);
|
|
13140
|
-
}
|
|
13141
|
-
return tree;
|
|
13142
|
-
}
|
|
13143
|
-
function build(map, loader, importer, importerDepth) {
|
|
13144
|
-
const { resolvedSources, sourcesContent } = map;
|
|
13145
|
-
const depth = importerDepth + 1;
|
|
13146
|
-
const children = resolvedSources.map((sourceFile, i) => {
|
|
13147
|
-
// The loading context gives the loader more information about why this file is being loaded
|
|
13148
|
-
// (eg, from which importer). It also allows the loader to override the location of the loaded
|
|
13149
|
-
// sourcemap/original source, or to override the content in the sourcesContent field if it's
|
|
13150
|
-
// an unmodified source file.
|
|
13151
|
-
const ctx = {
|
|
13152
|
-
importer,
|
|
13153
|
-
depth,
|
|
13154
|
-
source: sourceFile || '',
|
|
13155
|
-
content: undefined,
|
|
13156
|
-
};
|
|
13157
|
-
// Use the provided loader callback to retrieve the file's sourcemap.
|
|
13158
|
-
// TODO: We should eventually support async loading of sourcemap files.
|
|
13159
|
-
const sourceMap = loader(ctx.source, ctx);
|
|
13160
|
-
const { source, content } = ctx;
|
|
13161
|
-
// If there is a sourcemap, then we need to recurse into it to load its source files.
|
|
13162
|
-
if (sourceMap)
|
|
13163
|
-
return build(new TraceMap(sourceMap, source), loader, source, depth);
|
|
13164
|
-
// Else, it's an an unmodified source file.
|
|
13165
|
-
// The contents of this unmodified source file can be overridden via the loader context,
|
|
13166
|
-
// allowing it to be explicitly null or a string. If it remains undefined, we fall back to
|
|
13167
|
-
// the importing sourcemap's `sourcesContent` field.
|
|
13168
|
-
const sourceContent = content !== undefined ? content : sourcesContent ? sourcesContent[i] : null;
|
|
13169
|
-
return OriginalSource(source, sourceContent);
|
|
13170
|
-
});
|
|
13171
|
-
return MapSource(map, children);
|
|
12833
|
+
function getCSSModuleProxyReturn(strategy, filename) {
|
|
12834
|
+
if (strategy === "non-scoped")
|
|
12835
|
+
return "style";
|
|
12836
|
+
const hash = generateCssFilenameHash(filename);
|
|
12837
|
+
return `\`_\${style}_${hash}\``;
|
|
13172
12838
|
}
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
|
|
12839
|
+
function CSSEnablerPlugin(ctx) {
|
|
12840
|
+
const shouldProcessCSS = (id) => {
|
|
12841
|
+
const { css } = ctx.config;
|
|
12842
|
+
if (typeof css === "boolean")
|
|
12843
|
+
return css;
|
|
12844
|
+
if (toArray(css.exclude).some((re) => re.test(id)))
|
|
12845
|
+
return false;
|
|
12846
|
+
if (toArray(css.include).some((re) => re.test(id)))
|
|
12847
|
+
return true;
|
|
12848
|
+
return false;
|
|
12849
|
+
};
|
|
12850
|
+
return [
|
|
12851
|
+
{
|
|
12852
|
+
name: "vitest:css-disable",
|
|
12853
|
+
enforce: "pre",
|
|
12854
|
+
transform(code, id) {
|
|
12855
|
+
if (!isCSS(id))
|
|
12856
|
+
return;
|
|
12857
|
+
if (!shouldProcessCSS(id))
|
|
12858
|
+
return { code: "" };
|
|
12859
|
+
}
|
|
12860
|
+
},
|
|
12861
|
+
{
|
|
12862
|
+
name: "vitest:css-empty-post",
|
|
12863
|
+
enforce: "post",
|
|
12864
|
+
transform(_, id) {
|
|
12865
|
+
var _a;
|
|
12866
|
+
if (!isCSS(id) || shouldProcessCSS(id))
|
|
12867
|
+
return;
|
|
12868
|
+
if (isCSSModule(id)) {
|
|
12869
|
+
const scopeStrategy = typeof ctx.config.css !== "boolean" && ((_a = ctx.config.css.modules) == null ? void 0 : _a.classNameStrategy) || "stable";
|
|
12870
|
+
const proxyReturn = getCSSModuleProxyReturn(scopeStrategy, relative(ctx.config.root, id));
|
|
12871
|
+
const code = `export default new Proxy(Object.create(null), {
|
|
12872
|
+
get(_, style) {
|
|
12873
|
+
return ${proxyReturn};
|
|
12874
|
+
},
|
|
12875
|
+
})`;
|
|
12876
|
+
return { code };
|
|
13189
12877
|
}
|
|
12878
|
+
return { code: 'export default ""' };
|
|
12879
|
+
}
|
|
13190
12880
|
}
|
|
13191
|
-
|
|
13192
|
-
return JSON.stringify(this);
|
|
13193
|
-
}
|
|
12881
|
+
];
|
|
13194
12882
|
}
|
|
13195
12883
|
|
|
13196
|
-
|
|
13197
|
-
|
|
13198
|
-
|
|
13199
|
-
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
|
|
13203
|
-
|
|
13204
|
-
|
|
13205
|
-
|
|
13206
|
-
|
|
13207
|
-
|
|
13208
|
-
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
|
|
12884
|
+
function EnvReplacerPlugin() {
|
|
12885
|
+
return {
|
|
12886
|
+
name: "vitest:env-replacer",
|
|
12887
|
+
enforce: "pre",
|
|
12888
|
+
transform(code, id) {
|
|
12889
|
+
if (!/\bimport\.meta\.env\b/g.test(code))
|
|
12890
|
+
return null;
|
|
12891
|
+
let s = null;
|
|
12892
|
+
const envs = stripLiteral(code).matchAll(/\bimport\.meta\.env\b/g);
|
|
12893
|
+
for (const env of envs) {
|
|
12894
|
+
s || (s = new MagicString(code));
|
|
12895
|
+
const startIndex = env.index;
|
|
12896
|
+
const endIndex = startIndex + env[0].length;
|
|
12897
|
+
s.overwrite(startIndex, endIndex, "process.env");
|
|
12898
|
+
}
|
|
12899
|
+
if (s) {
|
|
12900
|
+
return {
|
|
12901
|
+
code: s.toString(),
|
|
12902
|
+
map: s.generateMap({
|
|
12903
|
+
hires: true,
|
|
12904
|
+
// Remove possible query parameters, e.g. vue's "?vue&type=script&src=true&lang.ts"
|
|
12905
|
+
source: cleanUrl(id)
|
|
12906
|
+
})
|
|
12907
|
+
};
|
|
12908
|
+
}
|
|
12909
|
+
}
|
|
12910
|
+
};
|
|
13215
12911
|
}
|
|
13216
12912
|
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13224
|
-
function
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
let found = false;
|
|
13232
|
-
for (const match of vitestImports) {
|
|
13233
|
-
const indexStart = match.index;
|
|
13234
|
-
const indexEnd = match[0].length + indexStart;
|
|
13235
|
-
m.remove(indexStart, indexEnd);
|
|
13236
|
-
m.prepend(`${match[0]}
|
|
13237
|
-
`);
|
|
13238
|
-
found = true;
|
|
13239
|
-
}
|
|
13240
|
-
if (!found) {
|
|
13241
|
-
m.prepend(`if (typeof globalThis.vi === "undefined" && typeof globalThis.vitest === "undefined") { throw new Error(${JSON.stringify(API_NOT_FOUND_ERROR)}) }
|
|
13242
|
-
`);
|
|
13243
|
-
}
|
|
12913
|
+
async function loadGlobalSetupFiles(project) {
|
|
12914
|
+
var _a;
|
|
12915
|
+
const server = project.server;
|
|
12916
|
+
const runner = project.runner;
|
|
12917
|
+
const globalSetupFiles = toArray((_a = server.config.test) == null ? void 0 : _a.globalSetup);
|
|
12918
|
+
return Promise.all(globalSetupFiles.map((file) => loadGlobalSetupFile(file, runner)));
|
|
12919
|
+
}
|
|
12920
|
+
async function loadGlobalSetupFile(file, runner) {
|
|
12921
|
+
const m = await runner.executeFile(file);
|
|
12922
|
+
for (const exp of ["default", "setup", "teardown"]) {
|
|
12923
|
+
if (m[exp] != null && typeof m[exp] !== "function")
|
|
12924
|
+
throw new Error(`invalid export in globalSetup file ${file}: ${exp} must be a function`);
|
|
12925
|
+
}
|
|
12926
|
+
if (m.default) {
|
|
13244
12927
|
return {
|
|
13245
|
-
|
|
13246
|
-
|
|
13247
|
-
|
|
13248
|
-
|
|
13249
|
-
|
|
13250
|
-
|
|
13251
|
-
|
|
13252
|
-
|
|
13253
|
-
},
|
|
13254
|
-
mod.map
|
|
13255
|
-
]
|
|
13256
|
-
) : null
|
|
12928
|
+
file,
|
|
12929
|
+
setup: m.default
|
|
12930
|
+
};
|
|
12931
|
+
} else if (m.setup || m.teardown) {
|
|
12932
|
+
return {
|
|
12933
|
+
file,
|
|
12934
|
+
setup: m.setup,
|
|
12935
|
+
teardown: m.teardown
|
|
13257
12936
|
};
|
|
13258
|
-
}
|
|
13259
|
-
return mod;
|
|
13260
|
-
}
|
|
13261
|
-
function hoistCodeMocks(code) {
|
|
13262
|
-
let m;
|
|
13263
|
-
const mocks = code.matchAll(hoistRegexp);
|
|
13264
|
-
for (const mockResult of mocks) {
|
|
13265
|
-
const lastIndex = getMockLastIndex(code.slice(mockResult.index));
|
|
13266
|
-
if (lastIndex === null)
|
|
13267
|
-
continue;
|
|
13268
|
-
const startIndex = mockResult.index;
|
|
13269
|
-
const { insideComment, insideString } = getIndexStatus(code, startIndex);
|
|
13270
|
-
if (insideComment || insideString)
|
|
13271
|
-
continue;
|
|
13272
|
-
const endIndex = startIndex + lastIndex;
|
|
13273
|
-
m ?? (m = new MagicString(code));
|
|
13274
|
-
m.prepend(`${m.slice(startIndex, endIndex)}
|
|
13275
|
-
`);
|
|
13276
|
-
m.remove(startIndex, endIndex);
|
|
13277
|
-
}
|
|
13278
|
-
return m;
|
|
13279
|
-
}
|
|
13280
|
-
function escapeToLinuxLikePath(path) {
|
|
13281
|
-
if (/^[A-Z]:/.test(path))
|
|
13282
|
-
return path.replace(/^([A-Z]):\//, "/windows/$1/");
|
|
13283
|
-
if (/^\/[^/]/.test(path))
|
|
13284
|
-
return `/linux${path}`;
|
|
13285
|
-
return path;
|
|
13286
|
-
}
|
|
13287
|
-
function unescapeToLinuxLikePath(path) {
|
|
13288
|
-
if (path.startsWith("/linux/"))
|
|
13289
|
-
return path.slice("/linux".length);
|
|
13290
|
-
if (path.startsWith("/windows/"))
|
|
13291
|
-
return path.replace(/^\/windows\/([A-Z])\//, "$1:/");
|
|
13292
|
-
return path;
|
|
13293
|
-
}
|
|
13294
|
-
const nullSourceMap = {
|
|
13295
|
-
names: [],
|
|
13296
|
-
sources: [],
|
|
13297
|
-
mappings: "",
|
|
13298
|
-
version: 3
|
|
13299
|
-
};
|
|
13300
|
-
function combineSourcemaps(filename, sourcemapList, excludeContent = true) {
|
|
13301
|
-
if (sourcemapList.length === 0 || sourcemapList.every((m) => m.sources.length === 0))
|
|
13302
|
-
return { ...nullSourceMap };
|
|
13303
|
-
sourcemapList = sourcemapList.map((sourcemap) => {
|
|
13304
|
-
const newSourcemaps = { ...sourcemap };
|
|
13305
|
-
newSourcemaps.sources = sourcemap.sources.map(
|
|
13306
|
-
(source) => source ? escapeToLinuxLikePath(source) : null
|
|
13307
|
-
);
|
|
13308
|
-
if (sourcemap.sourceRoot)
|
|
13309
|
-
newSourcemaps.sourceRoot = escapeToLinuxLikePath(sourcemap.sourceRoot);
|
|
13310
|
-
return newSourcemaps;
|
|
13311
|
-
});
|
|
13312
|
-
const escapedFilename = escapeToLinuxLikePath(filename);
|
|
13313
|
-
let map;
|
|
13314
|
-
let mapIndex = 1;
|
|
13315
|
-
const useArrayInterface = sourcemapList.slice(0, -1).find((m) => m.sources.length !== 1) === void 0;
|
|
13316
|
-
if (useArrayInterface) {
|
|
13317
|
-
map = remapping(sourcemapList, () => null, excludeContent);
|
|
13318
12937
|
} else {
|
|
13319
|
-
|
|
13320
|
-
sourcemapList[0],
|
|
13321
|
-
(sourcefile) => {
|
|
13322
|
-
if (sourcefile === escapedFilename && sourcemapList[mapIndex])
|
|
13323
|
-
return sourcemapList[mapIndex++];
|
|
13324
|
-
else
|
|
13325
|
-
return null;
|
|
13326
|
-
},
|
|
13327
|
-
excludeContent
|
|
13328
|
-
);
|
|
12938
|
+
throw new Error(`invalid globalSetup file ${file}. Must export setup, teardown or have a default export`);
|
|
13329
12939
|
}
|
|
13330
|
-
if (!map.file)
|
|
13331
|
-
delete map.file;
|
|
13332
|
-
map.sources = map.sources.map(
|
|
13333
|
-
(source) => source ? unescapeToLinuxLikePath(source) : source
|
|
13334
|
-
);
|
|
13335
|
-
map.file = filename;
|
|
13336
|
-
return map;
|
|
13337
|
-
}
|
|
13338
|
-
function getMockLastIndex(code) {
|
|
13339
|
-
const index = getCallLastIndex(code);
|
|
13340
|
-
if (index === null)
|
|
13341
|
-
return null;
|
|
13342
|
-
return code[index + 1] === ";" ? index + 2 : index + 1;
|
|
13343
12940
|
}
|
|
13344
|
-
function
|
|
13345
|
-
let
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
}
|
|
13364
|
-
|
|
13365
|
-
|
|
13366
|
-
|
|
13367
|
-
|
|
13368
|
-
if ((char === "\n" || sub === "\r\n") && commentStarted) {
|
|
13369
|
-
commentStarted = false;
|
|
13370
|
-
commentEnded = true;
|
|
12941
|
+
function GlobalSetupPlugin(project, logger) {
|
|
12942
|
+
let globalSetupFiles;
|
|
12943
|
+
return {
|
|
12944
|
+
name: "vitest:global-setup-plugin",
|
|
12945
|
+
enforce: "pre",
|
|
12946
|
+
async buildStart() {
|
|
12947
|
+
var _a, _b;
|
|
12948
|
+
if (!((_a = project.server.config.test) == null ? void 0 : _a.globalSetup))
|
|
12949
|
+
return;
|
|
12950
|
+
globalSetupFiles = await loadGlobalSetupFiles(project);
|
|
12951
|
+
try {
|
|
12952
|
+
for (const globalSetupFile of globalSetupFiles) {
|
|
12953
|
+
const teardown = await ((_b = globalSetupFile.setup) == null ? void 0 : _b.call(globalSetupFile));
|
|
12954
|
+
if (teardown == null || !!globalSetupFile.teardown)
|
|
12955
|
+
continue;
|
|
12956
|
+
if (typeof teardown !== "function")
|
|
12957
|
+
throw new Error(`invalid return value in globalSetup file ${globalSetupFile.file}. Must return a function`);
|
|
12958
|
+
globalSetupFile.teardown = teardown;
|
|
12959
|
+
}
|
|
12960
|
+
} catch (e) {
|
|
12961
|
+
logger.error(`
|
|
12962
|
+
${c.red(divider(c.bold(c.inverse(" Error during global setup "))))}`);
|
|
12963
|
+
await logger.printError(e);
|
|
12964
|
+
process.exit(1);
|
|
13371
12965
|
}
|
|
13372
|
-
}
|
|
13373
|
-
|
|
13374
|
-
|
|
13375
|
-
if (
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
12966
|
+
},
|
|
12967
|
+
async buildEnd() {
|
|
12968
|
+
var _a;
|
|
12969
|
+
if (globalSetupFiles == null ? void 0 : globalSetupFiles.length) {
|
|
12970
|
+
for (const globalSetupFile of globalSetupFiles.reverse()) {
|
|
12971
|
+
try {
|
|
12972
|
+
await ((_a = globalSetupFile.teardown) == null ? void 0 : _a.call(globalSetupFile));
|
|
12973
|
+
} catch (error) {
|
|
12974
|
+
logger.error(`error during global teardown of ${globalSetupFile.file}`, error);
|
|
12975
|
+
}
|
|
12976
|
+
}
|
|
13380
12977
|
}
|
|
13381
12978
|
}
|
|
13382
|
-
beforeChar = char;
|
|
13383
|
-
index++;
|
|
13384
|
-
}
|
|
13385
|
-
return {
|
|
13386
|
-
insideComment: !multilineCommentEnded || !commentEnded,
|
|
13387
|
-
insideString: inString !== null
|
|
13388
12979
|
};
|
|
13389
12980
|
}
|
|
13390
12981
|
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
12982
|
+
function WorkspaceVitestPlugin(project, options) {
|
|
12983
|
+
return [
|
|
12984
|
+
{
|
|
12985
|
+
name: "vitest:project",
|
|
12986
|
+
enforce: "pre",
|
|
12987
|
+
options() {
|
|
12988
|
+
this.meta.watchMode = false;
|
|
12989
|
+
},
|
|
12990
|
+
// TODO: refactor so we don't have the same code here and in plugins/index.ts
|
|
12991
|
+
config(viteConfig) {
|
|
12992
|
+
var _a, _b, _c;
|
|
12993
|
+
if (viteConfig.define) {
|
|
12994
|
+
delete viteConfig.define["import.meta.vitest"];
|
|
12995
|
+
delete viteConfig.define["process.env"];
|
|
12996
|
+
}
|
|
12997
|
+
const env = {};
|
|
12998
|
+
for (const key in viteConfig.define) {
|
|
12999
|
+
const val = viteConfig.define[key];
|
|
13000
|
+
let replacement;
|
|
13001
|
+
try {
|
|
13002
|
+
replacement = typeof val === "string" ? JSON.parse(val) : val;
|
|
13003
|
+
} catch {
|
|
13004
|
+
continue;
|
|
13005
|
+
}
|
|
13006
|
+
if (key.startsWith("import.meta.env.")) {
|
|
13007
|
+
const envKey = key.slice("import.meta.env.".length);
|
|
13008
|
+
env[envKey] = replacement;
|
|
13009
|
+
delete viteConfig.define[key];
|
|
13010
|
+
} else if (key.startsWith("process.env.")) {
|
|
13011
|
+
const envKey = key.slice("process.env.".length);
|
|
13012
|
+
env[envKey] = replacement;
|
|
13013
|
+
delete viteConfig.define[key];
|
|
13014
|
+
}
|
|
13015
|
+
}
|
|
13016
|
+
const testConfig = viteConfig.test || {};
|
|
13017
|
+
const root = testConfig.root || viteConfig.root || options.root;
|
|
13018
|
+
let name = testConfig.name;
|
|
13019
|
+
if (!name) {
|
|
13020
|
+
if (typeof options.workspacePath === "string")
|
|
13021
|
+
name = dirname(options.workspacePath).split("/").pop();
|
|
13022
|
+
else
|
|
13023
|
+
name = options.workspacePath.toString();
|
|
13024
|
+
}
|
|
13025
|
+
const config = {
|
|
13026
|
+
root,
|
|
13027
|
+
resolve: {
|
|
13028
|
+
// by default Vite resolves `module` field, which not always a native ESM module
|
|
13029
|
+
// setting this option can bypass that and fallback to cjs version
|
|
13030
|
+
mainFields: [],
|
|
13031
|
+
alias: testConfig.alias,
|
|
13032
|
+
conditions: ["node"],
|
|
13033
|
+
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
|
|
13034
|
+
// @ts-ignore we support Vite ^3.0, but browserField is available in Vite ^3.2
|
|
13035
|
+
browserField: false
|
|
13036
|
+
},
|
|
13037
|
+
esbuild: {
|
|
13038
|
+
sourcemap: "external",
|
|
13039
|
+
// Enables using ignore hint for coverage providers with @preserve keyword
|
|
13040
|
+
legalComments: "inline"
|
|
13041
|
+
},
|
|
13042
|
+
server: {
|
|
13043
|
+
// disable watch mode in workspaces,
|
|
13044
|
+
// because it is handled by the top-level watcher
|
|
13045
|
+
watch: {
|
|
13046
|
+
ignored: ["**/*"],
|
|
13047
|
+
depth: 0,
|
|
13048
|
+
persistent: false
|
|
13049
|
+
},
|
|
13050
|
+
open: false,
|
|
13051
|
+
hmr: false,
|
|
13052
|
+
preTransformRequests: false
|
|
13053
|
+
},
|
|
13054
|
+
test: {
|
|
13055
|
+
env,
|
|
13056
|
+
name
|
|
13057
|
+
}
|
|
13058
|
+
};
|
|
13059
|
+
const classNameStrategy = typeof testConfig.css !== "boolean" && ((_b = (_a = testConfig.css) == null ? void 0 : _a.modules) == null ? void 0 : _b.classNameStrategy) || "stable";
|
|
13060
|
+
if (classNameStrategy !== "scoped") {
|
|
13061
|
+
config.css ?? (config.css = {});
|
|
13062
|
+
(_c = config.css).modules ?? (_c.modules = {});
|
|
13063
|
+
if (config.css.modules) {
|
|
13064
|
+
config.css.modules.generateScopedName = (name2, filename) => {
|
|
13065
|
+
const root2 = project.config.root;
|
|
13066
|
+
return generateScopedClassName(classNameStrategy, name2, relative(root2, filename));
|
|
13067
|
+
};
|
|
13068
|
+
}
|
|
13069
|
+
}
|
|
13070
|
+
return config;
|
|
13071
|
+
},
|
|
13072
|
+
async configureServer(server) {
|
|
13073
|
+
try {
|
|
13074
|
+
const options2 = deepMerge(
|
|
13075
|
+
{},
|
|
13076
|
+
configDefaults,
|
|
13077
|
+
server.config.test || {}
|
|
13078
|
+
);
|
|
13079
|
+
await project.setServer(options2, server);
|
|
13080
|
+
} catch (err) {
|
|
13081
|
+
await project.ctx.logger.printError(err, true);
|
|
13082
|
+
process.exit(1);
|
|
13083
|
+
}
|
|
13084
|
+
await server.watcher.close();
|
|
13085
|
+
}
|
|
13086
|
+
},
|
|
13087
|
+
EnvReplacerPlugin(),
|
|
13088
|
+
...CSSEnablerPlugin(project),
|
|
13089
|
+
CoverageTransform(project.ctx),
|
|
13090
|
+
GlobalSetupPlugin(project, project.ctx.logger),
|
|
13091
|
+
MocksPlugin()
|
|
13092
|
+
];
|
|
13403
13093
|
}
|
|
13404
13094
|
|
|
13405
13095
|
async function initializeProject(workspacePath, ctx, options) {
|
|
@@ -13454,7 +13144,7 @@ class WorkspaceProject {
|
|
|
13454
13144
|
await Promise.all(files.map(async (file) => {
|
|
13455
13145
|
try {
|
|
13456
13146
|
const code = await promises.readFile(file, "utf-8");
|
|
13457
|
-
if (this.
|
|
13147
|
+
if (this.isInSourceTestFile(code))
|
|
13458
13148
|
testFiles.push(file);
|
|
13459
13149
|
} catch {
|
|
13460
13150
|
return null;
|
|
@@ -13472,6 +13162,22 @@ class WorkspaceProject {
|
|
|
13472
13162
|
};
|
|
13473
13163
|
return out(include, globOptions);
|
|
13474
13164
|
}
|
|
13165
|
+
async isTargetFile(id, source) {
|
|
13166
|
+
var _a;
|
|
13167
|
+
const relativeId = relative(this.config.dir || this.config.root, id);
|
|
13168
|
+
if (micromatch_1.isMatch(relativeId, this.config.exclude))
|
|
13169
|
+
return false;
|
|
13170
|
+
if (micromatch_1.isMatch(relativeId, this.config.include))
|
|
13171
|
+
return true;
|
|
13172
|
+
if (((_a = this.config.includeSource) == null ? void 0 : _a.length) && micromatch_1.isMatch(relativeId, this.config.includeSource)) {
|
|
13173
|
+
source = source || await promises.readFile(id, "utf-8");
|
|
13174
|
+
return this.isInSourceTestFile(source);
|
|
13175
|
+
}
|
|
13176
|
+
return false;
|
|
13177
|
+
}
|
|
13178
|
+
isInSourceTestFile(code) {
|
|
13179
|
+
return code.includes("import.meta.vitest");
|
|
13180
|
+
}
|
|
13475
13181
|
filterFiles(testFiles, filters = []) {
|
|
13476
13182
|
if (filters.length && process.platform === "win32")
|
|
13477
13183
|
filters = filters.map((f) => toNamespacedPath(f));
|
|
@@ -13489,7 +13195,7 @@ class WorkspaceProject {
|
|
|
13489
13195
|
async setServer(options, server, params = {}) {
|
|
13490
13196
|
this.config = resolveConfig(this.ctx.mode, options, server.config);
|
|
13491
13197
|
this.server = server;
|
|
13492
|
-
this.vitenode = params.server ?? new
|
|
13198
|
+
this.vitenode = params.server ?? new ViteNodeServer(server, this.config);
|
|
13493
13199
|
const node = this.vitenode;
|
|
13494
13200
|
this.runner = params.runner ?? new ViteNodeRunner({
|
|
13495
13201
|
root: server.config.root,
|
|
@@ -13631,6 +13337,7 @@ class Vitest {
|
|
|
13631
13337
|
this.vitenode = void 0;
|
|
13632
13338
|
this.invalidates = /* @__PURE__ */ new Set();
|
|
13633
13339
|
this.changedTests = /* @__PURE__ */ new Set();
|
|
13340
|
+
this.isCancelling = false;
|
|
13634
13341
|
this.isFirstRun = true;
|
|
13635
13342
|
this.restartsCount = 0;
|
|
13636
13343
|
this.runner = void 0;
|
|
@@ -13638,6 +13345,7 @@ class Vitest {
|
|
|
13638
13345
|
this.projectsTestFiles = /* @__PURE__ */ new Map();
|
|
13639
13346
|
this._onRestartListeners = [];
|
|
13640
13347
|
this._onSetServer = [];
|
|
13348
|
+
this._onCancelListeners = [];
|
|
13641
13349
|
this.unregisterWatcher = noop$1;
|
|
13642
13350
|
this.logger = new Logger(this);
|
|
13643
13351
|
}
|
|
@@ -13650,6 +13358,7 @@ class Vitest {
|
|
|
13650
13358
|
this.pool = void 0;
|
|
13651
13359
|
this.coverageProvider = void 0;
|
|
13652
13360
|
this.runningPromise = void 0;
|
|
13361
|
+
this.projectsTestFiles.clear();
|
|
13653
13362
|
const resolved = resolveConfig(this.mode, options, server.config);
|
|
13654
13363
|
this.server = server;
|
|
13655
13364
|
this.config = resolved;
|
|
@@ -13658,7 +13367,7 @@ class Vitest {
|
|
|
13658
13367
|
this.snapshot = new SnapshotManager({ ...resolved.snapshotOptions });
|
|
13659
13368
|
if (this.config.watch && this.mode !== "typecheck")
|
|
13660
13369
|
this.registerWatcher();
|
|
13661
|
-
this.vitenode = new
|
|
13370
|
+
this.vitenode = new ViteNodeServer(server, this.config);
|
|
13662
13371
|
const node = this.vitenode;
|
|
13663
13372
|
this.runner = new ViteNodeRunner({
|
|
13664
13373
|
root: server.config.root,
|
|
@@ -13706,9 +13415,7 @@ class Vitest {
|
|
|
13706
13415
|
return coreWorkspace;
|
|
13707
13416
|
}
|
|
13708
13417
|
getCoreWorkspaceProject() {
|
|
13709
|
-
|
|
13710
|
-
throw new Error("Core workspace project is not initialized");
|
|
13711
|
-
return this.coreWorkspace;
|
|
13418
|
+
return this.coreWorkspace || null;
|
|
13712
13419
|
}
|
|
13713
13420
|
async resolveWorkspace(options, cliOptions) {
|
|
13714
13421
|
const configDir = this.server.config.configFile ? dirname(this.server.config.configFile) : this.config.root;
|
|
@@ -13814,15 +13521,10 @@ class Vitest {
|
|
|
13814
13521
|
await this.typecheck(filters);
|
|
13815
13522
|
return;
|
|
13816
13523
|
}
|
|
13817
|
-
try {
|
|
13818
|
-
await this.initCoverageProvider();
|
|
13819
|
-
await ((_a = this.coverageProvider) == null ? void 0 : _a.clean(this.config.coverage.clean));
|
|
13820
|
-
await this.initBrowserProviders();
|
|
13821
|
-
} catch (e) {
|
|
13822
|
-
this.logger.error(e);
|
|
13823
|
-
process.exit(1);
|
|
13824
|
-
}
|
|
13825
13524
|
await this.report("onInit", this);
|
|
13525
|
+
await this.initCoverageProvider();
|
|
13526
|
+
await ((_a = this.coverageProvider) == null ? void 0 : _a.clean(this.config.coverage.clean));
|
|
13527
|
+
await this.initBrowserProviders();
|
|
13826
13528
|
const files = await this.filterTestsBySource(
|
|
13827
13529
|
await this.globTestFiles(filters)
|
|
13828
13530
|
);
|
|
@@ -13902,6 +13604,8 @@ class Vitest {
|
|
|
13902
13604
|
this.state.collectPaths(filepaths);
|
|
13903
13605
|
await this.report("onPathsCollected", filepaths);
|
|
13904
13606
|
await this.runningPromise;
|
|
13607
|
+
this._onCancelListeners = [];
|
|
13608
|
+
this.isCancelling = false;
|
|
13905
13609
|
this.runningPromise = (async () => {
|
|
13906
13610
|
if (!this.pool)
|
|
13907
13611
|
this.pool = createPool(this);
|
|
@@ -13926,6 +13630,10 @@ class Vitest {
|
|
|
13926
13630
|
});
|
|
13927
13631
|
return await this.runningPromise;
|
|
13928
13632
|
}
|
|
13633
|
+
async cancelCurrentRun(reason) {
|
|
13634
|
+
this.isCancelling = true;
|
|
13635
|
+
await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason)));
|
|
13636
|
+
}
|
|
13929
13637
|
async rerunFiles(files = this.state.getFilepaths(), trigger) {
|
|
13930
13638
|
if (this.filenamePattern) {
|
|
13931
13639
|
const filteredFiles = await this.globTestFiles([this.filenamePattern]);
|
|
@@ -14039,7 +13747,13 @@ class Vitest {
|
|
|
14039
13747
|
const onAdd = async (id) => {
|
|
14040
13748
|
id = slash$1(id);
|
|
14041
13749
|
updateLastChanged(id);
|
|
14042
|
-
|
|
13750
|
+
const matchingProjects = [];
|
|
13751
|
+
await Promise.all(this.projects.map(async (project) => {
|
|
13752
|
+
if (await project.isTargetFile(id))
|
|
13753
|
+
matchingProjects.push(project);
|
|
13754
|
+
}));
|
|
13755
|
+
if (matchingProjects.length > 0) {
|
|
13756
|
+
this.projectsTestFiles.set(id, new Set(matchingProjects));
|
|
14043
13757
|
this.changedTests.add(id);
|
|
14044
13758
|
this.scheduleRerun([id]);
|
|
14045
13759
|
}
|
|
@@ -14116,10 +13830,12 @@ class Vitest {
|
|
|
14116
13830
|
async close() {
|
|
14117
13831
|
var _a;
|
|
14118
13832
|
if (!this.closingPromise) {
|
|
13833
|
+
const closePromises = this.projects.map((w) => w.close());
|
|
13834
|
+
if (this.coreWorkspace && !this.projects.includes(this.coreWorkspace))
|
|
13835
|
+
closePromises.push(this.server.close());
|
|
14119
13836
|
this.closingPromise = Promise.allSettled([
|
|
14120
13837
|
(_a = this.pool) == null ? void 0 : _a.close(),
|
|
14121
|
-
|
|
14122
|
-
...this.projects.map((w) => w.close())
|
|
13838
|
+
...closePromises
|
|
14123
13839
|
].filter(Boolean)).then((results) => {
|
|
14124
13840
|
results.filter((r) => r.status === "rejected").forEach((err) => {
|
|
14125
13841
|
this.logger.error("error during close", err.reason);
|
|
@@ -14165,33 +13881,20 @@ class Vitest {
|
|
|
14165
13881
|
}));
|
|
14166
13882
|
return files;
|
|
14167
13883
|
}
|
|
14168
|
-
async isTargetFile(id, source) {
|
|
14169
|
-
var _a;
|
|
14170
|
-
const relativeId = relative(this.config.dir || this.config.root, id);
|
|
14171
|
-
if (micromatch_1.isMatch(relativeId, this.config.exclude))
|
|
14172
|
-
return false;
|
|
14173
|
-
if (micromatch_1.isMatch(relativeId, this.config.include))
|
|
14174
|
-
return true;
|
|
14175
|
-
if (((_a = this.config.includeSource) == null ? void 0 : _a.length) && micromatch_1.isMatch(relativeId, this.config.includeSource)) {
|
|
14176
|
-
source = source || await promises.readFile(id, "utf-8");
|
|
14177
|
-
return this.isInSourceTestFile(source);
|
|
14178
|
-
}
|
|
14179
|
-
return false;
|
|
14180
|
-
}
|
|
14181
13884
|
// The server needs to be running for communication
|
|
14182
13885
|
shouldKeepServer() {
|
|
14183
13886
|
var _a;
|
|
14184
13887
|
return !!((_a = this.config) == null ? void 0 : _a.watch);
|
|
14185
13888
|
}
|
|
14186
|
-
isInSourceTestFile(code) {
|
|
14187
|
-
return code.includes("import.meta.vitest");
|
|
14188
|
-
}
|
|
14189
13889
|
onServerRestart(fn) {
|
|
14190
13890
|
this._onRestartListeners.push(fn);
|
|
14191
13891
|
}
|
|
14192
13892
|
onAfterSetServer(fn) {
|
|
14193
13893
|
this._onSetServer.push(fn);
|
|
14194
13894
|
}
|
|
13895
|
+
onCancel(fn) {
|
|
13896
|
+
this._onCancelListeners.push(fn);
|
|
13897
|
+
}
|
|
14195
13898
|
}
|
|
14196
13899
|
|
|
14197
13900
|
async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
@@ -14202,7 +13905,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
|
14202
13905
|
};
|
|
14203
13906
|
async function UIPlugin() {
|
|
14204
13907
|
await ensurePackageInstalled("@vitest/ui", getRoot());
|
|
14205
|
-
return (await import('@vitest/ui')).default(
|
|
13908
|
+
return (await import('@vitest/ui')).default(ctx);
|
|
14206
13909
|
}
|
|
14207
13910
|
return [
|
|
14208
13911
|
{
|
|
@@ -14333,7 +14036,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
|
14333
14036
|
try {
|
|
14334
14037
|
await ctx.setServer(options, server, userConfig);
|
|
14335
14038
|
if (options.api && options.watch)
|
|
14336
|
-
(await import('./chunk-api-setup.
|
|
14039
|
+
(await import('./chunk-api-setup.df3106cd.js')).setup(ctx);
|
|
14337
14040
|
} catch (err) {
|
|
14338
14041
|
await ctx.logger.printError(err, true);
|
|
14339
14042
|
process.exit(1);
|
|
@@ -14346,7 +14049,8 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
|
14346
14049
|
GlobalSetupPlugin(ctx, ctx.logger),
|
|
14347
14050
|
...CSSEnablerPlugin(ctx),
|
|
14348
14051
|
CoverageTransform(ctx),
|
|
14349
|
-
options.ui ? await UIPlugin() : null
|
|
14052
|
+
options.ui ? await UIPlugin() : null,
|
|
14053
|
+
MocksPlugin()
|
|
14350
14054
|
].filter(notNullish);
|
|
14351
14055
|
}
|
|
14352
14056
|
|
|
@@ -20650,6 +20354,7 @@ const keys = [
|
|
|
20650
20354
|
["t", "filter by a test name regex pattern"],
|
|
20651
20355
|
["q", "quit"]
|
|
20652
20356
|
];
|
|
20357
|
+
const cancelKeys = ["space", "c", ...keys.map((key) => key[0])];
|
|
20653
20358
|
function printShortcutsHelp() {
|
|
20654
20359
|
stdout().write(
|
|
20655
20360
|
`
|
|
@@ -20668,9 +20373,12 @@ function registerConsoleShortcuts(ctx) {
|
|
|
20668
20373
|
process.kill(process.pid, "SIGTSTP");
|
|
20669
20374
|
return;
|
|
20670
20375
|
}
|
|
20671
|
-
if (ctx.runningPromise)
|
|
20672
|
-
return;
|
|
20673
20376
|
const name = key == null ? void 0 : key.name;
|
|
20377
|
+
if (ctx.runningPromise) {
|
|
20378
|
+
if (cancelKeys.includes(name))
|
|
20379
|
+
await ctx.cancelCurrentRun("keyboard-input");
|
|
20380
|
+
return;
|
|
20381
|
+
}
|
|
20674
20382
|
if (name === "q")
|
|
20675
20383
|
return ctx.exit(true);
|
|
20676
20384
|
if (ctx.mode === "typecheck")
|
|
@@ -20700,8 +20408,8 @@ function registerConsoleShortcuts(ctx) {
|
|
|
20700
20408
|
message: "Input test name pattern (RegExp)",
|
|
20701
20409
|
initial: ((_a = ctx.configOverride.testNamePattern) == null ? void 0 : _a.source) || ""
|
|
20702
20410
|
}]);
|
|
20703
|
-
await ctx.changeNamePattern(filter.trim(), void 0, "change pattern");
|
|
20704
20411
|
on();
|
|
20412
|
+
await ctx.changeNamePattern(filter.trim(), void 0, "change pattern");
|
|
20705
20413
|
}
|
|
20706
20414
|
async function inputFilePattern() {
|
|
20707
20415
|
off();
|
|
@@ -20712,8 +20420,8 @@ function registerConsoleShortcuts(ctx) {
|
|
|
20712
20420
|
initial: latestFilename
|
|
20713
20421
|
}]);
|
|
20714
20422
|
latestFilename = filter.trim();
|
|
20715
|
-
await ctx.changeFilenamePattern(filter.trim());
|
|
20716
20423
|
on();
|
|
20424
|
+
await ctx.changeFilenamePattern(filter.trim());
|
|
20717
20425
|
}
|
|
20718
20426
|
let rl;
|
|
20719
20427
|
function on() {
|