vitest 3.0.8 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +12 -23
- package/dist/browser.js +2 -2
- package/dist/chunks/{base.XvKTsMeK.js → base.DV59CbtV.js} +1 -1
- package/dist/chunks/{benchmark.Cdu9hjj4.js → benchmark.DL72EVN-.js} +1 -1
- package/dist/chunks/{benchmark.CFFwLv-O.d.ts → benchmark.d.BwvBVTda.d.ts} +11 -11
- package/dist/chunks/{cac.VN5q-TPC.js → cac.CeVHgzve.js} +5 -5
- package/dist/chunks/{cli-api.Dis64jtY.js → cli-api.Ckwz_xSb.js} +13 -8
- package/dist/chunks/config.d.DevWltVl.d.ts +218 -0
- package/dist/chunks/{constants.fzPh7AOq.js → constants.DTYd6dNH.js} +1 -1
- package/dist/chunks/{coverage.DnNIv-kJ.js → coverage.A3sS5-Wm.js} +1 -29
- package/dist/chunks/coverage.d.S9RMNXIe.d.ts +35 -0
- package/dist/chunks/{resolveConfig.L1_HR0_0.js → coverage.gV8doR2Y.js} +496 -127
- package/dist/chunks/{creator.2CFRE1Yx.js → creator.BsBnpTzI.js} +1 -1
- package/dist/chunks/defaults.C2Ndd9wx.js +119 -0
- package/dist/chunks/env.D4Lgay0q.js +8 -0
- package/dist/chunks/environment.d.C8UItCbf.d.ts +170 -0
- package/dist/chunks/global.d.Cg2sEPIm.d.ts +127 -0
- package/dist/chunks/{globals.CydvVTgC.js → globals.BEpDe-k3.js} +4 -4
- package/dist/chunks/{index.B7vJpkTD.js → index.B8tIoLPT.js} +6 -1
- package/dist/chunks/{index.CNRemkXW.js → index.D7Ny8f_s.js} +2 -2
- package/dist/chunks/{index.BmFgJtkv.js → index.uXkkC4xl.js} +1 -2
- package/dist/chunks/{mocker.cRtM890J.d.ts → mocker.d.BE_2ls6u.d.ts} +6 -6
- package/dist/chunks/reporters.d.CqBhtcTq.d.ts +3006 -0
- package/dist/chunks/{runBaseTests.DnaAUBKD.js → runBaseTests.BVrL_ow3.js} +8 -8
- package/dist/chunks/{setup-common.Uaw6Zgv9.js → setup-common.CPvtqi8q.js} +25 -2
- package/dist/chunks/{suite.qtkXWc6R.d.ts → suite.d.FvehnV49.d.ts} +1 -1
- package/dist/chunks/{typechecker.cZ0LjdSi.js → typechecker.BlF3eHsb.js} +2 -7
- package/dist/chunks/{vi.B5EKKJdE.js → vi.nSCvwQ7l.js} +3 -3
- package/dist/chunks/vite.d.BUZTGxQ3.d.ts +11 -0
- package/dist/chunks/{worker.BmVno_ab.d.ts → worker.d.C58isfFm.d.ts} +62 -62
- package/dist/chunks/{worker.BT4v-DKx.d.ts → worker.d.CSFlSYJg.d.ts} +2 -2
- package/dist/cli.js +2 -2
- package/dist/config.d.ts +48 -45
- package/dist/config.js +6 -123
- package/dist/coverage.d.ts +82 -79
- package/dist/coverage.js +19 -469
- package/dist/environments.d.ts +11 -11
- package/dist/execute.d.ts +109 -109
- package/dist/index.d.ts +414 -412
- package/dist/index.js +3 -3
- package/dist/node.d.ts +51 -48
- package/dist/node.js +13 -10
- package/dist/reporters.d.ts +7 -4
- package/dist/reporters.js +3 -2
- package/dist/runners.d.ts +28 -28
- package/dist/runners.js +2 -3
- package/dist/snapshot.d.ts +2 -2
- package/dist/suite.d.ts +2 -2
- package/dist/suite.js +1 -1
- package/dist/workers/forks.js +1 -1
- package/dist/workers/runVmTests.js +8 -8
- package/dist/workers/threads.js +1 -1
- package/dist/workers.d.ts +13 -13
- package/dist/workers.js +1 -1
- package/package.json +11 -11
- package/dist/chunks/config.BCv-fVdT.d.ts +0 -215
- package/dist/chunks/environment.d8YfPkTm.d.ts +0 -173
- package/dist/chunks/global.CnI8_G5V.d.ts +0 -133
- package/dist/chunks/reporters.66aFHiyX.d.ts +0 -3051
- package/dist/chunks/vite.BCQa3xFG.d.ts +0 -11
|
@@ -1,33 +1,36 @@
|
|
|
1
|
+
import fs, { statSync, realpathSync, promises as promises$1, mkdirSync, existsSync, readdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
|
|
3
|
+
import require$$0 from 'util';
|
|
4
|
+
import require$$0$1 from 'path';
|
|
5
|
+
import { relative, resolve, dirname, isAbsolute, join, normalize } from 'pathe';
|
|
6
|
+
import c from 'tinyrainbow';
|
|
7
|
+
import { c as configDefaults, e as benchmarkConfigDefaults, a as coverageConfigDefaults } from './defaults.C2Ndd9wx.js';
|
|
1
8
|
import crypto from 'node:crypto';
|
|
2
9
|
import { slash, createDefer, shuffle, toArray } from '@vitest/utils';
|
|
3
|
-
import
|
|
4
|
-
import { writeFile } from 'node:fs/promises';
|
|
10
|
+
import { writeFile, rename, stat, unlink } from 'node:fs/promises';
|
|
5
11
|
import { builtinModules, createRequire } from 'node:module';
|
|
6
12
|
import p, { win32, resolve as resolve$1 } from 'node:path';
|
|
7
13
|
import process$1 from 'node:process';
|
|
8
14
|
import { fileURLToPath as fileURLToPath$1, pathToFileURL as pathToFileURL$1, URL as URL$1 } from 'node:url';
|
|
9
|
-
import { relative, resolve, dirname, isAbsolute, join, normalize } from 'pathe';
|
|
10
15
|
import assert from 'node:assert';
|
|
11
16
|
import v8 from 'node:v8';
|
|
12
17
|
import { format, inspect } from 'node:util';
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
18
|
+
import { e as extraInlineDeps, d as defaultBrowserPort, b as defaultInspectPort, a as defaultPort } from './constants.DTYd6dNH.js';
|
|
19
|
+
import { a as isWindows } from './env.D4Lgay0q.js';
|
|
15
20
|
import * as nodeos from 'node:os';
|
|
16
21
|
import nodeos__default from 'node:os';
|
|
17
|
-
import { w as wrapSerializableConfig, a as Typechecker, b as isWindows } from './typechecker.cZ0LjdSi.js';
|
|
18
|
-
import { isCI, provider } from 'std-env';
|
|
19
22
|
import { isatty } from 'node:tty';
|
|
20
|
-
import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
|
|
21
|
-
import require$$0 from 'util';
|
|
22
|
-
import require$$0$1 from 'path';
|
|
23
23
|
import { version } from 'vite';
|
|
24
24
|
import EventEmitter from 'node:events';
|
|
25
25
|
import { c as createBirpc } from './index.68735LiX.js';
|
|
26
26
|
import Tinypool$1, { Tinypool } from 'tinypool';
|
|
27
|
+
import { w as wrapSerializableConfig, a as Typechecker } from './typechecker.BlF3eHsb.js';
|
|
27
28
|
import { MessageChannel } from 'node:worker_threads';
|
|
28
29
|
import { hasFailed } from '@vitest/runner/utils';
|
|
29
30
|
import { rootDir } from '../path.js';
|
|
30
31
|
import { slash as slash$1 } from 'vite-node/utils';
|
|
32
|
+
import { isCI, provider } from 'std-env';
|
|
33
|
+
import { r as resolveCoverageProviderModule } from './coverage.A3sS5-Wm.js';
|
|
31
34
|
|
|
32
35
|
function groupBy(collection, iteratee) {
|
|
33
36
|
return collection.reduce((acc, item) => {
|
|
@@ -2302,120 +2305,6 @@ function resolvePackage(name, options = {}) {
|
|
|
2302
2305
|
}
|
|
2303
2306
|
}
|
|
2304
2307
|
|
|
2305
|
-
const defaultInclude = ["**/*.{test,spec}.?(c|m)[jt]s?(x)"];
|
|
2306
|
-
const defaultExclude = [
|
|
2307
|
-
"**/node_modules/**",
|
|
2308
|
-
"**/dist/**",
|
|
2309
|
-
"**/cypress/**",
|
|
2310
|
-
"**/.{idea,git,cache,output,temp}/**",
|
|
2311
|
-
"**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*"
|
|
2312
|
-
];
|
|
2313
|
-
const benchmarkConfigDefaults = {
|
|
2314
|
-
include: ["**/*.{bench,benchmark}.?(c|m)[jt]s?(x)"],
|
|
2315
|
-
exclude: defaultExclude,
|
|
2316
|
-
includeSource: [],
|
|
2317
|
-
reporters: ["default"],
|
|
2318
|
-
includeSamples: false
|
|
2319
|
-
};
|
|
2320
|
-
const defaultCoverageExcludes = [
|
|
2321
|
-
"coverage/**",
|
|
2322
|
-
"dist/**",
|
|
2323
|
-
"**/node_modules/**",
|
|
2324
|
-
"**/[.]**",
|
|
2325
|
-
"packages/*/test?(s)/**",
|
|
2326
|
-
"**/*.d.ts",
|
|
2327
|
-
"**/virtual:*",
|
|
2328
|
-
"**/__x00__*",
|
|
2329
|
-
"**/\0*",
|
|
2330
|
-
"cypress/**",
|
|
2331
|
-
"test?(s)/**",
|
|
2332
|
-
"test?(-*).?(c|m)[jt]s?(x)",
|
|
2333
|
-
"**/*{.,-}{test,spec,bench,benchmark}?(-d).?(c|m)[jt]s?(x)",
|
|
2334
|
-
"**/__tests__/**",
|
|
2335
|
-
"**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*",
|
|
2336
|
-
"**/vitest.{workspace,projects}.[jt]s?(on)",
|
|
2337
|
-
"**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}"
|
|
2338
|
-
];
|
|
2339
|
-
const coverageConfigDefaults = {
|
|
2340
|
-
provider: "v8",
|
|
2341
|
-
enabled: false,
|
|
2342
|
-
all: true,
|
|
2343
|
-
clean: true,
|
|
2344
|
-
cleanOnRerun: true,
|
|
2345
|
-
reportsDirectory: "./coverage",
|
|
2346
|
-
exclude: defaultCoverageExcludes,
|
|
2347
|
-
reportOnFailure: false,
|
|
2348
|
-
reporter: [
|
|
2349
|
-
["text", {}],
|
|
2350
|
-
["html", {}],
|
|
2351
|
-
["clover", {}],
|
|
2352
|
-
["json", {}]
|
|
2353
|
-
],
|
|
2354
|
-
extension: [
|
|
2355
|
-
".js",
|
|
2356
|
-
".cjs",
|
|
2357
|
-
".mjs",
|
|
2358
|
-
".ts",
|
|
2359
|
-
".mts",
|
|
2360
|
-
".tsx",
|
|
2361
|
-
".jsx",
|
|
2362
|
-
".vue",
|
|
2363
|
-
".svelte",
|
|
2364
|
-
".marko",
|
|
2365
|
-
".astro"
|
|
2366
|
-
],
|
|
2367
|
-
allowExternal: false,
|
|
2368
|
-
excludeAfterRemap: false,
|
|
2369
|
-
ignoreEmptyLines: true,
|
|
2370
|
-
processingConcurrency: Math.min(
|
|
2371
|
-
20,
|
|
2372
|
-
nodeos__default.availableParallelism?.() ?? nodeos__default.cpus().length
|
|
2373
|
-
)
|
|
2374
|
-
};
|
|
2375
|
-
const fakeTimersDefaults = {
|
|
2376
|
-
loopLimit: 1e4,
|
|
2377
|
-
shouldClearNativeTimers: true
|
|
2378
|
-
};
|
|
2379
|
-
const configDefaults = Object.freeze({
|
|
2380
|
-
allowOnly: !isCI,
|
|
2381
|
-
isolate: true,
|
|
2382
|
-
watch: !isCI,
|
|
2383
|
-
globals: false,
|
|
2384
|
-
environment: "node",
|
|
2385
|
-
pool: "forks",
|
|
2386
|
-
clearMocks: false,
|
|
2387
|
-
restoreMocks: false,
|
|
2388
|
-
mockReset: false,
|
|
2389
|
-
unstubGlobals: false,
|
|
2390
|
-
unstubEnvs: false,
|
|
2391
|
-
include: defaultInclude,
|
|
2392
|
-
exclude: defaultExclude,
|
|
2393
|
-
teardownTimeout: 1e4,
|
|
2394
|
-
forceRerunTriggers: ["**/package.json/**", "**/{vitest,vite}.config.*/**"],
|
|
2395
|
-
update: false,
|
|
2396
|
-
reporters: [],
|
|
2397
|
-
silent: false,
|
|
2398
|
-
hideSkippedTests: false,
|
|
2399
|
-
api: false,
|
|
2400
|
-
ui: false,
|
|
2401
|
-
uiBase: "/__vitest__/",
|
|
2402
|
-
open: !isCI,
|
|
2403
|
-
css: {
|
|
2404
|
-
include: []
|
|
2405
|
-
},
|
|
2406
|
-
coverage: coverageConfigDefaults,
|
|
2407
|
-
fakeTimers: fakeTimersDefaults,
|
|
2408
|
-
maxConcurrency: 5,
|
|
2409
|
-
dangerouslyIgnoreUnhandledErrors: false,
|
|
2410
|
-
typecheck: {
|
|
2411
|
-
checker: "tsc",
|
|
2412
|
-
include: ["**/*.{test,spec}-d.?(c|m)[jt]s?(x)"],
|
|
2413
|
-
exclude: defaultExclude
|
|
2414
|
-
},
|
|
2415
|
-
slowTestThreshold: 300,
|
|
2416
|
-
disableConsoleIntercept: false
|
|
2417
|
-
});
|
|
2418
|
-
|
|
2419
2308
|
function getWorkersCountByPercentage(percent) {
|
|
2420
2309
|
const maxWorkersCount = nodeos__default.availableParallelism?.() ?? nodeos__default.cpus().length;
|
|
2421
2310
|
const workersCountByPercentage = Math.round(Number.parseInt(percent) / 100 * maxWorkersCount);
|
|
@@ -6650,7 +6539,7 @@ function createMethodsRPC(project, options = {}) {
|
|
|
6650
6539
|
}
|
|
6651
6540
|
promises.set(
|
|
6652
6541
|
tmp,
|
|
6653
|
-
writeFile(tmp, code, "utf-8").finally(() => promises.delete(tmp))
|
|
6542
|
+
atomicWriteFile(tmp, code).catch(() => writeFile(tmp, code, "utf-8")).finally(() => promises.delete(tmp))
|
|
6654
6543
|
);
|
|
6655
6544
|
await promises.get(tmp);
|
|
6656
6545
|
Object.assign(result, { id: tmp });
|
|
@@ -6721,6 +6610,21 @@ function handleRollupError(e) {
|
|
|
6721
6610
|
}
|
|
6722
6611
|
throw e;
|
|
6723
6612
|
}
|
|
6613
|
+
async function atomicWriteFile(realFilePath, data) {
|
|
6614
|
+
const dir = dirname(realFilePath);
|
|
6615
|
+
const tmpFilePath = join(dir, `.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
6616
|
+
try {
|
|
6617
|
+
await writeFile(tmpFilePath, data, "utf-8");
|
|
6618
|
+
await rename(tmpFilePath, realFilePath);
|
|
6619
|
+
} finally {
|
|
6620
|
+
try {
|
|
6621
|
+
if (await stat(tmpFilePath)) {
|
|
6622
|
+
await unlink(tmpFilePath);
|
|
6623
|
+
}
|
|
6624
|
+
} catch {
|
|
6625
|
+
}
|
|
6626
|
+
}
|
|
6627
|
+
}
|
|
6724
6628
|
|
|
6725
6629
|
function createChildProcessChannel$1(project, collect = false) {
|
|
6726
6630
|
const emitter = new EventEmitter();
|
|
@@ -7875,7 +7779,7 @@ function resolveInlineWorkerOption(value) {
|
|
|
7875
7779
|
return Number(value);
|
|
7876
7780
|
}
|
|
7877
7781
|
}
|
|
7878
|
-
function resolveConfig(vitest, options, viteConfig) {
|
|
7782
|
+
function resolveConfig$1(vitest, options, viteConfig) {
|
|
7879
7783
|
const mode = vitest.mode;
|
|
7880
7784
|
const logger = vitest.logger;
|
|
7881
7785
|
if (options.dom) {
|
|
@@ -8500,4 +8404,469 @@ function isPlaywrightChromiumOnly(vitest, config) {
|
|
|
8500
8404
|
return true;
|
|
8501
8405
|
}
|
|
8502
8406
|
|
|
8503
|
-
|
|
8407
|
+
const THRESHOLD_KEYS = [
|
|
8408
|
+
"lines",
|
|
8409
|
+
"functions",
|
|
8410
|
+
"statements",
|
|
8411
|
+
"branches"
|
|
8412
|
+
];
|
|
8413
|
+
const GLOBAL_THRESHOLDS_KEY = "global";
|
|
8414
|
+
const DEFAULT_PROJECT = Symbol.for("default-project");
|
|
8415
|
+
let uniqueId = 0;
|
|
8416
|
+
async function getCoverageProvider(options, loader) {
|
|
8417
|
+
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
8418
|
+
if (coverageModule) {
|
|
8419
|
+
return coverageModule.getProvider();
|
|
8420
|
+
}
|
|
8421
|
+
return null;
|
|
8422
|
+
}
|
|
8423
|
+
class BaseCoverageProvider {
|
|
8424
|
+
ctx;
|
|
8425
|
+
name;
|
|
8426
|
+
version;
|
|
8427
|
+
options;
|
|
8428
|
+
coverageFiles = /* @__PURE__ */ new Map();
|
|
8429
|
+
pendingPromises = [];
|
|
8430
|
+
coverageFilesDirectory;
|
|
8431
|
+
_initialize(ctx) {
|
|
8432
|
+
this.ctx = ctx;
|
|
8433
|
+
if (ctx.version !== this.version) {
|
|
8434
|
+
ctx.logger.warn(
|
|
8435
|
+
c.yellow(
|
|
8436
|
+
`Loaded ${c.inverse(c.yellow(` vitest@${ctx.version} `))} and ${c.inverse(c.yellow(` @vitest/coverage-${this.name}@${this.version} `))}.
|
|
8437
|
+
Running mixed versions is not supported and may lead into bugs
|
|
8438
|
+
Update your dependencies and make sure the versions match.`
|
|
8439
|
+
)
|
|
8440
|
+
);
|
|
8441
|
+
}
|
|
8442
|
+
const config = ctx.config.coverage;
|
|
8443
|
+
this.options = {
|
|
8444
|
+
...coverageConfigDefaults,
|
|
8445
|
+
// User's options
|
|
8446
|
+
...config,
|
|
8447
|
+
// Resolved fields
|
|
8448
|
+
provider: this.name,
|
|
8449
|
+
reportsDirectory: resolve(
|
|
8450
|
+
ctx.config.root,
|
|
8451
|
+
config.reportsDirectory || coverageConfigDefaults.reportsDirectory
|
|
8452
|
+
),
|
|
8453
|
+
reporter: resolveCoverageReporters(
|
|
8454
|
+
config.reporter || coverageConfigDefaults.reporter
|
|
8455
|
+
),
|
|
8456
|
+
thresholds: config.thresholds && {
|
|
8457
|
+
...config.thresholds,
|
|
8458
|
+
lines: config.thresholds["100"] ? 100 : config.thresholds.lines,
|
|
8459
|
+
branches: config.thresholds["100"] ? 100 : config.thresholds.branches,
|
|
8460
|
+
functions: config.thresholds["100"] ? 100 : config.thresholds.functions,
|
|
8461
|
+
statements: config.thresholds["100"] ? 100 : config.thresholds.statements
|
|
8462
|
+
}
|
|
8463
|
+
};
|
|
8464
|
+
const shard = this.ctx.config.shard;
|
|
8465
|
+
const tempDirectory = `.tmp${shard ? `-${shard.index}-${shard.count}` : ""}`;
|
|
8466
|
+
this.coverageFilesDirectory = resolve(
|
|
8467
|
+
this.options.reportsDirectory,
|
|
8468
|
+
tempDirectory
|
|
8469
|
+
);
|
|
8470
|
+
}
|
|
8471
|
+
createCoverageMap() {
|
|
8472
|
+
throw new Error("BaseReporter's createCoverageMap was not overwritten");
|
|
8473
|
+
}
|
|
8474
|
+
async generateReports(_, __) {
|
|
8475
|
+
throw new Error("BaseReporter's generateReports was not overwritten");
|
|
8476
|
+
}
|
|
8477
|
+
async parseConfigModule(_) {
|
|
8478
|
+
throw new Error("BaseReporter's parseConfigModule was not overwritten");
|
|
8479
|
+
}
|
|
8480
|
+
resolveOptions() {
|
|
8481
|
+
return this.options;
|
|
8482
|
+
}
|
|
8483
|
+
async clean(clean = true) {
|
|
8484
|
+
if (clean && existsSync(this.options.reportsDirectory)) {
|
|
8485
|
+
await promises$1.rm(this.options.reportsDirectory, {
|
|
8486
|
+
recursive: true,
|
|
8487
|
+
force: true,
|
|
8488
|
+
maxRetries: 10
|
|
8489
|
+
});
|
|
8490
|
+
}
|
|
8491
|
+
if (existsSync(this.coverageFilesDirectory)) {
|
|
8492
|
+
await promises$1.rm(this.coverageFilesDirectory, {
|
|
8493
|
+
recursive: true,
|
|
8494
|
+
force: true,
|
|
8495
|
+
maxRetries: 10
|
|
8496
|
+
});
|
|
8497
|
+
}
|
|
8498
|
+
await promises$1.mkdir(this.coverageFilesDirectory, { recursive: true });
|
|
8499
|
+
this.coverageFiles = /* @__PURE__ */ new Map();
|
|
8500
|
+
this.pendingPromises = [];
|
|
8501
|
+
}
|
|
8502
|
+
onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }) {
|
|
8503
|
+
if (!coverage) {
|
|
8504
|
+
return;
|
|
8505
|
+
}
|
|
8506
|
+
if (transformMode !== "web" && transformMode !== "ssr" && transformMode !== "browser") {
|
|
8507
|
+
throw new Error(`Invalid transform mode: ${transformMode}`);
|
|
8508
|
+
}
|
|
8509
|
+
let entry = this.coverageFiles.get(projectName || DEFAULT_PROJECT);
|
|
8510
|
+
if (!entry) {
|
|
8511
|
+
entry = { web: {}, ssr: {}, browser: {} };
|
|
8512
|
+
this.coverageFiles.set(projectName || DEFAULT_PROJECT, entry);
|
|
8513
|
+
}
|
|
8514
|
+
const testFilenames = testFiles.join();
|
|
8515
|
+
const filename = resolve(
|
|
8516
|
+
this.coverageFilesDirectory,
|
|
8517
|
+
`coverage-${uniqueId++}.json`
|
|
8518
|
+
);
|
|
8519
|
+
entry[transformMode][testFilenames] = filename;
|
|
8520
|
+
const promise = promises$1.writeFile(filename, JSON.stringify(coverage), "utf-8");
|
|
8521
|
+
this.pendingPromises.push(promise);
|
|
8522
|
+
}
|
|
8523
|
+
async readCoverageFiles({ onFileRead, onFinished, onDebug }) {
|
|
8524
|
+
let index = 0;
|
|
8525
|
+
const total = this.pendingPromises.length;
|
|
8526
|
+
await Promise.all(this.pendingPromises);
|
|
8527
|
+
this.pendingPromises = [];
|
|
8528
|
+
for (const [projectName, coveragePerProject] of this.coverageFiles.entries()) {
|
|
8529
|
+
for (const [transformMode, coverageByTestfiles] of Object.entries(coveragePerProject)) {
|
|
8530
|
+
const filenames = Object.values(coverageByTestfiles);
|
|
8531
|
+
const project = this.ctx.getProjectByName(projectName);
|
|
8532
|
+
for (const chunk of this.toSlices(filenames, this.options.processingConcurrency)) {
|
|
8533
|
+
if (onDebug.enabled) {
|
|
8534
|
+
index += chunk.length;
|
|
8535
|
+
onDebug("Covered files %d/%d", index, total);
|
|
8536
|
+
}
|
|
8537
|
+
await Promise.all(
|
|
8538
|
+
chunk.map(async (filename) => {
|
|
8539
|
+
const contents = await promises$1.readFile(filename, "utf-8");
|
|
8540
|
+
const coverage = JSON.parse(contents);
|
|
8541
|
+
onFileRead(coverage);
|
|
8542
|
+
})
|
|
8543
|
+
);
|
|
8544
|
+
}
|
|
8545
|
+
await onFinished(project, transformMode);
|
|
8546
|
+
}
|
|
8547
|
+
}
|
|
8548
|
+
}
|
|
8549
|
+
async cleanAfterRun() {
|
|
8550
|
+
this.coverageFiles = /* @__PURE__ */ new Map();
|
|
8551
|
+
await promises$1.rm(this.coverageFilesDirectory, { recursive: true });
|
|
8552
|
+
if (readdirSync(this.options.reportsDirectory).length === 0) {
|
|
8553
|
+
await promises$1.rm(this.options.reportsDirectory, { recursive: true });
|
|
8554
|
+
}
|
|
8555
|
+
}
|
|
8556
|
+
async onTestFailure() {
|
|
8557
|
+
if (!this.options.reportOnFailure) {
|
|
8558
|
+
await this.cleanAfterRun();
|
|
8559
|
+
}
|
|
8560
|
+
}
|
|
8561
|
+
async reportCoverage(coverageMap, { allTestsRun }) {
|
|
8562
|
+
await this.generateReports(
|
|
8563
|
+
coverageMap || this.createCoverageMap(),
|
|
8564
|
+
allTestsRun
|
|
8565
|
+
);
|
|
8566
|
+
const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch;
|
|
8567
|
+
if (!keepResults) {
|
|
8568
|
+
await this.cleanAfterRun();
|
|
8569
|
+
}
|
|
8570
|
+
}
|
|
8571
|
+
async reportThresholds(coverageMap, allTestsRun) {
|
|
8572
|
+
const resolvedThresholds = this.resolveThresholds(coverageMap);
|
|
8573
|
+
this.checkThresholds(resolvedThresholds);
|
|
8574
|
+
if (this.options.thresholds?.autoUpdate && allTestsRun) {
|
|
8575
|
+
if (!this.ctx.server.config.configFile) {
|
|
8576
|
+
throw new Error(
|
|
8577
|
+
'Missing configurationFile. The "coverage.thresholds.autoUpdate" can only be enabled when configuration file is used.'
|
|
8578
|
+
);
|
|
8579
|
+
}
|
|
8580
|
+
const configFilePath = this.ctx.server.config.configFile;
|
|
8581
|
+
const configModule = await this.parseConfigModule(configFilePath);
|
|
8582
|
+
await this.updateThresholds({
|
|
8583
|
+
thresholds: resolvedThresholds,
|
|
8584
|
+
configurationFile: configModule,
|
|
8585
|
+
onUpdate: () => writeFileSync(
|
|
8586
|
+
configFilePath,
|
|
8587
|
+
configModule.generate().code,
|
|
8588
|
+
"utf-8"
|
|
8589
|
+
)
|
|
8590
|
+
});
|
|
8591
|
+
}
|
|
8592
|
+
}
|
|
8593
|
+
/**
|
|
8594
|
+
* Constructs collected coverage and users' threshold options into separate sets
|
|
8595
|
+
* where each threshold set holds their own coverage maps. Threshold set is either
|
|
8596
|
+
* for specific files defined by glob pattern or global for all other files.
|
|
8597
|
+
*/
|
|
8598
|
+
resolveThresholds(coverageMap) {
|
|
8599
|
+
const resolvedThresholds = [];
|
|
8600
|
+
const files = coverageMap.files();
|
|
8601
|
+
const globalCoverageMap = this.createCoverageMap();
|
|
8602
|
+
for (const key of Object.keys(this.options.thresholds)) {
|
|
8603
|
+
if (key === "perFile" || key === "autoUpdate" || key === "100" || THRESHOLD_KEYS.includes(key)) {
|
|
8604
|
+
continue;
|
|
8605
|
+
}
|
|
8606
|
+
const glob = key;
|
|
8607
|
+
const globThresholds = resolveGlobThresholds(this.options.thresholds[glob]);
|
|
8608
|
+
const globCoverageMap = this.createCoverageMap();
|
|
8609
|
+
const matchingFiles = files.filter(
|
|
8610
|
+
(file) => mm.isMatch(relative(this.ctx.config.root, file), glob)
|
|
8611
|
+
);
|
|
8612
|
+
for (const file of matchingFiles) {
|
|
8613
|
+
const fileCoverage = coverageMap.fileCoverageFor(file);
|
|
8614
|
+
globCoverageMap.addFileCoverage(fileCoverage);
|
|
8615
|
+
}
|
|
8616
|
+
resolvedThresholds.push({
|
|
8617
|
+
name: glob,
|
|
8618
|
+
coverageMap: globCoverageMap,
|
|
8619
|
+
thresholds: globThresholds
|
|
8620
|
+
});
|
|
8621
|
+
}
|
|
8622
|
+
for (const file of files) {
|
|
8623
|
+
const fileCoverage = coverageMap.fileCoverageFor(file);
|
|
8624
|
+
globalCoverageMap.addFileCoverage(fileCoverage);
|
|
8625
|
+
}
|
|
8626
|
+
resolvedThresholds.unshift({
|
|
8627
|
+
name: GLOBAL_THRESHOLDS_KEY,
|
|
8628
|
+
coverageMap: globalCoverageMap,
|
|
8629
|
+
thresholds: {
|
|
8630
|
+
branches: this.options.thresholds?.branches,
|
|
8631
|
+
functions: this.options.thresholds?.functions,
|
|
8632
|
+
lines: this.options.thresholds?.lines,
|
|
8633
|
+
statements: this.options.thresholds?.statements
|
|
8634
|
+
}
|
|
8635
|
+
});
|
|
8636
|
+
return resolvedThresholds;
|
|
8637
|
+
}
|
|
8638
|
+
/**
|
|
8639
|
+
* Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
|
|
8640
|
+
*/
|
|
8641
|
+
checkThresholds(allThresholds) {
|
|
8642
|
+
for (const { coverageMap, thresholds, name } of allThresholds) {
|
|
8643
|
+
if (thresholds.branches === void 0 && thresholds.functions === void 0 && thresholds.lines === void 0 && thresholds.statements === void 0) {
|
|
8644
|
+
continue;
|
|
8645
|
+
}
|
|
8646
|
+
const summaries = this.options.thresholds?.perFile ? coverageMap.files().map((file) => ({
|
|
8647
|
+
file,
|
|
8648
|
+
summary: coverageMap.fileCoverageFor(file).toSummary()
|
|
8649
|
+
})) : [{ file: null, summary: coverageMap.getCoverageSummary() }];
|
|
8650
|
+
for (const { summary, file } of summaries) {
|
|
8651
|
+
for (const thresholdKey of THRESHOLD_KEYS) {
|
|
8652
|
+
const threshold = thresholds[thresholdKey];
|
|
8653
|
+
if (threshold === void 0) {
|
|
8654
|
+
continue;
|
|
8655
|
+
}
|
|
8656
|
+
if (threshold >= 0) {
|
|
8657
|
+
const coverage = summary.data[thresholdKey].pct;
|
|
8658
|
+
if (coverage < threshold) {
|
|
8659
|
+
process.exitCode = 1;
|
|
8660
|
+
let errorMessage = `ERROR: Coverage for ${thresholdKey} (${coverage}%) does not meet ${name === GLOBAL_THRESHOLDS_KEY ? name : `"${name}"`} threshold (${threshold}%)`;
|
|
8661
|
+
if (this.options.thresholds?.perFile && file) {
|
|
8662
|
+
errorMessage += ` for ${relative("./", file).replace(/\\/g, "/")}`;
|
|
8663
|
+
}
|
|
8664
|
+
this.ctx.logger.error(errorMessage);
|
|
8665
|
+
}
|
|
8666
|
+
} else {
|
|
8667
|
+
const uncovered = summary.data[thresholdKey].total - summary.data[thresholdKey].covered;
|
|
8668
|
+
const absoluteThreshold = threshold * -1;
|
|
8669
|
+
if (uncovered > absoluteThreshold) {
|
|
8670
|
+
process.exitCode = 1;
|
|
8671
|
+
let errorMessage = `ERROR: Uncovered ${thresholdKey} (${uncovered}) exceed ${name === GLOBAL_THRESHOLDS_KEY ? name : `"${name}"`} threshold (${absoluteThreshold})`;
|
|
8672
|
+
if (this.options.thresholds?.perFile && file) {
|
|
8673
|
+
errorMessage += ` for ${relative("./", file).replace(/\\/g, "/")}`;
|
|
8674
|
+
}
|
|
8675
|
+
this.ctx.logger.error(errorMessage);
|
|
8676
|
+
}
|
|
8677
|
+
}
|
|
8678
|
+
}
|
|
8679
|
+
}
|
|
8680
|
+
}
|
|
8681
|
+
}
|
|
8682
|
+
/**
|
|
8683
|
+
* Check if current coverage is above configured thresholds and bump the thresholds if needed
|
|
8684
|
+
*/
|
|
8685
|
+
async updateThresholds({ thresholds: allThresholds, onUpdate, configurationFile }) {
|
|
8686
|
+
let updatedThresholds = false;
|
|
8687
|
+
const config = resolveConfig(configurationFile);
|
|
8688
|
+
assertConfigurationModule(config);
|
|
8689
|
+
for (const { coverageMap, thresholds, name } of allThresholds) {
|
|
8690
|
+
const summaries = this.options.thresholds?.perFile ? coverageMap.files().map(
|
|
8691
|
+
(file) => coverageMap.fileCoverageFor(file).toSummary()
|
|
8692
|
+
) : [coverageMap.getCoverageSummary()];
|
|
8693
|
+
const thresholdsToUpdate = [];
|
|
8694
|
+
for (const key of THRESHOLD_KEYS) {
|
|
8695
|
+
const threshold = thresholds[key] ?? 100;
|
|
8696
|
+
if (threshold >= 0) {
|
|
8697
|
+
const actual = Math.min(
|
|
8698
|
+
...summaries.map((summary) => summary[key].pct)
|
|
8699
|
+
);
|
|
8700
|
+
if (actual > threshold) {
|
|
8701
|
+
thresholdsToUpdate.push([key, actual]);
|
|
8702
|
+
}
|
|
8703
|
+
} else {
|
|
8704
|
+
const absoluteThreshold = threshold * -1;
|
|
8705
|
+
const actual = Math.max(
|
|
8706
|
+
...summaries.map((summary) => summary[key].total - summary[key].covered)
|
|
8707
|
+
);
|
|
8708
|
+
if (actual < absoluteThreshold) {
|
|
8709
|
+
const updatedThreshold = actual === 0 ? 100 : actual * -1;
|
|
8710
|
+
thresholdsToUpdate.push([key, updatedThreshold]);
|
|
8711
|
+
}
|
|
8712
|
+
}
|
|
8713
|
+
}
|
|
8714
|
+
if (thresholdsToUpdate.length === 0) {
|
|
8715
|
+
continue;
|
|
8716
|
+
}
|
|
8717
|
+
updatedThresholds = true;
|
|
8718
|
+
for (const [threshold, newValue] of thresholdsToUpdate) {
|
|
8719
|
+
if (name === GLOBAL_THRESHOLDS_KEY) {
|
|
8720
|
+
config.test.coverage.thresholds[threshold] = newValue;
|
|
8721
|
+
} else {
|
|
8722
|
+
const glob = config.test.coverage.thresholds[name];
|
|
8723
|
+
glob[threshold] = newValue;
|
|
8724
|
+
}
|
|
8725
|
+
}
|
|
8726
|
+
}
|
|
8727
|
+
if (updatedThresholds) {
|
|
8728
|
+
this.ctx.logger.log("Updating thresholds to configuration file. You may want to push with updated coverage thresholds.");
|
|
8729
|
+
onUpdate();
|
|
8730
|
+
}
|
|
8731
|
+
}
|
|
8732
|
+
async mergeReports(coverageMaps) {
|
|
8733
|
+
const coverageMap = this.createCoverageMap();
|
|
8734
|
+
for (const coverage of coverageMaps) {
|
|
8735
|
+
coverageMap.merge(coverage);
|
|
8736
|
+
}
|
|
8737
|
+
await this.generateReports(coverageMap, true);
|
|
8738
|
+
}
|
|
8739
|
+
hasTerminalReporter(reporters) {
|
|
8740
|
+
return reporters.some(
|
|
8741
|
+
([reporter]) => reporter === "text" || reporter === "text-summary" || reporter === "text-lcov" || reporter === "teamcity"
|
|
8742
|
+
);
|
|
8743
|
+
}
|
|
8744
|
+
toSlices(array, size) {
|
|
8745
|
+
return array.reduce((chunks, item) => {
|
|
8746
|
+
const index = Math.max(0, chunks.length - 1);
|
|
8747
|
+
const lastChunk = chunks[index] || [];
|
|
8748
|
+
chunks[index] = lastChunk;
|
|
8749
|
+
if (lastChunk.length >= size) {
|
|
8750
|
+
chunks.push([item]);
|
|
8751
|
+
} else {
|
|
8752
|
+
lastChunk.push(item);
|
|
8753
|
+
}
|
|
8754
|
+
return chunks;
|
|
8755
|
+
}, []);
|
|
8756
|
+
}
|
|
8757
|
+
createUncoveredFileTransformer(ctx) {
|
|
8758
|
+
const servers = [
|
|
8759
|
+
...ctx.projects.map((project) => ({
|
|
8760
|
+
root: project.config.root,
|
|
8761
|
+
isBrowserEnabled: project.isBrowserEnabled(),
|
|
8762
|
+
vitenode: project.vitenode
|
|
8763
|
+
})),
|
|
8764
|
+
// Check core last as it will match all files anyway
|
|
8765
|
+
{ root: ctx.config.root, vitenode: ctx.vitenode, isBrowserEnabled: ctx.getRootProject().isBrowserEnabled() }
|
|
8766
|
+
];
|
|
8767
|
+
return async function transformFile(filename) {
|
|
8768
|
+
let lastError;
|
|
8769
|
+
for (const { root, vitenode, isBrowserEnabled } of servers) {
|
|
8770
|
+
if (!filename.startsWith(root) && !filename.startsWith(`/${root}`)) {
|
|
8771
|
+
continue;
|
|
8772
|
+
}
|
|
8773
|
+
if (isBrowserEnabled) {
|
|
8774
|
+
const result = await vitenode.transformRequest(filename, void 0, "web").catch(() => null);
|
|
8775
|
+
if (result) {
|
|
8776
|
+
return result;
|
|
8777
|
+
}
|
|
8778
|
+
}
|
|
8779
|
+
try {
|
|
8780
|
+
return await vitenode.transformRequest(filename);
|
|
8781
|
+
} catch (error) {
|
|
8782
|
+
lastError = error;
|
|
8783
|
+
}
|
|
8784
|
+
}
|
|
8785
|
+
throw lastError;
|
|
8786
|
+
};
|
|
8787
|
+
}
|
|
8788
|
+
}
|
|
8789
|
+
function resolveGlobThresholds(thresholds) {
|
|
8790
|
+
if (!thresholds || typeof thresholds !== "object") {
|
|
8791
|
+
return {};
|
|
8792
|
+
}
|
|
8793
|
+
if (100 in thresholds && thresholds[100] === true) {
|
|
8794
|
+
return {
|
|
8795
|
+
lines: 100,
|
|
8796
|
+
branches: 100,
|
|
8797
|
+
functions: 100,
|
|
8798
|
+
statements: 100
|
|
8799
|
+
};
|
|
8800
|
+
}
|
|
8801
|
+
return {
|
|
8802
|
+
lines: "lines" in thresholds && typeof thresholds.lines === "number" ? thresholds.lines : void 0,
|
|
8803
|
+
branches: "branches" in thresholds && typeof thresholds.branches === "number" ? thresholds.branches : void 0,
|
|
8804
|
+
functions: "functions" in thresholds && typeof thresholds.functions === "number" ? thresholds.functions : void 0,
|
|
8805
|
+
statements: "statements" in thresholds && typeof thresholds.statements === "number" ? thresholds.statements : void 0
|
|
8806
|
+
};
|
|
8807
|
+
}
|
|
8808
|
+
function assertConfigurationModule(config) {
|
|
8809
|
+
try {
|
|
8810
|
+
if (typeof config.test.coverage.thresholds !== "object") {
|
|
8811
|
+
throw new TypeError(
|
|
8812
|
+
"Expected config.test.coverage.thresholds to be an object"
|
|
8813
|
+
);
|
|
8814
|
+
}
|
|
8815
|
+
} catch (error) {
|
|
8816
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8817
|
+
throw new Error(
|
|
8818
|
+
`Unable to parse thresholds from configuration file: ${message}`
|
|
8819
|
+
);
|
|
8820
|
+
}
|
|
8821
|
+
}
|
|
8822
|
+
function resolveConfig(configModule) {
|
|
8823
|
+
const mod = configModule.exports.default;
|
|
8824
|
+
try {
|
|
8825
|
+
if (mod.$type === "object") {
|
|
8826
|
+
return mod;
|
|
8827
|
+
}
|
|
8828
|
+
let config = resolveDefineConfig(mod);
|
|
8829
|
+
if (config) {
|
|
8830
|
+
return config;
|
|
8831
|
+
}
|
|
8832
|
+
if (mod.$type === "function-call" && mod.$callee === "mergeConfig") {
|
|
8833
|
+
config = resolveMergeConfig(mod);
|
|
8834
|
+
if (config) {
|
|
8835
|
+
return config;
|
|
8836
|
+
}
|
|
8837
|
+
}
|
|
8838
|
+
} catch (error) {
|
|
8839
|
+
throw new Error(error instanceof Error ? error.message : String(error));
|
|
8840
|
+
}
|
|
8841
|
+
throw new Error(
|
|
8842
|
+
"Failed to update coverage thresholds. Configuration file is too complex."
|
|
8843
|
+
);
|
|
8844
|
+
}
|
|
8845
|
+
function resolveDefineConfig(mod) {
|
|
8846
|
+
if (mod.$type === "function-call" && mod.$callee === "defineConfig") {
|
|
8847
|
+
if (mod.$args[0].$type === "object") {
|
|
8848
|
+
return mod.$args[0];
|
|
8849
|
+
}
|
|
8850
|
+
if (mod.$args[0].$type === "arrow-function-expression") {
|
|
8851
|
+
if (mod.$args[0].$body.$type === "object") {
|
|
8852
|
+
return mod.$args[0].$body;
|
|
8853
|
+
}
|
|
8854
|
+
const config = resolveMergeConfig(mod.$args[0].$body);
|
|
8855
|
+
if (config) {
|
|
8856
|
+
return config;
|
|
8857
|
+
}
|
|
8858
|
+
}
|
|
8859
|
+
}
|
|
8860
|
+
}
|
|
8861
|
+
function resolveMergeConfig(mod) {
|
|
8862
|
+
if (mod.$type === "function-call" && mod.$callee === "mergeConfig") {
|
|
8863
|
+
for (const arg of mod.$args) {
|
|
8864
|
+
const config = resolveDefineConfig(arg);
|
|
8865
|
+
if (config) {
|
|
8866
|
+
return config;
|
|
8867
|
+
}
|
|
8868
|
+
}
|
|
8869
|
+
}
|
|
8870
|
+
}
|
|
8871
|
+
|
|
8872
|
+
export { BaseCoverageProvider as B, RandomSequencer as R, VitestCache as V, resolveApiServerConfig as a, BaseSequencer as b, createMethodsRPC as c, isBrowserEnabled as d, groupBy as e, getCoverageProvider as f, getFilePoolName as g, hash as h, isPackageExists as i, createPool as j, mm as m, resolveConfig$1 as r, stdout as s, wildcardPatternToRegExp as w };
|
|
@@ -5,7 +5,7 @@ import { detectPackageManager, installPackage } from './index.Bw6JxgX8.js';
|
|
|
5
5
|
import { p as prompt, f as findUp } from './index.DBIGubLC.js';
|
|
6
6
|
import { x } from 'tinyexec';
|
|
7
7
|
import c from 'tinyrainbow';
|
|
8
|
-
import { c as configFiles } from './constants.
|
|
8
|
+
import { c as configFiles } from './constants.DTYd6dNH.js';
|
|
9
9
|
import 'node:process';
|
|
10
10
|
import 'node:url';
|
|
11
11
|
import './_commonjsHelpers.BFTU3MAI.js';
|