vitest 5.0.4 → 5.1.0-beta.1
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 -1
- package/dist/browser.d.ts +4 -4
- package/dist/browser.js +3 -3
- package/dist/chunks/{base.CYbb9pQW.js → base.PJyN9N0u.js} +13 -11
- package/dist/chunks/{browser.d.FGQ9_rK6.d.ts → browser.d.D7a15z82.d.ts} +4 -3
- package/dist/chunks/{cac.DTXWs6Ni.js → cac.Ccf5Je_F.js} +21 -9
- package/dist/chunks/{cli-api.Bx28WXzL.js → cli-api.DE22LIzq.js} +4584 -4369
- package/dist/chunks/{config.d.QBNYCgFU.d.ts → config.d.BgktgHfG.d.ts} +134 -93
- package/dist/chunks/{console.DtI4yxfN.js → console.DrMPSuFo.js} +5 -2
- package/dist/chunks/{constants.-juJ8b_4.js → constants.DLYM6cZY.js} +1 -1
- package/dist/chunks/{creator.CLL8QFMS.js → creator.BQ3onxbh.js} +5 -5
- package/dist/chunks/{doctor.Bqc8NDDb.js → doctor.CPlMs7-y.js} +1 -1
- package/dist/chunks/{environment.d.BY56MoGs.d.ts → environment.d.CbTLsZSj.d.ts} +1 -1
- package/dist/chunks/{globals.CTWMSIPL.js → globals.TipXUFcZ.js} +5 -5
- package/dist/chunks/{index.GYMZ12wH.js → index.B03wg4V0.js} +5 -3
- package/dist/chunks/{index.CPNMO3h-.js → index.BFXLpwll.js} +119 -43
- package/dist/chunks/{index.uwTEEBsB.js → index.BXttT2gP.js} +37 -18
- package/dist/chunks/{index.B8VfM7Mf.js → index.D14IAvnE.js} +149 -96
- package/dist/chunks/{init-forks.CbYYa5xq.js → init-forks.BL1E3__4.js} +1 -1
- package/dist/chunks/{init-threads.DtjdvxPl.js → init-threads.CYXAGzKQ.js} +1 -1
- package/dist/chunks/{init.DrHtV5zd.js → init.DVorxUyL.js} +3 -3
- package/dist/chunks/{nativeModuleMocker.D8f4cW4A.js → nativeModuleMocker.3uBcOd84.js} +26 -4
- package/dist/chunks/{plugin.d.C8mmycim.d.ts → plugin.d.olEn8IL9.d.ts} +108 -20
- package/dist/chunks/{rpc.DpkUyY1N.js → rpc.BV0XpJ5q.js} +1 -1
- package/dist/chunks/{rpc.d.Cft1biqy.d.ts → rpc.d.DGFP7vWr.d.ts} +1 -1
- package/dist/chunks/{run.Cm2sd7-x.js → run.BfrMbGVD.js} +59 -32
- package/dist/chunks/{setup-common.BABL3z3m.js → setup-common.llxJkJaD.js} +2 -2
- package/dist/chunks/{source-map.DdKI5IHB.js → source-map.BjWcsIL9.js} +32 -24
- package/dist/chunks/{source-map.d.kzFtk_dj.d.ts → source-map.d.C5A_Tr6V.d.ts} +2 -1
- package/dist/chunks/{task-utils.d.PFh2BV6Q.d.ts → task-utils.d.BUh7ylUT.d.ts} +2 -1
- package/dist/chunks/{vm.Uo_C9Uld.js → vm.Cwj01UFE.js} +16 -5
- package/dist/chunks/{worker.d.BH-r1bPu.d.ts → worker.d.gsA26mmR.d.ts} +3 -3
- package/dist/cli.js +2 -2
- package/dist/config.cjs +1 -1
- package/dist/config.d.ts +11 -11
- package/dist/config.js +1 -1
- package/dist/index.d.ts +14 -13
- package/dist/index.js +4 -4
- package/dist/module-evaluator.d.ts +3 -2
- package/dist/module-evaluator.js +16 -12
- package/dist/node.d.ts +29 -11
- package/dist/node.js +7 -7
- package/dist/runtime.d.ts +4 -4
- package/dist/runtime.js +3 -2
- package/dist/task-utils.js +3 -1
- package/dist/worker.d.ts +4 -4
- package/dist/worker.js +9 -9
- package/dist/workers/forks.js +10 -10
- package/dist/workers/runVmTests.js +10 -8
- package/dist/workers/threads.js +10 -10
- package/dist/workers/vmForks.js +9 -8
- package/dist/workers/vmThreads.js +9 -8
- package/package.json +14 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { promises, existsSync, mkdirSync,
|
|
1
|
+
import { promises, existsSync, mkdirSync, writeFileSync, linkSync, renameSync, rmSync, chmodSync, readFileSync, statfsSync, realpathSync, statSync, readdirSync } from 'node:fs';
|
|
2
2
|
import url, { pathToFileURL, fileURLToPath } from 'node:url';
|
|
3
3
|
import { c as cleanUrl, r as resolve, f as extname, d as dirname, j as join, h as KNOWN_ASSET_RE, H as withTrailingSlash, I as wrapId, i as isAbsolute, J as isExternalUrl, L as unwrapId, a as relative, z as unique, s as slash, t as toArray, b as basename, m as isPrimitive, n as normalize, G as deepMerge, e as createDefer, p as deepClone } from './pathe.M-eThtNZ.Ba-7h1rE.js';
|
|
4
4
|
import { N as NativeModuleRunner, i as isPackageExists, r as resolveModule } from './nativeModuleRunner.xi64Afb2.js';
|
|
@@ -6,7 +6,7 @@ import { glob, isDynamicPattern } from 'tinyglobby';
|
|
|
6
6
|
import { $ } from './tinyrainbow.Do8I1XRG.js';
|
|
7
7
|
import * as vite from 'vite';
|
|
8
8
|
import { createServer, normalizePath, isFileLoadingAllowed, fetchModule, parseAst, searchForWorkspaceRoot, version, isRunnableDevEnvironment, mergeConfig, resolveConfig as resolveConfig$1 } from 'vite';
|
|
9
|
-
import { a as defaultPort, c as configFiles, d as defaultBrowserPort, b as defaultInspectPort } from './constants
|
|
9
|
+
import { a as defaultPort, c as configFiles, d as defaultBrowserPort, b as defaultInspectPort } from './constants.DLYM6cZY.js';
|
|
10
10
|
import { c as configDefaults, e as benchmarkConfigDefaults } from './defaults.B1FCaFfh.js';
|
|
11
11
|
import { b as isWindows, i as isForceColor, a as isTTY } from './env.BKKtU2WC.js';
|
|
12
12
|
import * as os from 'node:os';
|
|
@@ -22,9 +22,9 @@ import { Writable } from 'node:stream';
|
|
|
22
22
|
import { stripVTControlCharacters } from 'node:util';
|
|
23
23
|
import { i as inspect } from './display.BlTmubjj.js';
|
|
24
24
|
import { performance as performance$1 } from 'node:perf_hooks';
|
|
25
|
-
import { T as TraceMap, o as originalPositionFor, i as generatedPositionFor, j as eachMapping, k as stackIgnorePatterns, e as parseErrorStacktrace } from './source-map.
|
|
25
|
+
import { T as TraceMap, o as originalPositionFor, i as generatedPositionFor, j as eachMapping, k as stackIgnorePatterns, e as parseErrorStacktrace } from './source-map.BjWcsIL9.js';
|
|
26
26
|
import { x } from 'tinyexec';
|
|
27
|
-
import { B as validateTags, z as limitConcurrency, C as shuffle } from './run.
|
|
27
|
+
import { B as validateTags, z as limitConcurrency, C as shuffle } from './run.BfrMbGVD.js';
|
|
28
28
|
import { createDebug } from 'obug';
|
|
29
29
|
import { createFileTask as createFileTask$1, createTaskName, calculateSuiteHash, convertTasksToEvents, hasFailed, generateFileHash } from '../task-utils.js';
|
|
30
30
|
import { readFile, mkdir, writeFile, rm, stat } from 'node:fs/promises';
|
|
@@ -45,7 +45,7 @@ import EventEmitter$1, { EventEmitter } from 'node:events';
|
|
|
45
45
|
import { c as createBirpc } from './index.DmDMHCg8.js';
|
|
46
46
|
import { fork } from 'node:child_process';
|
|
47
47
|
import { Worker } from 'node:worker_threads';
|
|
48
|
-
import { v as version$1 } from './cac.
|
|
48
|
+
import { v as version$1 } from './cac.Ccf5Je_F.js';
|
|
49
49
|
import { g as getDefaultExportFromCjs } from './index.D0heQG4v.js';
|
|
50
50
|
import require$$0 from 'readline';
|
|
51
51
|
import require$$0$1 from 'events';
|
|
@@ -915,14 +915,16 @@ class ModuleTransformService {
|
|
|
915
915
|
*/
|
|
916
916
|
async transform(id, environment) {
|
|
917
917
|
await this.traces.waitInit();
|
|
918
|
-
|
|
918
|
+
// the module graph keeps the url of the first request, so it has to be the url that workers import
|
|
919
|
+
const url = normalizeResolvedIdToUrl(environment, id);
|
|
920
|
+
const result = await this.traces.$("vitest.module.transform", (span) => this.fetchInSpan(span, url, void 0, environment));
|
|
919
921
|
// externalized modules are loaded by Node without a transform, like in a normal run
|
|
920
922
|
if ("externalize" in result) return null;
|
|
921
923
|
if ("id" in result) {
|
|
922
924
|
const transformResult = environment.moduleGraph.getModuleById(result.id)?.transformResult;
|
|
923
925
|
if (transformResult) return transformResult;
|
|
924
926
|
}
|
|
925
|
-
return environment.transformRequest(
|
|
927
|
+
return environment.transformRequest(url);
|
|
926
928
|
}
|
|
927
929
|
async fetchInSpan(trace, url, importer, environment, makeTmpCopies, options) {
|
|
928
930
|
if (url.startsWith("data:")) {
|
|
@@ -1101,7 +1103,7 @@ class ModuleTransformService {
|
|
|
1101
1103
|
file: cachedModule.file,
|
|
1102
1104
|
id: cachedModule.id,
|
|
1103
1105
|
tmp: cachePath,
|
|
1104
|
-
url:
|
|
1106
|
+
url: moduleGraphModule.url,
|
|
1105
1107
|
invalidate: false,
|
|
1106
1108
|
moduleType
|
|
1107
1109
|
};
|
|
@@ -1422,6 +1424,7 @@ function createFailedFileTask(project, filepath, error, options) {
|
|
|
1422
1424
|
return file;
|
|
1423
1425
|
}
|
|
1424
1426
|
function serializeError(error) {
|
|
1427
|
+
if (error?.__vitest_rollup_error__) return [error];
|
|
1425
1428
|
return [toRollupError(error) ?? {
|
|
1426
1429
|
name: error.name,
|
|
1427
1430
|
stack: error.stack,
|
|
@@ -1574,7 +1577,8 @@ async function transformSSR(project, filepath) {
|
|
|
1574
1577
|
const { env: pragmaEnv, tags: fileTags } = detectCodeBlock(originalCode);
|
|
1575
1578
|
// Use environment from pragma if defined, otherwise fall back to config
|
|
1576
1579
|
const environment = pragmaEnv || project.config.environment;
|
|
1577
|
-
const
|
|
1580
|
+
const env = environment === "jsdom" || environment === "happy-dom" ? project.vite.environments.client : project.vite.environments.ssr;
|
|
1581
|
+
const transformResult = await project._transformService.transform(filepath, env);
|
|
1578
1582
|
return transformResult ? {
|
|
1579
1583
|
...transformResult,
|
|
1580
1584
|
fileTags
|
|
@@ -1865,7 +1869,12 @@ async function createClusterServer(vitest, viteConfig, config, children) {
|
|
|
1865
1869
|
// listen on startup only for `api`/`ui`, otherwise on the first browser launch
|
|
1866
1870
|
// (collect-only processes never listen, so Vite never starts a dependency scan)
|
|
1867
1871
|
if (config._apiRequested) await server.listen(config.api.port);
|
|
1868
|
-
else
|
|
1872
|
+
else {
|
|
1873
|
+
deferredListen.set(server, { port: config.api.port });
|
|
1874
|
+
// Vite runs plugin buildStart hooks on listen; global setup and --changed
|
|
1875
|
+
// transform modules before the first browser launch
|
|
1876
|
+
await server.environments.client.pluginContainer.buildStart();
|
|
1877
|
+
}
|
|
1869
1878
|
contribution.setupRpc(parent);
|
|
1870
1879
|
return {
|
|
1871
1880
|
server,
|
|
@@ -1883,6 +1892,70 @@ function generateScopedClassName(strategy, name, filename) {
|
|
|
1883
1892
|
return `_${name}_${generateCssFilenameHash(filename)}`;
|
|
1884
1893
|
}
|
|
1885
1894
|
|
|
1895
|
+
const API_TOKEN_FILE = ".vitest-secret-token";
|
|
1896
|
+
// Follows env-paths' user data directory conventions:
|
|
1897
|
+
// https://github.com/sindresorhus/env-paths/blob/v4.0.0/index.js
|
|
1898
|
+
function getUserDataDir() {
|
|
1899
|
+
if (process.platform === "win32") return process.env.LOCALAPPDATA || join(homedir(), "AppData/Local");
|
|
1900
|
+
if (process.platform === "darwin") return join(homedir(), "Library/Application Support");
|
|
1901
|
+
return process.env.XDG_DATA_HOME || join(homedir(), ".local/share");
|
|
1902
|
+
}
|
|
1903
|
+
function readPublishedToken(tokenPath) {
|
|
1904
|
+
try {
|
|
1905
|
+
return readFileSync(tokenPath, "utf-8").trim() || void 0;
|
|
1906
|
+
} catch {
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
function resolveTokenFromPath(tokenPath) {
|
|
1911
|
+
const published = readPublishedToken(tokenPath);
|
|
1912
|
+
if (published) return {
|
|
1913
|
+
token: published,
|
|
1914
|
+
tokenCreated: false
|
|
1915
|
+
};
|
|
1916
|
+
const dir = dirname(tokenPath);
|
|
1917
|
+
mkdirSync(dir, {
|
|
1918
|
+
recursive: true,
|
|
1919
|
+
mode: 448
|
|
1920
|
+
});
|
|
1921
|
+
const token = crypto.randomUUID();
|
|
1922
|
+
const pendingPath = join(dir, `${API_TOKEN_FILE}.${process.pid}.${crypto.randomUUID()}`);
|
|
1923
|
+
writeFileSync(pendingPath, `${token}\n`, { mode: 384 });
|
|
1924
|
+
let tokenCreated = true;
|
|
1925
|
+
try {
|
|
1926
|
+
// linking fails when another process already published, which keeps a single winner
|
|
1927
|
+
linkSync(pendingPath, tokenPath);
|
|
1928
|
+
} catch (error) {
|
|
1929
|
+
if (error.code === "EEXIST") tokenCreated = false;
|
|
1930
|
+
else renameSync(pendingPath, tokenPath);
|
|
1931
|
+
} finally {
|
|
1932
|
+
rmSync(pendingPath, { force: true });
|
|
1933
|
+
}
|
|
1934
|
+
const winner = readPublishedToken(tokenPath);
|
|
1935
|
+
if (!tokenCreated && !winner) {
|
|
1936
|
+
writeFileSync(tokenPath, `${token}\n`, { mode: 384 });
|
|
1937
|
+
tokenCreated = true;
|
|
1938
|
+
}
|
|
1939
|
+
try {
|
|
1940
|
+
chmodSync(dir, 448);
|
|
1941
|
+
chmodSync(tokenPath, 384);
|
|
1942
|
+
} catch {}
|
|
1943
|
+
return {
|
|
1944
|
+
token: (tokenCreated ? token : winner) ?? token,
|
|
1945
|
+
tokenCreated
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
function resolveApiToken(root) {
|
|
1949
|
+
const tokenPaths = [join(getUserDataDir(), "vitest", API_TOKEN_FILE), join(searchForWorkspaceRoot(root), "node_modules/.vitest", API_TOKEN_FILE)];
|
|
1950
|
+
for (const tokenPath of tokenPaths) try {
|
|
1951
|
+
return {
|
|
1952
|
+
...resolveTokenFromPath(tokenPath),
|
|
1953
|
+
tokenPath
|
|
1954
|
+
};
|
|
1955
|
+
} catch {}
|
|
1956
|
+
throw new Error(`Failed to create Vitest API token at ${tokenPaths.join(" or ")}`);
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1886
1959
|
function resolveTestCacheDir(root, testConfig, viteCacheDir) {
|
|
1887
1960
|
const name = testConfig.name;
|
|
1888
1961
|
const label = typeof name === "string" ? name : name?.label || "";
|
|
@@ -1976,6 +2049,23 @@ function deleteDefineConfig(viteConfig) {
|
|
|
1976
2049
|
scriptDefines
|
|
1977
2050
|
};
|
|
1978
2051
|
}
|
|
2052
|
+
// TODO: use Vite's own defaults once they are exported (request upstream)
|
|
2053
|
+
// copied from Vite 8.3 https://github.com/vitejs/vite/blob/v8.3.4/packages/vite/src/node/server/index.ts#L1254-L1261
|
|
2054
|
+
const VITE_DEFAULT_FS_DENY = [
|
|
2055
|
+
".env",
|
|
2056
|
+
".env.*",
|
|
2057
|
+
"*.{crt,pem,key,p12,pfx,cer,der}",
|
|
2058
|
+
".npmrc",
|
|
2059
|
+
".yarnrc.yml",
|
|
2060
|
+
"**/.git/**"
|
|
2061
|
+
];
|
|
2062
|
+
// Vite drops its default `server.fs.deny` once any value is set,
|
|
2063
|
+
// so the defaults are kept explicitly when the user didn't set one.
|
|
2064
|
+
function appendApiTokenFsDeny(viteConfig) {
|
|
2065
|
+
viteConfig.server ??= {};
|
|
2066
|
+
viteConfig.server.fs ??= {};
|
|
2067
|
+
viteConfig.server.fs.deny = [...viteConfig.server.fs.deny ?? VITE_DEFAULT_FS_DENY, API_TOKEN_FILE];
|
|
2068
|
+
}
|
|
1979
2069
|
function resolveFsAllow(projectRoot, rootConfigFile) {
|
|
1980
2070
|
if (!rootConfigFile) return [searchForWorkspaceRoot(projectRoot), rootDir];
|
|
1981
2071
|
return [
|
|
@@ -3558,6 +3648,7 @@ function VitestCorePlugin(harness) {
|
|
|
3558
3648
|
order: "post",
|
|
3559
3649
|
handler(viteConfig) {
|
|
3560
3650
|
const root = resolve(viteConfig.test?.root || viteConfig.root || process.cwd());
|
|
3651
|
+
appendApiTokenFsDeny(viteConfig);
|
|
3561
3652
|
return {
|
|
3562
3653
|
base: "/",
|
|
3563
3654
|
root,
|
|
@@ -3783,70 +3874,6 @@ function processWildcard(dep, moduleDirectories) {
|
|
|
3783
3874
|
return dep;
|
|
3784
3875
|
}
|
|
3785
3876
|
|
|
3786
|
-
const API_TOKEN_FILE = ".vitest-secret-token";
|
|
3787
|
-
// Follows env-paths' user data directory conventions:
|
|
3788
|
-
// https://github.com/sindresorhus/env-paths/blob/v4.0.0/index.js
|
|
3789
|
-
function getUserDataDir() {
|
|
3790
|
-
if (process.platform === "win32") return process.env.LOCALAPPDATA || join(homedir(), "AppData/Local");
|
|
3791
|
-
if (process.platform === "darwin") return join(homedir(), "Library/Application Support");
|
|
3792
|
-
return process.env.XDG_DATA_HOME || join(homedir(), ".local/share");
|
|
3793
|
-
}
|
|
3794
|
-
function readPublishedToken(tokenPath) {
|
|
3795
|
-
try {
|
|
3796
|
-
return readFileSync(tokenPath, "utf-8").trim() || void 0;
|
|
3797
|
-
} catch {
|
|
3798
|
-
return;
|
|
3799
|
-
}
|
|
3800
|
-
}
|
|
3801
|
-
function resolveTokenFromPath(tokenPath) {
|
|
3802
|
-
const published = readPublishedToken(tokenPath);
|
|
3803
|
-
if (published) return {
|
|
3804
|
-
token: published,
|
|
3805
|
-
tokenCreated: false
|
|
3806
|
-
};
|
|
3807
|
-
const dir = dirname(tokenPath);
|
|
3808
|
-
mkdirSync(dir, {
|
|
3809
|
-
recursive: true,
|
|
3810
|
-
mode: 448
|
|
3811
|
-
});
|
|
3812
|
-
const token = crypto.randomUUID();
|
|
3813
|
-
const pendingPath = join(dir, `${API_TOKEN_FILE}.${process.pid}.${crypto.randomUUID()}`);
|
|
3814
|
-
writeFileSync(pendingPath, `${token}\n`, { mode: 384 });
|
|
3815
|
-
let tokenCreated = true;
|
|
3816
|
-
try {
|
|
3817
|
-
// linking fails when another process already published, which keeps a single winner
|
|
3818
|
-
linkSync(pendingPath, tokenPath);
|
|
3819
|
-
} catch (error) {
|
|
3820
|
-
if (error.code === "EEXIST") tokenCreated = false;
|
|
3821
|
-
else renameSync(pendingPath, tokenPath);
|
|
3822
|
-
} finally {
|
|
3823
|
-
rmSync(pendingPath, { force: true });
|
|
3824
|
-
}
|
|
3825
|
-
const winner = readPublishedToken(tokenPath);
|
|
3826
|
-
if (!tokenCreated && !winner) {
|
|
3827
|
-
writeFileSync(tokenPath, `${token}\n`, { mode: 384 });
|
|
3828
|
-
tokenCreated = true;
|
|
3829
|
-
}
|
|
3830
|
-
try {
|
|
3831
|
-
chmodSync(dir, 448);
|
|
3832
|
-
chmodSync(tokenPath, 384);
|
|
3833
|
-
} catch {}
|
|
3834
|
-
return {
|
|
3835
|
-
token: (tokenCreated ? token : winner) ?? token,
|
|
3836
|
-
tokenCreated
|
|
3837
|
-
};
|
|
3838
|
-
}
|
|
3839
|
-
function resolveApiToken(root) {
|
|
3840
|
-
const tokenPaths = [join(getUserDataDir(), "vitest", API_TOKEN_FILE), join(searchForWorkspaceRoot(root), "node_modules/.vitest", API_TOKEN_FILE)];
|
|
3841
|
-
for (const tokenPath of tokenPaths) try {
|
|
3842
|
-
return {
|
|
3843
|
-
...resolveTokenFromPath(tokenPath),
|
|
3844
|
-
tokenPath
|
|
3845
|
-
};
|
|
3846
|
-
} catch {}
|
|
3847
|
-
throw new Error(`Failed to create Vitest API token at ${tokenPaths.join(" or ")}`);
|
|
3848
|
-
}
|
|
3849
|
-
|
|
3850
3877
|
function ProjectRootPlugin(projectRoot) {
|
|
3851
3878
|
return {
|
|
3852
3879
|
name: "vitest:project-root",
|
|
@@ -3872,16 +3899,14 @@ function WorkspaceVitestPlugin(harness, globalViteConfig) {
|
|
|
3872
3899
|
config(viteConfig) {
|
|
3873
3900
|
const testConfig = viteConfig.test || {};
|
|
3874
3901
|
const root = testConfig.root || viteConfig.root;
|
|
3902
|
+
appendApiTokenFsDeny(viteConfig);
|
|
3875
3903
|
return {
|
|
3876
3904
|
base: "/",
|
|
3877
3905
|
root,
|
|
3878
3906
|
cacheDir: resolveTestCacheDir(resolve(root || process.cwd()), testConfig, viteConfig.cacheDir),
|
|
3879
3907
|
server: {
|
|
3880
3908
|
open: false,
|
|
3881
|
-
fs: {
|
|
3882
|
-
allow: globalViteConfig.server.fs.allow,
|
|
3883
|
-
deny: [API_TOKEN_FILE]
|
|
3884
|
-
}
|
|
3909
|
+
fs: { allow: globalViteConfig.server.fs.allow }
|
|
3885
3910
|
}
|
|
3886
3911
|
};
|
|
3887
3912
|
},
|
|
@@ -4100,6 +4125,7 @@ function serializeConfig(project) {
|
|
|
4100
4125
|
},
|
|
4101
4126
|
providerOptions: provider?.name === "playwright" ? { actionTimeout: provider?.options?.actionTimeout } : {},
|
|
4102
4127
|
trackUnhandledErrors: browser.trackUnhandledErrors ?? true,
|
|
4128
|
+
importMapMocks: browser.importMapMocks,
|
|
4103
4129
|
trace: browser.trace.mode,
|
|
4104
4130
|
traceView: browser.traceView
|
|
4105
4131
|
};
|
|
@@ -4272,7 +4298,7 @@ class RangeLocationFilterProvidedError extends Error {
|
|
|
4272
4298
|
}
|
|
4273
4299
|
|
|
4274
4300
|
const debug$1 = createDebugger("vitest:browser:pool");
|
|
4275
|
-
const PROVIDER_CLOSE_TIMEOUT =
|
|
4301
|
+
const PROVIDER_CLOSE_TIMEOUT = 3e4;
|
|
4276
4302
|
function createBrowserPool(vitest) {
|
|
4277
4303
|
// every browser instance is a worker; at most `maxWorkers` of them are open
|
|
4278
4304
|
const workers = /* @__PURE__ */ new Map();
|
|
@@ -4392,7 +4418,7 @@ function createBrowserPool(vitest) {
|
|
|
4392
4418
|
project,
|
|
4393
4419
|
files,
|
|
4394
4420
|
method,
|
|
4395
|
-
exclusive: !provider.
|
|
4421
|
+
exclusive: !provider.supportsParallelism || !provider.mocker && project.config.browser.importMapMocks !== true,
|
|
4396
4422
|
result: createDefer()
|
|
4397
4423
|
};
|
|
4398
4424
|
}));
|
|
@@ -4420,7 +4446,9 @@ function createBrowserPool(vitest) {
|
|
|
4420
4446
|
await Promise.all([...stopping, ...exitPromises]);
|
|
4421
4447
|
// pages can be opened outside of the pool (`vitest.standalone`)
|
|
4422
4448
|
await Promise.all(vitest.projects.map((project) => closeProvider(project)));
|
|
4423
|
-
vitest._browserSessions.sessionIds.
|
|
4449
|
+
vitest._browserSessions.sessionIds.forEach((sessionId) => {
|
|
4450
|
+
vitest._browserSessions.close(sessionId);
|
|
4451
|
+
});
|
|
4424
4452
|
vitest.projects.forEach((project) => {
|
|
4425
4453
|
project.browser?.state.orchestrators.forEach((orchestrator) => {
|
|
4426
4454
|
orchestrator.$close();
|
|
@@ -4439,12 +4467,13 @@ async function groupSpecifications(specs) {
|
|
|
4439
4467
|
const code = /* @__PURE__ */ new Map();
|
|
4440
4468
|
const docblocks = await Promise.all(specs.map((spec) => getSpecificationDocblock(spec, code)));
|
|
4441
4469
|
specs.forEach((spec, index) => {
|
|
4442
|
-
const { project, moduleId, testLines, testIds, testNamePattern, testTagsFilter } = spec;
|
|
4470
|
+
const { project, moduleId, testLines, testIds, testNames, testNamePattern, testTagsFilter } = spec;
|
|
4443
4471
|
const files = groupedFiles.get(project) || [];
|
|
4444
4472
|
files.push({
|
|
4445
4473
|
filepath: moduleId,
|
|
4446
4474
|
testLocations: testLines,
|
|
4447
4475
|
testIds,
|
|
4476
|
+
testNames,
|
|
4448
4477
|
testNamePattern,
|
|
4449
4478
|
testTagsFilter,
|
|
4450
4479
|
fileTags: docblocks[index].tags
|
|
@@ -4638,8 +4667,7 @@ class BrowserWorker {
|
|
|
4638
4667
|
this.busySessions.clear();
|
|
4639
4668
|
this.readySessions.clear();
|
|
4640
4669
|
await closeProvider(this.project, options);
|
|
4641
|
-
|
|
4642
|
-
sessionIds.forEach((sessionId) => sessions.sessionIds.delete(sessionId));
|
|
4670
|
+
sessionIds.forEach((sessionId) => sessions.close(sessionId));
|
|
4643
4671
|
orchestrators.forEach((orchestrator) => orchestrator?.$close());
|
|
4644
4672
|
}
|
|
4645
4673
|
async openPage(sessionId, options) {
|
|
@@ -6120,6 +6148,7 @@ function createPool(ctx) {
|
|
|
6120
6148
|
testLocations: spec.testLines,
|
|
6121
6149
|
testNamePattern: spec.testNamePattern,
|
|
6122
6150
|
testIds: spec.testIds,
|
|
6151
|
+
testNames: spec.testNames,
|
|
6123
6152
|
testTagsFilter: spec.testTagsFilter
|
|
6124
6153
|
})),
|
|
6125
6154
|
invalidates,
|
|
@@ -6356,6 +6385,10 @@ class TestSpecification {
|
|
|
6356
6385
|
*/
|
|
6357
6386
|
testIds;
|
|
6358
6387
|
/**
|
|
6388
|
+
* The full names of the tests inside of this specification to run, including the parent suites separated with `>`.
|
|
6389
|
+
*/
|
|
6390
|
+
testNames;
|
|
6391
|
+
/**
|
|
6359
6392
|
* The tags of tests to run.
|
|
6360
6393
|
*/
|
|
6361
6394
|
testTagsFilter;
|
|
@@ -6379,6 +6412,7 @@ class TestSpecification {
|
|
|
6379
6412
|
this.testLines = testLinesOrOptions.testLines;
|
|
6380
6413
|
this.testNamePattern = testLinesOrOptions.testNamePattern;
|
|
6381
6414
|
this.testIds = testLinesOrOptions.testIds;
|
|
6415
|
+
this.testNames = testLinesOrOptions.testNames;
|
|
6382
6416
|
this.testTagsFilter = testLinesOrOptions.testTagsFilter;
|
|
6383
6417
|
}
|
|
6384
6418
|
}
|
|
@@ -6401,6 +6435,7 @@ class TestSpecification {
|
|
|
6401
6435
|
pool: this.pool,
|
|
6402
6436
|
testLines: this.testLines,
|
|
6403
6437
|
testIds: this.testIds,
|
|
6438
|
+
testNames: this.testNames,
|
|
6404
6439
|
testNamePattern: this.testNamePattern,
|
|
6405
6440
|
testTagsFilter: this.testTagsFilter
|
|
6406
6441
|
}
|
|
@@ -6478,10 +6513,8 @@ class TestProject {
|
|
|
6478
6513
|
*/
|
|
6479
6514
|
getProvidedContext() {
|
|
6480
6515
|
if (this.isRootProject()) return this._provided;
|
|
6481
|
-
// globalSetup can run even if core workspace is not part of the test run
|
|
6482
|
-
// so we need to inherit its provided context
|
|
6483
6516
|
return {
|
|
6484
|
-
...this.vitest.getRootProject().getProvidedContext(),
|
|
6517
|
+
...(this._instanceParent ?? this.vitest.getRootProject()).getProvidedContext(),
|
|
6485
6518
|
...this._provided
|
|
6486
6519
|
};
|
|
6487
6520
|
}
|
|
@@ -6534,10 +6567,14 @@ class TestProject {
|
|
|
6534
6567
|
/** @internal */
|
|
6535
6568
|
async _initializeGlobalSetup() {
|
|
6536
6569
|
if (this._globalSetups) return;
|
|
6570
|
+
// the project that declares browser instances runs their inherited global setup once
|
|
6571
|
+
const parent = this._instanceParent;
|
|
6572
|
+
await parent?._initializeGlobalSetup();
|
|
6573
|
+
const globalSetup = parent ? toArray(this.config.globalSetup).filter((file) => !parent.config.globalSetup.includes(file)) : this.config.globalSetup;
|
|
6537
6574
|
const native = this.runner instanceof NativeModuleRunner;
|
|
6538
6575
|
// global setup is imported by this process, so its imports are only known to a resolve hook
|
|
6539
6576
|
const canRecord = !native || !this.vitest.config.experimental.recordDependencies || !this.config.globalSetup.length || trackNativeImports();
|
|
6540
|
-
this._globalSetups = await loadGlobalSetupFiles(this.runner,
|
|
6577
|
+
this._globalSetups = await loadGlobalSetupFiles(this.runner, globalSetup);
|
|
6541
6578
|
if (canRecord) this.vitest.cache._dependencies.recordGlobalSetup(this, collectDependencies(native ? nativeImports.getImports : getEvaluatedImports(this.runner.evaluatedModules), this.config.globalSetup));
|
|
6542
6579
|
for (const globalSetupFile of this._globalSetups) {
|
|
6543
6580
|
const teardown = await globalSetupFile.setup?.(this);
|
|
@@ -6655,6 +6692,10 @@ class TestProject {
|
|
|
6655
6692
|
_parentBrowser;
|
|
6656
6693
|
/** @internal */
|
|
6657
6694
|
_parent;
|
|
6695
|
+
/** @internal */
|
|
6696
|
+
get _instanceParent() {
|
|
6697
|
+
return this._parent?._parentBrowser ? this._parent : void 0;
|
|
6698
|
+
}
|
|
6658
6699
|
/**
|
|
6659
6700
|
* Closes the project and all associated resources. This can only be called once; the closing promise is cached until the server restarts.
|
|
6660
6701
|
* If the resources are needed again, create a new project.
|
|
@@ -8465,12 +8506,14 @@ class Logger {
|
|
|
8465
8506
|
const config = this.ctx.config;
|
|
8466
8507
|
// test files were found, but none of them depend on the changed files
|
|
8467
8508
|
const noAffectedTests = !!this.ctx._sourceFilterResult?.total;
|
|
8468
|
-
|
|
8469
|
-
|
|
8509
|
+
// test files were found, but none of them failed in the last run
|
|
8510
|
+
const noFailedTests = !!this.ctx._failedFilterResult?.total;
|
|
8511
|
+
const message = noFailedTests ? "No failed tests found" : !noAffectedTests ? "No test files found" : config.related?.length ? "No affected test files found" : "No changed files found";
|
|
8512
|
+
if (config.watch && (noAffectedTests || noFailedTests)) this.log(`${message}\n`);
|
|
8470
8513
|
else if (config.watch) this.log($.red(`${message}. You can change the file name pattern by pressing "p"\n`));
|
|
8471
8514
|
else if (config.passWithNoTests) this.log(`${message}, exiting with code 0\n`);
|
|
8472
8515
|
else this.error($.red(`${message}, exiting with code 1\n`));
|
|
8473
|
-
if (noAffectedTests) return;
|
|
8516
|
+
if (noAffectedTests || noFailedTests) return;
|
|
8474
8517
|
const comma = $.dim(", ");
|
|
8475
8518
|
if (filters?.length) this.console.error($.dim("filter: ") + $.yellow(filters.join(comma)));
|
|
8476
8519
|
const projectsFilter = toArray(config.project);
|
|
@@ -8640,6 +8683,7 @@ class PluginHarness {
|
|
|
8640
8683
|
}
|
|
8641
8684
|
}
|
|
8642
8685
|
|
|
8686
|
+
const builtinVCSProviders = /* @__PURE__ */ new Set(["git", "mtime"]);
|
|
8643
8687
|
function resolvePath(path, root) {
|
|
8644
8688
|
// local-pkg (mlly)'s resolveModule("./file", { paths: ["/some/root"] }) tries
|
|
8645
8689
|
// /some/file
|
|
@@ -8891,6 +8935,14 @@ function resolveTestConfig(logger, options, viteConfig, globalConfig) {
|
|
|
8891
8935
|
if (!textSummary) resolved.coverage.reporter.push(["text-summary", {}]);
|
|
8892
8936
|
}
|
|
8893
8937
|
}
|
|
8938
|
+
// CLI options are merged into the test config
|
|
8939
|
+
if (options.sinceLastRun) {
|
|
8940
|
+
if (resolved.cache === false) throw new Error("The \"--since-last-run\" flag requires the \"cache\" option to store the dependencies of the test files.");
|
|
8941
|
+
resolved.changed ||= true;
|
|
8942
|
+
resolved.experimental ??= {};
|
|
8943
|
+
resolved.experimental.recordDependencies = true;
|
|
8944
|
+
resolved.experimental.vcsProvider = "mtime";
|
|
8945
|
+
}
|
|
8894
8946
|
if (resolved.coverage.changed === void 0 && resolved.changed !== void 0) resolved.coverage.changed = resolved.changed;
|
|
8895
8947
|
if (resolved.coverage.enabled && resolved.coverage.reportsDirectory) {
|
|
8896
8948
|
const reportsDirectory = resolve(resolved.root, resolved.coverage.reportsDirectory);
|
|
@@ -9112,11 +9164,13 @@ function resolveTestConfig(logger, options, viteConfig, globalConfig) {
|
|
|
9112
9164
|
resolved.browser.traceView = typeof traceView === "object" ? {
|
|
9113
9165
|
enabled: traceView.enabled ?? false,
|
|
9114
9166
|
recordCanvas: traceView.recordCanvas ?? false,
|
|
9115
|
-
inlineImages: traceView.inlineImages ?? false
|
|
9167
|
+
inlineImages: traceView.inlineImages ?? false,
|
|
9168
|
+
ariaSnapshot: traceView.ariaSnapshot ?? true
|
|
9116
9169
|
} : {
|
|
9117
9170
|
enabled: traceView ?? false,
|
|
9118
9171
|
recordCanvas: false,
|
|
9119
|
-
inlineImages: false
|
|
9172
|
+
inlineImages: false,
|
|
9173
|
+
ariaSnapshot: true
|
|
9120
9174
|
};
|
|
9121
9175
|
if (resolved.browser.enabled && resolved.browser.traceView.enabled) resolved.browser.detailsPanelPosition = "bottom";
|
|
9122
9176
|
if (resolved.browser.trace.tracesDir != null) resolved.browser.trace.tracesDir = resolvePath(resolved.browser.trace.tracesDir, resolved.root);
|
|
@@ -9165,7 +9219,7 @@ function resolveTestConfig(logger, options, viteConfig, globalConfig) {
|
|
|
9165
9219
|
import: diagnostics.import ?? true,
|
|
9166
9220
|
transform: diagnostics.transform ?? true
|
|
9167
9221
|
};
|
|
9168
|
-
if (typeof resolved.experimental.vcsProvider === "string" && resolved.experimental.vcsProvider
|
|
9222
|
+
if (typeof resolved.experimental.vcsProvider === "string" && !builtinVCSProviders.has(resolved.experimental.vcsProvider)) resolved.experimental.vcsProvider = resolvePath(resolved.experimental.vcsProvider, resolved.root);
|
|
9169
9223
|
// `experimental.fsModuleCache` / `experimental.fsModuleCachePath` were promoted to
|
|
9170
9224
|
// the top-level `fsModuleCache` / `fsModuleCachePath` options.
|
|
9171
9225
|
const legacyExperimental = options.experimental;
|
|
@@ -9242,7 +9296,6 @@ async function resolveConfig(options = {}, viteOverrides = {}, pluginsHarness =
|
|
|
9242
9296
|
const rootConfig = resolveTestConfig(pluginsHarness.logger, rootViteConfig.test || {}, rootViteConfig);
|
|
9243
9297
|
rootViteConfig.test = rootConfig;
|
|
9244
9298
|
rootViteConfig.server.fs.allow.push(...resolveFsAllow(rootViteConfig.root, rootViteConfig.configFile));
|
|
9245
|
-
rootViteConfig.server.fs.deny.push(API_TOKEN_FILE);
|
|
9246
9299
|
// the server has been created, we don't need to override vite.server options
|
|
9247
9300
|
const { token, tokenCreated } = resolveApiToken(rootViteConfig.root);
|
|
9248
9301
|
rootConfig.api.token = token;
|
|
@@ -15603,4 +15656,4 @@ var index = /*#__PURE__*/_mergeNamespaces({
|
|
|
15603
15656
|
default: prompt
|
|
15604
15657
|
}, [promptsExports]);
|
|
15605
15658
|
|
|
15606
|
-
export {
|
|
15659
|
+
export { generateCodeFrame as A, BaseSequencer as B, printStack as C, LocationFilterFileNotFoundError as D, GitCommandError as E, ForksPoolWorker as F, GitNotFoundError as G, VitestResolver as H, IncludeTaskLocationDisabledError as I, createClusterServer as J, attachProjectsFromEntries as K, Logger as L, ModuleTransformService as M, TestProject as N, resolveAndAttachProjects as O, PluginHarness as P, RandomSequencer as Q, RangeLocationFilterProvidedError as R, ServerModuleRunner as S, ThreadsPoolWorker as T, createPool as U, VitestPackageInstaller as V, astCollectTests as W, createFailedFileTask as X, matchesProjectFilter as Y, nanoid as Z, stdout as _, BrowserConnectionError as a, FilesNotFoundError as b, TypecheckPoolWorker as c, VmForksPoolWorker as d, VmThreadsPoolWorker as e, createDebugger as f, createMethodsRPC as g, createViteLogger as h, escapeTestName as i, getFilePoolName as j, isFileServingAllowed as k, resolveConfig as l, resolveFsAllow as m, findConfigFile as n, parse as o, prompt as p, getSpecificationDocblock as q, resolveApiServerConfig as r, stringify as s, resolveStaticMocks as t, getStaticMocks as u, hash as v, resolveCoverageReporters as w, createIndexLocationsMap as x, getOutputFile as y, groupBy as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isMainThread, parentPort } from 'node:worker_threads';
|
|
2
|
-
import { i as init } from './init.
|
|
2
|
+
import { i as init } from './init.DVorxUyL.js';
|
|
3
3
|
|
|
4
4
|
if (isMainThread || !parentPort) throw new Error("Expected worker to be run in node:worker_threads");
|
|
5
5
|
function workerInit(options) {
|
|
@@ -2,12 +2,12 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import module$1, { isBuiltin } from 'node:module';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import { EvaluatedModules, ModuleRunner } from 'vite/module-runner';
|
|
5
|
-
import { e as environments, b as VitestTransport } from './index.
|
|
5
|
+
import { e as environments, b as VitestTransport } from './index.BFXLpwll.js';
|
|
6
6
|
import { r as resolve } from './pathe.M-eThtNZ.Ba-7h1rE.js';
|
|
7
|
-
import { b as serializeValue, c as createStackString, p as parseStacktrace } from './source-map.
|
|
7
|
+
import { b as serializeValue, c as createStackString, p as parseStacktrace } from './source-map.BjWcsIL9.js';
|
|
8
8
|
import { w } from './tinyrainbow.Do8I1XRG.js';
|
|
9
9
|
import { Traces } from '../traces.js';
|
|
10
|
-
import { o as onCancel, V as VitestEvaluatedModules, a as rpcDone, c as createRuntimeRpc } from './rpc.
|
|
10
|
+
import { o as onCancel, V as VitestEvaluatedModules, a as rpcDone, c as createRuntimeRpc } from './rpc.BV0XpJ5q.js';
|
|
11
11
|
import { s as setupInspect } from './inspector.CvyFGlXm.js';
|
|
12
12
|
import { E as EnvironmentTeardownError } from './utils.DYj33du9.js';
|
|
13
13
|
|
|
@@ -4,7 +4,7 @@ import { automockModule, createManualModuleSource, collectModuleExports } from '
|
|
|
4
4
|
import { c as cleanUrl, e as createDefer, i as isAbsolute } from './pathe.M-eThtNZ.Ba-7h1rE.js';
|
|
5
5
|
import { p as parse } from './acorn.C1kjbUFw.js';
|
|
6
6
|
import { t as toBuiltin } from './modules.BJuCwlRJ.js';
|
|
7
|
-
import { B as BareModuleMocker, n as normalizeModuleId } from './index.
|
|
7
|
+
import { B as BareModuleMocker, n as normalizeModuleId } from './index.BFXLpwll.js';
|
|
8
8
|
import 'node:fs';
|
|
9
9
|
import './utils.DYj33du9.js';
|
|
10
10
|
import '../path.js';
|
|
@@ -13,18 +13,22 @@ import '../module-evaluator.js';
|
|
|
13
13
|
import 'node:vm';
|
|
14
14
|
import 'vite/module-runner';
|
|
15
15
|
import '../traces.js';
|
|
16
|
+
import 'node:async_hooks';
|
|
16
17
|
import '@vitest/mocker';
|
|
17
18
|
import '@vitest/mocker/redirect';
|
|
18
19
|
import 'node:console';
|
|
19
20
|
|
|
20
21
|
class NativeModuleMocker extends BareModuleMocker {
|
|
21
22
|
wrapDynamicImport(moduleFactory) {
|
|
22
|
-
if (typeof moduleFactory
|
|
23
|
+
if (typeof moduleFactory !== "function") return moduleFactory;
|
|
24
|
+
// Node.js can evaluate the module outside of the importer's async chain,
|
|
25
|
+
// so the stack of an import error would not point at the import
|
|
26
|
+
const importer = /* @__PURE__ */ new Error("import location");
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
23
28
|
this.resolveMocks().finally(() => {
|
|
24
|
-
moduleFactory().then(resolve, reject);
|
|
29
|
+
moduleFactory().then(resolve, (error) => reject(addImporterFrame(error, importer)));
|
|
25
30
|
});
|
|
26
31
|
});
|
|
27
|
-
return moduleFactory;
|
|
28
32
|
}
|
|
29
33
|
resolveMockedModule(url, parentURL) {
|
|
30
34
|
// don't mock modules inside of packages because there is
|
|
@@ -209,5 +213,23 @@ function transformCode(code, format, filename) {
|
|
|
209
213
|
}
|
|
210
214
|
return code;
|
|
211
215
|
}
|
|
216
|
+
function addImporterFrame(error, importer) {
|
|
217
|
+
const lines = importer.stack?.split("\n") || [];
|
|
218
|
+
const index = lines.findIndex((line) => line.includes("wrapDynamicImport"));
|
|
219
|
+
const frame = index === -1 ? void 0 : lines[index + 1];
|
|
220
|
+
const file = frame?.match(/\(?([^()\s]+):\d+:\d+\)?$/)?.[1];
|
|
221
|
+
if (!frame || !file || frame.includes("node:")) return error;
|
|
222
|
+
const asyncFrame = frame.replace(/^(\s*)at /, "$1at async ");
|
|
223
|
+
const seen = /* @__PURE__ */ new Set();
|
|
224
|
+
let current = error;
|
|
225
|
+
while (current instanceof Error && !seen.has(current)) {
|
|
226
|
+
seen.add(current);
|
|
227
|
+
const stack = current.stack;
|
|
228
|
+
// older Node.js versions keep the async frame of the import themselves
|
|
229
|
+
if (typeof stack === "string" && !stack.split("\n").some((line) => line.includes("at async ") && line.includes(file))) current.stack = `${stack}\n${asyncFrame}`;
|
|
230
|
+
current = current.cause;
|
|
231
|
+
}
|
|
232
|
+
return error;
|
|
233
|
+
}
|
|
212
234
|
|
|
213
235
|
export { NativeModuleMocker };
|