vitest 4.0.17 → 4.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/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/chunks/{base.XJJQZiKB.js → base.CBRNZa3k.js} +8 -7
- package/dist/chunks/{browser.d.ChKACdzH.d.ts → browser.d.8hOapKZr.d.ts} +3 -1
- package/dist/chunks/{cac.jRCLJDDc.js → cac.B1v3xxoC.js} +26 -8
- package/dist/chunks/{cli-api.Cx2DW4Bc.js → cli-api.B4CqEpI6.js} +102 -54
- package/dist/chunks/{config.d.Cy95HiCx.d.ts → config.d.idH22YSr.d.ts} +8 -11
- package/dist/chunks/{console.Cf-YriPC.js → console.uGgdMhyZ.js} +2 -1
- package/dist/chunks/{coverage.AVPTjMgw.js → coverage.BMlOMIWl.js} +14 -4
- package/dist/chunks/{creator.DAmOKTvJ.js → creator.C7WwjkuR.js} +32 -1
- package/dist/chunks/{globals.DOayXfHP.js → globals.DjuGMoMc.js} +10 -9
- package/dist/chunks/{index.Z5E_ObnR.js → index.BEFi2-_3.js} +3 -1
- package/dist/chunks/{index.6Qv1eEA6.js → index.BiOAd_ki.js} +16 -4
- package/dist/chunks/{index.M8mOzt4Y.js → index.Dm4xqZ0s.js} +2 -2
- package/dist/chunks/{index.C5r1PdPD.js → index.DyBZXrH3.js} +1 -1
- package/dist/chunks/{init-forks.BC6ZwHQN.js → init-forks.CHeQ9Moq.js} +1 -1
- package/dist/chunks/{init-threads.CxSxLC0N.js → init-threads.uZiNAuPk.js} +1 -1
- package/dist/chunks/{init.C9kljSTm.js → init.DVtKdFty.js} +21 -6
- package/dist/chunks/{plugin.d.CtqpEehP.d.ts → plugin.d.D8KU2PY_.d.ts} +1 -1
- package/dist/chunks/{reporters.d.CWXNI2jG.d.ts → reporters.d.Db3MiIWX.d.ts} +48 -20
- package/dist/chunks/rpc.HLmECnw_.js +148 -0
- package/dist/chunks/{setup-common.Cm-kSBVi.js → setup-common.BcqLPsn5.js} +1 -1
- package/dist/chunks/{startModuleRunner.DEj0jb3e.js → startModuleRunner.C5CcWyXW.js} +22 -22
- package/dist/chunks/{vi.2VT5v0um.js → test.prxIahgM.js} +500 -119
- package/dist/chunks/{vm.CMjifoPa.js → vm.CrifS09m.js} +5 -8
- package/dist/chunks/{worker.d.Dyxm8DEL.d.ts → worker.d.Bji1eq5g.d.ts} +1 -1
- package/dist/cli.js +2 -2
- package/dist/config.d.ts +9 -9
- package/dist/coverage.d.ts +7 -7
- package/dist/coverage.js +3 -1
- package/dist/environments.js +2 -0
- package/dist/index.d.ts +21 -9
- package/dist/index.js +8 -7
- package/dist/module-evaluator.js +1 -5
- package/dist/node.d.ts +11 -10
- package/dist/node.js +19 -19
- package/dist/reporters.d.ts +7 -7
- package/dist/reporters.js +4 -2
- package/dist/runners.d.ts +23 -4
- package/dist/runners.js +4 -4
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.js +36 -0
- package/dist/snapshot.js +2 -0
- package/dist/suite.js +2 -0
- package/dist/worker.d.ts +4 -3
- package/dist/worker.js +8 -10
- package/dist/workers/forks.js +9 -11
- package/dist/workers/runVmTests.js +10 -12
- package/dist/workers/threads.js +9 -11
- package/dist/workers/vmForks.js +6 -7
- package/dist/workers/vmThreads.js +6 -7
- package/package.json +23 -27
- package/dist/chunks/date.Bq6ZW5rf.js +0 -73
- package/dist/chunks/rpc.BoxB0q7B.js +0 -76
- package/dist/chunks/test.B8ej_ZHS.js +0 -254
- package/dist/mocker.d.ts +0 -1
- package/dist/mocker.js +0 -1
- package/dist/module-runner.js +0 -17
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { g as getWorkerState, i as isChildProcess, w as waitForImportsToResolve, r as resetModules } from './utils.DvEY5TfP.js';
|
|
1
|
+
import { getCurrentTest, updateTask, createTaskCollector, getCurrentSuite, getHooks, getFn } from '@vitest/runner';
|
|
2
|
+
import { assertTypes, createSimpleStackTrace, createDefer } from '@vitest/utils/helpers';
|
|
4
3
|
import { getSafeTimers, delay } from '@vitest/utils/timers';
|
|
5
|
-
import {
|
|
4
|
+
import { a as getBenchOptions, g as getBenchFn } from './benchmark.B3N2zMcH.js';
|
|
5
|
+
import { g as getWorkerState, i as isChildProcess, w as waitForImportsToResolve, r as resetModules } from './utils.DvEY5TfP.js';
|
|
6
|
+
import { chai, equals, iterableEquality, subsetEquality, JestExtend, JestChaiExpect, ChaiStyleAssertions, JestAsymmetricMatchers, GLOBAL_EXPECT, ASYMMETRIC_MATCHERS_OBJECT, getState, setState, addCustomEqualityTesters, customMatchers } from '@vitest/expect';
|
|
7
|
+
import { getNames, getTests, getTestName, createChainable } from '@vitest/runner/utils';
|
|
8
|
+
import { processError } from '@vitest/utils/error';
|
|
9
|
+
import { normalize } from 'pathe';
|
|
6
10
|
import { stripSnapshotIndentation, addSerializer, SnapshotClient } from '@vitest/snapshot';
|
|
7
|
-
import '@vitest/utils/error';
|
|
8
|
-
import { assertTypes, createSimpleStackTrace } from '@vitest/utils/helpers';
|
|
9
11
|
import { fn, spyOn, restoreAllMocks, resetAllMocks, clearAllMocks, isMockFunction } from '@vitest/spy';
|
|
10
12
|
import '@vitest/utils/offset';
|
|
11
13
|
import { parseSingleStack } from '@vitest/utils/source-map';
|
|
12
14
|
import { c as commonjsGlobal } from './_commonjsHelpers.D26ty3Ew.js';
|
|
13
|
-
import { R as RealDate,
|
|
15
|
+
import { R as RealDate, b as resetDate, m as mockDate, r as rpc } from './rpc.HLmECnw_.js';
|
|
14
16
|
|
|
15
17
|
// these matchers are not supported because they don't make sense with poll
|
|
16
18
|
const unsupported = [
|
|
@@ -295,6 +297,7 @@ const SnapshotPlugin = (chai, utils) => {
|
|
|
295
297
|
|
|
296
298
|
chai.use(JestExtend);
|
|
297
299
|
chai.use(JestChaiExpect);
|
|
300
|
+
chai.use(ChaiStyleAssertions);
|
|
298
301
|
chai.use(SnapshotPlugin);
|
|
299
302
|
chai.use(JestAsymmetricMatchers);
|
|
300
303
|
|
|
@@ -1326,6 +1329,30 @@ function requireFakeTimersSrc () {
|
|
|
1326
1329
|
}
|
|
1327
1330
|
}
|
|
1328
1331
|
|
|
1332
|
+
/**
|
|
1333
|
+
* @typedef {"nextAsync" | "manual" | "interval"} TickMode
|
|
1334
|
+
*/
|
|
1335
|
+
|
|
1336
|
+
/**
|
|
1337
|
+
* @typedef {object} NextAsyncTickMode
|
|
1338
|
+
* @property {"nextAsync"} mode
|
|
1339
|
+
*/
|
|
1340
|
+
|
|
1341
|
+
/**
|
|
1342
|
+
* @typedef {object} ManualTickMode
|
|
1343
|
+
* @property {"manual"} mode
|
|
1344
|
+
*/
|
|
1345
|
+
|
|
1346
|
+
/**
|
|
1347
|
+
* @typedef {object} IntervalTickMode
|
|
1348
|
+
* @property {"interval"} mode
|
|
1349
|
+
* @property {number} [delta]
|
|
1350
|
+
*/
|
|
1351
|
+
|
|
1352
|
+
/**
|
|
1353
|
+
* @typedef {IntervalTickMode | NextAsyncTickMode | ManualTickMode} TimerTickMode
|
|
1354
|
+
*/
|
|
1355
|
+
|
|
1329
1356
|
/**
|
|
1330
1357
|
* @typedef {object} IdleDeadline
|
|
1331
1358
|
* @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout
|
|
@@ -1411,6 +1438,7 @@ function requireFakeTimersSrc () {
|
|
|
1411
1438
|
* @property {{methodName:string, original:any}[] | undefined} timersModuleMethods
|
|
1412
1439
|
* @property {{methodName:string, original:any}[] | undefined} timersPromisesModuleMethods
|
|
1413
1440
|
* @property {Map<function(): void, AbortSignal>} abortListenerMap
|
|
1441
|
+
* @property {function(TimerTickMode): void} setTickMode
|
|
1414
1442
|
*/
|
|
1415
1443
|
/* eslint-enable jsdoc/require-property-description */
|
|
1416
1444
|
|
|
@@ -2208,10 +2236,9 @@ function requireFakeTimersSrc () {
|
|
|
2208
2236
|
|
|
2209
2237
|
/**
|
|
2210
2238
|
* @param {Clock} clock
|
|
2211
|
-
* @param {Config} config
|
|
2212
2239
|
* @returns {Timer[]}
|
|
2213
2240
|
*/
|
|
2214
|
-
function uninstall(clock
|
|
2241
|
+
function uninstall(clock) {
|
|
2215
2242
|
let method, i, l;
|
|
2216
2243
|
const installedHrTime = "_hrtime";
|
|
2217
2244
|
const installedNextTick = "_nextTick";
|
|
@@ -2269,9 +2296,7 @@ function requireFakeTimersSrc () {
|
|
|
2269
2296
|
}
|
|
2270
2297
|
}
|
|
2271
2298
|
|
|
2272
|
-
|
|
2273
|
-
_global.clearInterval(clock.attachedInterval);
|
|
2274
|
-
}
|
|
2299
|
+
clock.setTickMode("manual");
|
|
2275
2300
|
|
|
2276
2301
|
// Prevent multiple executions which will completely remove these props
|
|
2277
2302
|
clock.methods = [];
|
|
@@ -2427,6 +2452,8 @@ function requireFakeTimersSrc () {
|
|
|
2427
2452
|
}
|
|
2428
2453
|
|
|
2429
2454
|
const originalSetTimeout = _global.setImmediate || _global.setTimeout;
|
|
2455
|
+
const originalClearInterval = _global.clearInterval;
|
|
2456
|
+
const originalSetInterval = _global.setInterval;
|
|
2430
2457
|
|
|
2431
2458
|
/**
|
|
2432
2459
|
* @param {Date|number} [start] the system time - non-integer values are floored
|
|
@@ -2445,6 +2472,7 @@ function requireFakeTimersSrc () {
|
|
|
2445
2472
|
now: start,
|
|
2446
2473
|
Date: createDate(),
|
|
2447
2474
|
loopLimit: loopLimit,
|
|
2475
|
+
tickMode: { mode: "manual", counter: 0, delta: undefined },
|
|
2448
2476
|
};
|
|
2449
2477
|
|
|
2450
2478
|
clock.Date.clock = clock;
|
|
@@ -2511,6 +2539,74 @@ function requireFakeTimersSrc () {
|
|
|
2511
2539
|
clock.Intl.clock = clock;
|
|
2512
2540
|
}
|
|
2513
2541
|
|
|
2542
|
+
/**
|
|
2543
|
+
* @param {TimerTickMode} tickModeConfig - The new configuration for how the clock should tick.
|
|
2544
|
+
*/
|
|
2545
|
+
clock.setTickMode = function (tickModeConfig) {
|
|
2546
|
+
const { mode: newMode, delta: newDelta } = tickModeConfig;
|
|
2547
|
+
const { mode: oldMode, delta: oldDelta } = clock.tickMode;
|
|
2548
|
+
if (newMode === oldMode && newDelta === oldDelta) {
|
|
2549
|
+
return;
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
if (oldMode === "interval") {
|
|
2553
|
+
originalClearInterval(clock.attachedInterval);
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
clock.tickMode = {
|
|
2557
|
+
counter: clock.tickMode.counter + 1,
|
|
2558
|
+
mode: newMode,
|
|
2559
|
+
delta: newDelta,
|
|
2560
|
+
};
|
|
2561
|
+
|
|
2562
|
+
if (newMode === "nextAsync") {
|
|
2563
|
+
advanceUntilModeChanges();
|
|
2564
|
+
} else if (newMode === "interval") {
|
|
2565
|
+
createIntervalTick(clock, newDelta || 20);
|
|
2566
|
+
}
|
|
2567
|
+
};
|
|
2568
|
+
|
|
2569
|
+
async function advanceUntilModeChanges() {
|
|
2570
|
+
async function newMacrotask() {
|
|
2571
|
+
// MessageChannel ensures that setTimeout is not throttled to 4ms.
|
|
2572
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
|
|
2573
|
+
// https://stackblitz.com/edit/stackblitz-starters-qtlpcc
|
|
2574
|
+
const channel = new MessageChannel();
|
|
2575
|
+
await new Promise((resolve) => {
|
|
2576
|
+
channel.port1.onmessage = () => {
|
|
2577
|
+
resolve();
|
|
2578
|
+
channel.port1.close();
|
|
2579
|
+
};
|
|
2580
|
+
channel.port2.postMessage(undefined);
|
|
2581
|
+
});
|
|
2582
|
+
channel.port1.close();
|
|
2583
|
+
channel.port2.close();
|
|
2584
|
+
// setTimeout ensures microtask queue is emptied
|
|
2585
|
+
await new Promise((resolve) => {
|
|
2586
|
+
originalSetTimeout(resolve);
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
const { counter } = clock.tickMode;
|
|
2591
|
+
while (clock.tickMode.counter === counter) {
|
|
2592
|
+
await newMacrotask();
|
|
2593
|
+
if (clock.tickMode.counter !== counter) {
|
|
2594
|
+
return;
|
|
2595
|
+
}
|
|
2596
|
+
clock.next();
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
function pauseAutoTickUntilFinished(promise) {
|
|
2601
|
+
if (clock.tickMode.mode !== "nextAsync") {
|
|
2602
|
+
return promise;
|
|
2603
|
+
}
|
|
2604
|
+
clock.setTickMode({ mode: "manual" });
|
|
2605
|
+
return promise.finally(() => {
|
|
2606
|
+
clock.setTickMode({ mode: "nextAsync" });
|
|
2607
|
+
});
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2514
2610
|
clock.requestIdleCallback = function requestIdleCallback(
|
|
2515
2611
|
func,
|
|
2516
2612
|
timeout,
|
|
@@ -2809,15 +2905,17 @@ function requireFakeTimersSrc () {
|
|
|
2809
2905
|
* @returns {Promise}
|
|
2810
2906
|
*/
|
|
2811
2907
|
clock.tickAsync = function tickAsync(tickValue) {
|
|
2812
|
-
return
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2908
|
+
return pauseAutoTickUntilFinished(
|
|
2909
|
+
new _global.Promise(function (resolve, reject) {
|
|
2910
|
+
originalSetTimeout(function () {
|
|
2911
|
+
try {
|
|
2912
|
+
doTick(tickValue, true, resolve, reject);
|
|
2913
|
+
} catch (e) {
|
|
2914
|
+
reject(e);
|
|
2915
|
+
}
|
|
2916
|
+
});
|
|
2917
|
+
}),
|
|
2918
|
+
);
|
|
2821
2919
|
};
|
|
2822
2920
|
}
|
|
2823
2921
|
|
|
@@ -2841,37 +2939,39 @@ function requireFakeTimersSrc () {
|
|
|
2841
2939
|
|
|
2842
2940
|
if (typeof _global.Promise !== "undefined") {
|
|
2843
2941
|
clock.nextAsync = function nextAsync() {
|
|
2844
|
-
return
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
const timer = firstTimer(clock);
|
|
2848
|
-
if (!timer) {
|
|
2849
|
-
resolve(clock.now);
|
|
2850
|
-
return;
|
|
2851
|
-
}
|
|
2852
|
-
|
|
2853
|
-
let err;
|
|
2854
|
-
clock.duringTick = true;
|
|
2855
|
-
clock.now = timer.callAt;
|
|
2942
|
+
return pauseAutoTickUntilFinished(
|
|
2943
|
+
new _global.Promise(function (resolve, reject) {
|
|
2944
|
+
originalSetTimeout(function () {
|
|
2856
2945
|
try {
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
err = e;
|
|
2860
|
-
}
|
|
2861
|
-
clock.duringTick = false;
|
|
2862
|
-
|
|
2863
|
-
originalSetTimeout(function () {
|
|
2864
|
-
if (err) {
|
|
2865
|
-
reject(err);
|
|
2866
|
-
} else {
|
|
2946
|
+
const timer = firstTimer(clock);
|
|
2947
|
+
if (!timer) {
|
|
2867
2948
|
resolve(clock.now);
|
|
2949
|
+
return;
|
|
2868
2950
|
}
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2951
|
+
|
|
2952
|
+
let err;
|
|
2953
|
+
clock.duringTick = true;
|
|
2954
|
+
clock.now = timer.callAt;
|
|
2955
|
+
try {
|
|
2956
|
+
callTimer(clock, timer);
|
|
2957
|
+
} catch (e) {
|
|
2958
|
+
err = e;
|
|
2959
|
+
}
|
|
2960
|
+
clock.duringTick = false;
|
|
2961
|
+
|
|
2962
|
+
originalSetTimeout(function () {
|
|
2963
|
+
if (err) {
|
|
2964
|
+
reject(err);
|
|
2965
|
+
} else {
|
|
2966
|
+
resolve(clock.now);
|
|
2967
|
+
}
|
|
2968
|
+
});
|
|
2969
|
+
} catch (e) {
|
|
2970
|
+
reject(e);
|
|
2971
|
+
}
|
|
2972
|
+
});
|
|
2973
|
+
}),
|
|
2974
|
+
);
|
|
2875
2975
|
};
|
|
2876
2976
|
}
|
|
2877
2977
|
|
|
@@ -2904,51 +3004,55 @@ function requireFakeTimersSrc () {
|
|
|
2904
3004
|
|
|
2905
3005
|
if (typeof _global.Promise !== "undefined") {
|
|
2906
3006
|
clock.runAllAsync = function runAllAsync() {
|
|
2907
|
-
return
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
if (
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
3007
|
+
return pauseAutoTickUntilFinished(
|
|
3008
|
+
new _global.Promise(function (resolve, reject) {
|
|
3009
|
+
let i = 0;
|
|
3010
|
+
/**
|
|
3011
|
+
*
|
|
3012
|
+
*/
|
|
3013
|
+
function doRun() {
|
|
3014
|
+
originalSetTimeout(function () {
|
|
3015
|
+
try {
|
|
3016
|
+
runJobs(clock);
|
|
3017
|
+
|
|
3018
|
+
let numTimers;
|
|
3019
|
+
if (i < clock.loopLimit) {
|
|
3020
|
+
if (!clock.timers) {
|
|
3021
|
+
resetIsNearInfiniteLimit();
|
|
3022
|
+
resolve(clock.now);
|
|
3023
|
+
return;
|
|
3024
|
+
}
|
|
3025
|
+
|
|
3026
|
+
numTimers = Object.keys(
|
|
3027
|
+
clock.timers,
|
|
3028
|
+
).length;
|
|
3029
|
+
if (numTimers === 0) {
|
|
3030
|
+
resetIsNearInfiniteLimit();
|
|
3031
|
+
resolve(clock.now);
|
|
3032
|
+
return;
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
clock.next();
|
|
3036
|
+
|
|
3037
|
+
i++;
|
|
3038
|
+
|
|
3039
|
+
doRun();
|
|
3040
|
+
checkIsNearInfiniteLimit(clock, i);
|
|
2931
3041
|
return;
|
|
2932
3042
|
}
|
|
2933
3043
|
|
|
2934
|
-
clock
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
return;
|
|
3044
|
+
const excessJob = firstTimer(clock);
|
|
3045
|
+
reject(
|
|
3046
|
+
getInfiniteLoopError(clock, excessJob),
|
|
3047
|
+
);
|
|
3048
|
+
} catch (e) {
|
|
3049
|
+
reject(e);
|
|
2941
3050
|
}
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
}
|
|
2948
|
-
});
|
|
2949
|
-
}
|
|
2950
|
-
doRun();
|
|
2951
|
-
});
|
|
3051
|
+
});
|
|
3052
|
+
}
|
|
3053
|
+
doRun();
|
|
3054
|
+
}),
|
|
3055
|
+
);
|
|
2952
3056
|
};
|
|
2953
3057
|
}
|
|
2954
3058
|
|
|
@@ -2964,21 +3068,25 @@ function requireFakeTimersSrc () {
|
|
|
2964
3068
|
|
|
2965
3069
|
if (typeof _global.Promise !== "undefined") {
|
|
2966
3070
|
clock.runToLastAsync = function runToLastAsync() {
|
|
2967
|
-
return
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
3071
|
+
return pauseAutoTickUntilFinished(
|
|
3072
|
+
new _global.Promise(function (resolve, reject) {
|
|
3073
|
+
originalSetTimeout(function () {
|
|
3074
|
+
try {
|
|
3075
|
+
const timer = lastTimer(clock);
|
|
3076
|
+
if (!timer) {
|
|
3077
|
+
runJobs(clock);
|
|
3078
|
+
resolve(clock.now);
|
|
3079
|
+
}
|
|
2975
3080
|
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
3081
|
+
resolve(
|
|
3082
|
+
clock.tickAsync(timer.callAt - clock.now),
|
|
3083
|
+
);
|
|
3084
|
+
} catch (e) {
|
|
3085
|
+
reject(e);
|
|
3086
|
+
}
|
|
3087
|
+
});
|
|
3088
|
+
}),
|
|
3089
|
+
);
|
|
2982
3090
|
};
|
|
2983
3091
|
}
|
|
2984
3092
|
|
|
@@ -3042,6 +3150,12 @@ function requireFakeTimersSrc () {
|
|
|
3042
3150
|
return clock;
|
|
3043
3151
|
}
|
|
3044
3152
|
|
|
3153
|
+
function createIntervalTick(clock, delta) {
|
|
3154
|
+
const intervalTick = doIntervalTick.bind(null, clock, delta);
|
|
3155
|
+
const intervalId = originalSetInterval(intervalTick, delta);
|
|
3156
|
+
clock.attachedInterval = intervalId;
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3045
3159
|
/* eslint-disable complexity */
|
|
3046
3160
|
|
|
3047
3161
|
/**
|
|
@@ -3102,7 +3216,7 @@ function requireFakeTimersSrc () {
|
|
|
3102
3216
|
clock.shouldClearNativeTimers = config.shouldClearNativeTimers;
|
|
3103
3217
|
|
|
3104
3218
|
clock.uninstall = function () {
|
|
3105
|
-
return uninstall(clock
|
|
3219
|
+
return uninstall(clock);
|
|
3106
3220
|
};
|
|
3107
3221
|
|
|
3108
3222
|
clock.abortListenerMap = new Map();
|
|
@@ -3114,16 +3228,10 @@ function requireFakeTimersSrc () {
|
|
|
3114
3228
|
}
|
|
3115
3229
|
|
|
3116
3230
|
if (config.shouldAdvanceTime === true) {
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
);
|
|
3122
|
-
const intervalId = _global.setInterval(
|
|
3123
|
-
intervalTick,
|
|
3124
|
-
config.advanceTimeDelta,
|
|
3125
|
-
);
|
|
3126
|
-
clock.attachedInterval = intervalId;
|
|
3231
|
+
clock.setTickMode({
|
|
3232
|
+
mode: "interval",
|
|
3233
|
+
delta: config.advanceTimeDelta,
|
|
3234
|
+
});
|
|
3127
3235
|
}
|
|
3128
3236
|
|
|
3129
3237
|
if (clock.methods.includes("performance")) {
|
|
@@ -3535,9 +3643,7 @@ class FakeTimers {
|
|
|
3535
3643
|
if (this._checkFakeTimers()) this._clock.runToFrame();
|
|
3536
3644
|
}
|
|
3537
3645
|
runAllTicks() {
|
|
3538
|
-
if (this._checkFakeTimers())
|
|
3539
|
-
// @ts-expect-error method not exposed
|
|
3540
|
-
this._clock.runMicrotasks();
|
|
3646
|
+
if (this._checkFakeTimers()) this._clock.runMicrotasks();
|
|
3541
3647
|
}
|
|
3542
3648
|
useRealTimers() {
|
|
3543
3649
|
if (this._fakingDate) {
|
|
@@ -3591,6 +3697,15 @@ class FakeTimers {
|
|
|
3591
3697
|
if (this._checkFakeTimers()) return this._clock.countTimers();
|
|
3592
3698
|
return 0;
|
|
3593
3699
|
}
|
|
3700
|
+
setTimerTickMode(mode, interval) {
|
|
3701
|
+
if (this._checkFakeTimers()) if (mode === "manual") this._clock.setTickMode({ mode: "manual" });
|
|
3702
|
+
else if (mode === "nextTimerAsync") this._clock.setTickMode({ mode: "nextAsync" });
|
|
3703
|
+
else if (mode === "interval") this._clock.setTickMode({
|
|
3704
|
+
mode: "interval",
|
|
3705
|
+
delta: interval
|
|
3706
|
+
});
|
|
3707
|
+
else throw new Error(`Invalid tick mode: ${mode}`);
|
|
3708
|
+
}
|
|
3594
3709
|
configure(config) {
|
|
3595
3710
|
this._userConfig = config;
|
|
3596
3711
|
}
|
|
@@ -3793,6 +3908,10 @@ function createVitest() {
|
|
|
3793
3908
|
timers().clearAllTimers();
|
|
3794
3909
|
return utils;
|
|
3795
3910
|
},
|
|
3911
|
+
setTimerTickMode(mode, interval) {
|
|
3912
|
+
timers().setTimerTickMode(mode, interval);
|
|
3913
|
+
return utils;
|
|
3914
|
+
},
|
|
3796
3915
|
spyOn,
|
|
3797
3916
|
fn,
|
|
3798
3917
|
waitFor,
|
|
@@ -3814,6 +3933,11 @@ function createVitest() {
|
|
|
3814
3933
|
if (typeof path !== "string") throw new TypeError(`vi.doMock() expects a string path, but received a ${typeof path}`);
|
|
3815
3934
|
const importer = getImporter("doMock");
|
|
3816
3935
|
_mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
|
|
3936
|
+
const rv = {};
|
|
3937
|
+
if (Symbol.dispose) rv[Symbol.dispose] = () => {
|
|
3938
|
+
_mocker().queueUnmock(path, importer);
|
|
3939
|
+
};
|
|
3940
|
+
return rv;
|
|
3817
3941
|
},
|
|
3818
3942
|
doUnmock(path) {
|
|
3819
3943
|
if (typeof path !== "string") throw new TypeError(`vi.doUnmock() expects a string path, but received a ${typeof path}`);
|
|
@@ -3916,4 +4040,261 @@ function getImporter(name) {
|
|
|
3916
4040
|
}) + 1])?.file || "";
|
|
3917
4041
|
}
|
|
3918
4042
|
|
|
3919
|
-
|
|
4043
|
+
function createBenchmarkResult(name) {
|
|
4044
|
+
return {
|
|
4045
|
+
name,
|
|
4046
|
+
rank: 0,
|
|
4047
|
+
rme: 0,
|
|
4048
|
+
samples: []
|
|
4049
|
+
};
|
|
4050
|
+
}
|
|
4051
|
+
const benchmarkTasks = /* @__PURE__ */ new WeakMap();
|
|
4052
|
+
async function runBenchmarkSuite(suite, runner) {
|
|
4053
|
+
const { Task, Bench } = await runner.importTinybench();
|
|
4054
|
+
const start = performance.now();
|
|
4055
|
+
const benchmarkGroup = [];
|
|
4056
|
+
const benchmarkSuiteGroup = [];
|
|
4057
|
+
for (const task of suite.tasks) {
|
|
4058
|
+
if (task.mode !== "run" && task.mode !== "queued") continue;
|
|
4059
|
+
if (task.meta?.benchmark) benchmarkGroup.push(task);
|
|
4060
|
+
else if (task.type === "suite") benchmarkSuiteGroup.push(task);
|
|
4061
|
+
}
|
|
4062
|
+
// run sub suites sequentially
|
|
4063
|
+
for (const subSuite of benchmarkSuiteGroup) await runBenchmarkSuite(subSuite, runner);
|
|
4064
|
+
if (benchmarkGroup.length) {
|
|
4065
|
+
const defer = createDefer();
|
|
4066
|
+
suite.result = {
|
|
4067
|
+
state: "run",
|
|
4068
|
+
startTime: start,
|
|
4069
|
+
benchmark: createBenchmarkResult(suite.name)
|
|
4070
|
+
};
|
|
4071
|
+
updateTask$1("suite-prepare", suite);
|
|
4072
|
+
const addBenchTaskListener = (task, benchmark) => {
|
|
4073
|
+
task.addEventListener("complete", (e) => {
|
|
4074
|
+
const taskRes = e.task.result;
|
|
4075
|
+
const result = benchmark.result.benchmark;
|
|
4076
|
+
benchmark.result.state = "pass";
|
|
4077
|
+
Object.assign(result, taskRes);
|
|
4078
|
+
// compute extra stats and free raw samples as early as possible
|
|
4079
|
+
const samples = result.samples;
|
|
4080
|
+
result.sampleCount = samples.length;
|
|
4081
|
+
result.median = samples.length % 2 ? samples[Math.floor(samples.length / 2)] : (samples[samples.length / 2] + samples[samples.length / 2 - 1]) / 2;
|
|
4082
|
+
if (!runner.config.benchmark?.includeSamples) result.samples.length = 0;
|
|
4083
|
+
updateTask$1("test-finished", benchmark);
|
|
4084
|
+
}, { once: true });
|
|
4085
|
+
task.addEventListener("error", (e) => {
|
|
4086
|
+
const task = e.task;
|
|
4087
|
+
defer.reject(benchmark ? task.result.error : e);
|
|
4088
|
+
}, { once: true });
|
|
4089
|
+
};
|
|
4090
|
+
benchmarkGroup.forEach((benchmark) => {
|
|
4091
|
+
const benchmarkInstance = new Bench(getBenchOptions(benchmark));
|
|
4092
|
+
const benchmarkFn = getBenchFn(benchmark);
|
|
4093
|
+
benchmark.result = {
|
|
4094
|
+
state: "run",
|
|
4095
|
+
startTime: start,
|
|
4096
|
+
benchmark: createBenchmarkResult(benchmark.name)
|
|
4097
|
+
};
|
|
4098
|
+
const task = new Task(benchmarkInstance, benchmark.name, benchmarkFn);
|
|
4099
|
+
benchmarkTasks.set(benchmark, task);
|
|
4100
|
+
addBenchTaskListener(task, benchmark);
|
|
4101
|
+
});
|
|
4102
|
+
const { setTimeout } = getSafeTimers();
|
|
4103
|
+
const tasks = [];
|
|
4104
|
+
for (const benchmark of benchmarkGroup) {
|
|
4105
|
+
const task = benchmarkTasks.get(benchmark);
|
|
4106
|
+
updateTask$1("test-prepare", benchmark);
|
|
4107
|
+
await task.warmup();
|
|
4108
|
+
tasks.push([await new Promise((resolve) => setTimeout(async () => {
|
|
4109
|
+
resolve(await task.run());
|
|
4110
|
+
})), benchmark]);
|
|
4111
|
+
}
|
|
4112
|
+
suite.result.duration = performance.now() - start;
|
|
4113
|
+
suite.result.state = "pass";
|
|
4114
|
+
updateTask$1("suite-finished", suite);
|
|
4115
|
+
defer.resolve(null);
|
|
4116
|
+
await defer;
|
|
4117
|
+
}
|
|
4118
|
+
function updateTask$1(event, task) {
|
|
4119
|
+
updateTask(event, task, runner);
|
|
4120
|
+
}
|
|
4121
|
+
}
|
|
4122
|
+
class NodeBenchmarkRunner {
|
|
4123
|
+
moduleRunner;
|
|
4124
|
+
constructor(config) {
|
|
4125
|
+
this.config = config;
|
|
4126
|
+
}
|
|
4127
|
+
async importTinybench() {
|
|
4128
|
+
return await import('tinybench');
|
|
4129
|
+
}
|
|
4130
|
+
importFile(filepath, source) {
|
|
4131
|
+
if (source === "setup") {
|
|
4132
|
+
const moduleNode = getWorkerState().evaluatedModules.getModuleById(filepath);
|
|
4133
|
+
if (moduleNode) getWorkerState().evaluatedModules.invalidateModule(moduleNode);
|
|
4134
|
+
}
|
|
4135
|
+
return this.moduleRunner.import(filepath);
|
|
4136
|
+
}
|
|
4137
|
+
async runSuite(suite) {
|
|
4138
|
+
await runBenchmarkSuite(suite, this);
|
|
4139
|
+
}
|
|
4140
|
+
async runTask() {
|
|
4141
|
+
throw new Error("`test()` and `it()` is only available in test mode.");
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
|
|
4145
|
+
// worker context is shared between all tests
|
|
4146
|
+
const workerContext = Object.create(null);
|
|
4147
|
+
class TestRunner {
|
|
4148
|
+
snapshotClient = getSnapshotClient();
|
|
4149
|
+
workerState = getWorkerState();
|
|
4150
|
+
moduleRunner;
|
|
4151
|
+
cancelRun = false;
|
|
4152
|
+
assertionsErrors = /* @__PURE__ */ new WeakMap();
|
|
4153
|
+
pool = this.workerState.ctx.pool;
|
|
4154
|
+
_otel;
|
|
4155
|
+
viteEnvironment;
|
|
4156
|
+
constructor(config) {
|
|
4157
|
+
this.config = config;
|
|
4158
|
+
const environment = this.workerState.environment;
|
|
4159
|
+
this.viteEnvironment = environment.viteEnvironment || environment.name;
|
|
4160
|
+
}
|
|
4161
|
+
importFile(filepath, source) {
|
|
4162
|
+
if (source === "setup") {
|
|
4163
|
+
const moduleNode = this.workerState.evaluatedModules.getModuleById(filepath);
|
|
4164
|
+
if (moduleNode) this.workerState.evaluatedModules.invalidateModule(moduleNode);
|
|
4165
|
+
}
|
|
4166
|
+
return this._otel.$(`vitest.module.import_${source === "setup" ? "setup" : "spec"}`, { attributes: { "code.file.path": filepath } }, () => this.moduleRunner.import(filepath));
|
|
4167
|
+
}
|
|
4168
|
+
onCollectStart(file) {
|
|
4169
|
+
this.workerState.current = file;
|
|
4170
|
+
}
|
|
4171
|
+
onCleanupWorkerContext(listener) {
|
|
4172
|
+
this.workerState.onCleanup(listener);
|
|
4173
|
+
}
|
|
4174
|
+
onAfterRunFiles() {
|
|
4175
|
+
this.snapshotClient.clear();
|
|
4176
|
+
this.workerState.current = void 0;
|
|
4177
|
+
}
|
|
4178
|
+
getWorkerContext() {
|
|
4179
|
+
return workerContext;
|
|
4180
|
+
}
|
|
4181
|
+
async onAfterRunSuite(suite) {
|
|
4182
|
+
if (this.config.logHeapUsage && typeof process !== "undefined") suite.result.heap = process.memoryUsage().heapUsed;
|
|
4183
|
+
if (suite.mode !== "skip" && "filepath" in suite) {
|
|
4184
|
+
// mark snapshots in skipped tests as not obsolete
|
|
4185
|
+
for (const test of getTests(suite)) if (test.mode === "skip") {
|
|
4186
|
+
const name = getNames(test).slice(1).join(" > ");
|
|
4187
|
+
this.snapshotClient.skipTest(suite.file.filepath, name);
|
|
4188
|
+
}
|
|
4189
|
+
const result = await this.snapshotClient.finish(suite.file.filepath);
|
|
4190
|
+
if (this.workerState.config.snapshotOptions.updateSnapshot === "none" && result.unchecked) {
|
|
4191
|
+
let message = `Obsolete snapshots found when no snapshot update is expected.\n`;
|
|
4192
|
+
for (const key of result.uncheckedKeys) message += `· ${key}\n`;
|
|
4193
|
+
suite.result.errors ??= [];
|
|
4194
|
+
suite.result.errors.push(processError(new Error(message)));
|
|
4195
|
+
suite.result.state = "fail";
|
|
4196
|
+
}
|
|
4197
|
+
await rpc().snapshotSaved(result);
|
|
4198
|
+
}
|
|
4199
|
+
this.workerState.current = suite.suite || suite.file;
|
|
4200
|
+
}
|
|
4201
|
+
onAfterRunTask(test) {
|
|
4202
|
+
if (this.config.logHeapUsage && typeof process !== "undefined") test.result.heap = process.memoryUsage().heapUsed;
|
|
4203
|
+
this.workerState.current = test.suite || test.file;
|
|
4204
|
+
}
|
|
4205
|
+
cancel(_reason) {
|
|
4206
|
+
this.cancelRun = true;
|
|
4207
|
+
}
|
|
4208
|
+
injectValue(key) {
|
|
4209
|
+
// inject has a very limiting type controlled by ProvidedContext
|
|
4210
|
+
// some tests override it which causes the build to fail
|
|
4211
|
+
return inject(key);
|
|
4212
|
+
}
|
|
4213
|
+
async onBeforeRunTask(test) {
|
|
4214
|
+
if (this.cancelRun) test.mode = "skip";
|
|
4215
|
+
if (test.mode !== "run" && test.mode !== "queued") return;
|
|
4216
|
+
this.workerState.current = test;
|
|
4217
|
+
}
|
|
4218
|
+
async onBeforeRunSuite(suite) {
|
|
4219
|
+
if (this.cancelRun) suite.mode = "skip";
|
|
4220
|
+
// initialize snapshot state before running file suite
|
|
4221
|
+
if (suite.mode !== "skip" && "filepath" in suite) await this.snapshotClient.setup(suite.file.filepath, this.workerState.config.snapshotOptions);
|
|
4222
|
+
this.workerState.current = suite;
|
|
4223
|
+
}
|
|
4224
|
+
onBeforeTryTask(test) {
|
|
4225
|
+
clearModuleMocks(this.config);
|
|
4226
|
+
this.snapshotClient.clearTest(test.file.filepath, test.id);
|
|
4227
|
+
setState({
|
|
4228
|
+
assertionCalls: 0,
|
|
4229
|
+
isExpectingAssertions: false,
|
|
4230
|
+
isExpectingAssertionsError: null,
|
|
4231
|
+
expectedAssertionsNumber: null,
|
|
4232
|
+
expectedAssertionsNumberErrorGen: null,
|
|
4233
|
+
currentTestName: getTestName(test),
|
|
4234
|
+
snapshotState: this.snapshotClient.getSnapshotState(test.file.filepath)
|
|
4235
|
+
}, globalThis[GLOBAL_EXPECT]);
|
|
4236
|
+
}
|
|
4237
|
+
onAfterTryTask(test) {
|
|
4238
|
+
const { assertionCalls, expectedAssertionsNumber, expectedAssertionsNumberErrorGen, isExpectingAssertions, isExpectingAssertionsError } = test.context._local ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]);
|
|
4239
|
+
if (expectedAssertionsNumber !== null && assertionCalls !== expectedAssertionsNumber) throw expectedAssertionsNumberErrorGen();
|
|
4240
|
+
if (isExpectingAssertions === true && assertionCalls === 0) throw isExpectingAssertionsError;
|
|
4241
|
+
if (this.config.expect.requireAssertions && assertionCalls === 0) throw this.assertionsErrors.get(test);
|
|
4242
|
+
}
|
|
4243
|
+
extendTaskContext(context) {
|
|
4244
|
+
// create error during the test initialization so we have a nice stack trace
|
|
4245
|
+
if (this.config.expect.requireAssertions) this.assertionsErrors.set(context.task, /* @__PURE__ */ new Error("expected any number of assertion, but got none"));
|
|
4246
|
+
let _expect;
|
|
4247
|
+
Object.defineProperty(context, "expect", { get() {
|
|
4248
|
+
if (!_expect) _expect = createExpect(context.task);
|
|
4249
|
+
return _expect;
|
|
4250
|
+
} });
|
|
4251
|
+
Object.defineProperty(context, "_local", { get() {
|
|
4252
|
+
return _expect != null;
|
|
4253
|
+
} });
|
|
4254
|
+
return context;
|
|
4255
|
+
}
|
|
4256
|
+
getImportDurations() {
|
|
4257
|
+
const importDurations = {};
|
|
4258
|
+
const entries = this.workerState.moduleExecutionInfo?.entries() || [];
|
|
4259
|
+
for (const [filepath, { duration, selfTime, external, importer }] of entries) importDurations[normalize(filepath)] = {
|
|
4260
|
+
selfTime,
|
|
4261
|
+
totalTime: duration,
|
|
4262
|
+
external,
|
|
4263
|
+
importer
|
|
4264
|
+
};
|
|
4265
|
+
return importDurations;
|
|
4266
|
+
}
|
|
4267
|
+
trace = (name, attributes, cb) => {
|
|
4268
|
+
const options = typeof attributes === "object" ? { attributes } : {};
|
|
4269
|
+
return this._otel.$(`vitest.test.runner.${name}`, options, cb || attributes);
|
|
4270
|
+
};
|
|
4271
|
+
__setTraces(traces) {
|
|
4272
|
+
this._otel = traces;
|
|
4273
|
+
}
|
|
4274
|
+
static createTaskCollector = createTaskCollector;
|
|
4275
|
+
static getCurrentSuite = getCurrentSuite;
|
|
4276
|
+
static getCurrentTest = getCurrentTest;
|
|
4277
|
+
static createChainable = createChainable;
|
|
4278
|
+
static getSuiteHooks = getHooks;
|
|
4279
|
+
static getTestFn = getFn;
|
|
4280
|
+
static setSuiteHooks = getHooks;
|
|
4281
|
+
static setTestFn = getFn;
|
|
4282
|
+
/**
|
|
4283
|
+
* @deprecated
|
|
4284
|
+
*/
|
|
4285
|
+
static getBenchFn = getBenchFn;
|
|
4286
|
+
/**
|
|
4287
|
+
* @deprecated
|
|
4288
|
+
*/
|
|
4289
|
+
static getBenchOptions = getBenchOptions;
|
|
4290
|
+
}
|
|
4291
|
+
function clearModuleMocks(config) {
|
|
4292
|
+
const { clearMocks, mockReset, restoreMocks, unstubEnvs, unstubGlobals } = config;
|
|
4293
|
+
if (restoreMocks) vi.restoreAllMocks();
|
|
4294
|
+
if (mockReset) vi.resetAllMocks();
|
|
4295
|
+
if (clearMocks) vi.clearAllMocks();
|
|
4296
|
+
if (unstubEnvs) vi.unstubAllEnvs();
|
|
4297
|
+
if (unstubGlobals) vi.unstubAllGlobals();
|
|
4298
|
+
}
|
|
4299
|
+
|
|
4300
|
+
export { NodeBenchmarkRunner as N, TestRunner as T, assert as a, vitest as b, createExpect as c, globalExpect as g, inject as i, should as s, vi as v };
|