vitest 4.0.7 → 4.0.8
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 +2 -2
- package/dist/browser.js +2 -2
- package/dist/chunks/{base.D3GxgUMI.js → base.BgTO2qAg.js} +71 -36
- package/dist/chunks/{benchmark.DHKMYAts.js → benchmark.B3N2zMcH.js} +9 -4
- package/dist/chunks/{browser.d.-LKfRopd.d.ts → browser.d.DTTM2PTh.d.ts} +1 -1
- package/dist/chunks/{cac.G9DAn-c7.js → cac.CfkWq8Qy.js} +115 -42
- package/dist/chunks/{cli-api.Csks4as1.js → cli-api.BQ-bjcRi.js} +1857 -839
- package/dist/chunks/console.Cf-YriPC.js +146 -0
- package/dist/chunks/{coverage.C2LA1DSL.js → coverage.NVjCOln1.js} +273 -103
- package/dist/chunks/{creator.cqqifzG7.js → creator.fzVyoMf3.js} +74 -30
- package/dist/chunks/{date.-jtEtIeV.js → date.Bq6ZW5rf.js} +17 -6
- package/dist/chunks/{git.BFNcloKD.js → git.Bm2pzPAa.js} +3 -3
- package/dist/chunks/{global.d.DxtanrNO.d.ts → global.d.DVdCfKp5.d.ts} +1 -1
- package/dist/chunks/{globals.BGT_RUsD.js → globals.DOh96BiR.js} +5 -5
- package/dist/chunks/{index.DEPqWSIZ.js → index.BY4-tcno.js} +33 -16
- package/dist/chunks/{index.Bgo3tNWt.js → index.DAL392Ss.js} +40 -15
- package/dist/chunks/{index.RwjEGCQ0.js → index.DIFZf73e.js} +2 -2
- package/dist/chunks/{index.CWIFvlX5.js → index.DfKyPFVi.js} +159 -54
- package/dist/chunks/{index.CVpyv-Zg.js → index.kotH7DY7.js} +832 -373
- package/dist/chunks/{index.jMQYiEWE.js → index.op2Re5rn.js} +22 -12
- package/dist/chunks/{init-forks.IU-xQ2_X.js → init-forks.2hx7cf78.js} +14 -4
- package/dist/chunks/{init-threads.C_NWvZkU.js → init-threads.Cm4OCIWA.js} +1 -1
- package/dist/chunks/{init.fmH9J833.js → init.DMDG-idf.js} +53 -30
- package/dist/chunks/{inspector.DLZxSeU3.js → inspector.CvyFGlXm.js} +25 -10
- package/dist/chunks/{moduleRunner.d.DEkTotCv.d.ts → moduleRunner.d.CzOZ_4wC.d.ts} +1 -1
- package/dist/chunks/{node.BwAWWjHZ.js → node.Ce0vMQM7.js} +1 -1
- package/dist/chunks/{plugin.d.Cpes8Bt6.d.ts → plugin.d.D4RrtywJ.d.ts} +1 -1
- package/dist/chunks/{reporters.d.CSNcMDxF.d.ts → reporters.d.Da1D1VbQ.d.ts} +6 -5
- package/dist/chunks/{rpc.D38ahn14.js → rpc.BUV7uWKJ.js} +20 -7
- package/dist/chunks/{setup-common.DR1sucx6.js → setup-common.LGjNSzXp.js} +20 -8
- package/dist/chunks/{startModuleRunner.Cn7hCL7D.js → startModuleRunner.BOmUtLIO.js} +206 -83
- package/dist/chunks/{test.B6aJd6T3.js → test.ClrAtjMv.js} +48 -22
- package/dist/chunks/{utils.CG9h5ccR.js → utils.DvEY5TfP.js} +14 -5
- package/dist/chunks/{vi.BZvkKVkM.js → vi.Bgcdy3bQ.js} +261 -111
- package/dist/chunks/{vm.BL7_zzOr.js → vm.BIkCDs68.js} +177 -71
- package/dist/chunks/{worker.d.D25zYZ7N.d.ts → worker.d.DadbA89M.d.ts} +30 -2
- package/dist/cli.js +2 -2
- package/dist/config.d.ts +5 -5
- package/dist/coverage.d.ts +3 -3
- package/dist/coverage.js +1 -1
- package/dist/environments.js +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/module-evaluator.d.ts +2 -2
- package/dist/module-evaluator.js +85 -35
- package/dist/module-runner.js +2 -2
- package/dist/node.d.ts +7 -7
- package/dist/node.js +16 -12
- package/dist/reporters.d.ts +3 -3
- package/dist/reporters.js +2 -2
- package/dist/runners.js +7 -7
- package/dist/snapshot.js +2 -2
- package/dist/suite.js +2 -2
- package/dist/worker.d.ts +1 -1
- package/dist/worker.js +15 -15
- package/dist/workers/forks.js +16 -16
- package/dist/workers/runVmTests.js +41 -22
- package/dist/workers/threads.js +16 -16
- package/dist/workers/vmForks.js +11 -11
- package/dist/workers/vmThreads.js +11 -11
- package/package.json +20 -20
- package/dist/chunks/console.CTJL2nuH.js +0 -115
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { chai, equals, iterableEquality, subsetEquality, JestExtend, JestChaiExpect, JestAsymmetricMatchers, GLOBAL_EXPECT, ASYMMETRIC_MATCHERS_OBJECT, getState, setState, addCustomEqualityTesters, customMatchers } from '@vitest/expect';
|
|
2
2
|
import { getCurrentTest } from '@vitest/runner';
|
|
3
3
|
import { getNames, getTestName } from '@vitest/runner/utils';
|
|
4
|
-
import { g as getWorkerState, i as isChildProcess, w as waitForImportsToResolve, r as resetModules } from './utils.
|
|
4
|
+
import { g as getWorkerState, i as isChildProcess, w as waitForImportsToResolve, r as resetModules } from './utils.DvEY5TfP.js';
|
|
5
5
|
import { getSafeTimers } from '@vitest/utils/timers';
|
|
6
6
|
import { stripSnapshotIndentation, addSerializer, SnapshotClient } from '@vitest/snapshot';
|
|
7
7
|
import '@vitest/utils/error';
|
|
@@ -10,7 +10,7 @@ import { fn, spyOn, restoreAllMocks, resetAllMocks, clearAllMocks, isMockFunctio
|
|
|
10
10
|
import '@vitest/utils/offset';
|
|
11
11
|
import { parseSingleStack } from '@vitest/utils/source-map';
|
|
12
12
|
import { c as commonjsGlobal } from './_commonjsHelpers.BFTU3MAI.js';
|
|
13
|
-
import { R as RealDate, r as resetDate, m as mockDate } from './date
|
|
13
|
+
import { R as RealDate, r as resetDate, m as mockDate } from './date.Bq6ZW5rf.js';
|
|
14
14
|
|
|
15
15
|
// these matchers are not supported because they don't make sense with poll
|
|
16
16
|
const unsupported = [
|
|
@@ -27,7 +27,10 @@ const unsupported = [
|
|
|
27
27
|
];
|
|
28
28
|
function createExpectPoll(expect) {
|
|
29
29
|
return function poll(fn, options = {}) {
|
|
30
|
-
const defaults = getWorkerState().config.expect?.poll ?? {}
|
|
30
|
+
const defaults = getWorkerState().config.expect?.poll ?? {};
|
|
31
|
+
const { interval = defaults.interval ?? 50, timeout = defaults.timeout ?? 1e3, message } = options;
|
|
32
|
+
// @ts-expect-error private poll access
|
|
33
|
+
const assertion = expect(null, message).withContext({ poll: true });
|
|
31
34
|
fn = fn.bind(assertion);
|
|
32
35
|
const test = chai.util.flag(assertion, "vitest-test");
|
|
33
36
|
if (!test) throw new Error("expect.poll() must be called inside a test");
|
|
@@ -37,31 +40,43 @@ function createExpectPoll(expect) {
|
|
|
37
40
|
if (key === "assert") return assertionFunction;
|
|
38
41
|
if (typeof key === "string" && unsupported.includes(key)) throw new SyntaxError(`expect.poll() is not supported in combination with .${key}(). Use vi.waitFor() if your assertion condition is unstable.`);
|
|
39
42
|
return function(...args) {
|
|
40
|
-
const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR")
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
|
|
44
|
+
const promise = () => new Promise((resolve, reject) => {
|
|
45
|
+
let intervalId;
|
|
46
|
+
let timeoutId;
|
|
47
|
+
let lastError;
|
|
48
|
+
const { setTimeout, clearTimeout } = getSafeTimers();
|
|
49
|
+
const check = async () => {
|
|
43
50
|
try {
|
|
44
51
|
chai.util.flag(assertion, "_name", key);
|
|
45
52
|
const obj = await fn();
|
|
46
|
-
chai.util.flag(assertion, "object", obj)
|
|
53
|
+
chai.util.flag(assertion, "object", obj);
|
|
54
|
+
resolve(await assertionFunction.call(assertion, ...args));
|
|
55
|
+
clearTimeout(intervalId);
|
|
56
|
+
clearTimeout(timeoutId);
|
|
47
57
|
} catch (err) {
|
|
48
|
-
|
|
58
|
+
lastError = err;
|
|
59
|
+
if (!chai.util.flag(assertion, "_isLastPollAttempt")) intervalId = setTimeout(check, interval);
|
|
49
60
|
}
|
|
50
61
|
};
|
|
51
62
|
timeoutId = setTimeout(() => {
|
|
52
|
-
clearTimeout(intervalId)
|
|
63
|
+
clearTimeout(intervalId);
|
|
64
|
+
chai.util.flag(assertion, "_isLastPollAttempt", true);
|
|
53
65
|
const rejectWithCause = (error) => {
|
|
54
66
|
if (error.cause == null) error.cause = /* @__PURE__ */ new Error("Matcher did not succeed in time.");
|
|
55
67
|
reject(copyStackTrace$1(error, STACK_TRACE_ERROR));
|
|
56
68
|
};
|
|
57
69
|
check().then(() => rejectWithCause(lastError)).catch((e) => rejectWithCause(e));
|
|
58
|
-
}, timeout)
|
|
70
|
+
}, timeout);
|
|
71
|
+
check();
|
|
59
72
|
});
|
|
60
73
|
let awaited = false;
|
|
61
|
-
test.onFinished ??= []
|
|
74
|
+
test.onFinished ??= [];
|
|
75
|
+
test.onFinished.push(() => {
|
|
62
76
|
if (!awaited) {
|
|
63
|
-
const negated = chai.util.flag(assertion, "negate") ? "not." : ""
|
|
64
|
-
|
|
77
|
+
const negated = chai.util.flag(assertion, "negate") ? "not." : "";
|
|
78
|
+
const assertionString = `expect.${chai.util.flag(assertion, "_poll.element") ? "element(locator)" : "poll(assertion)"}.${negated}${String(key)}()`;
|
|
79
|
+
throw copyStackTrace$1(/* @__PURE__ */ new Error(`${assertionString} was not awaited. This assertion is asynchronous and must be awaited; otherwise, it is not executed to avoid unhandled rejections:\n\nawait ${assertionString}\n`), STACK_TRACE_ERROR);
|
|
65
80
|
}
|
|
66
81
|
});
|
|
67
82
|
let resultPromise;
|
|
@@ -69,7 +84,8 @@ function createExpectPoll(expect) {
|
|
|
69
84
|
// so let's follow it
|
|
70
85
|
return {
|
|
71
86
|
then(onFulfilled, onRejected) {
|
|
72
|
-
|
|
87
|
+
awaited = true;
|
|
88
|
+
return (resultPromise ||= promise()).then(onFulfilled, onRejected);
|
|
73
89
|
},
|
|
74
90
|
catch(onRejected) {
|
|
75
91
|
return (resultPromise ||= promise()).catch(onRejected);
|
|
@@ -90,22 +106,27 @@ function copyStackTrace$1(target, source) {
|
|
|
90
106
|
}
|
|
91
107
|
|
|
92
108
|
function createAssertionMessage(util, assertion, hasArgs) {
|
|
93
|
-
const not = util.flag(assertion, "negate") ? "not." : ""
|
|
109
|
+
const not = util.flag(assertion, "negate") ? "not." : "";
|
|
110
|
+
const name = `${util.flag(assertion, "_name")}(${"expected" })`;
|
|
111
|
+
const promiseName = util.flag(assertion, "promise");
|
|
94
112
|
return `expect(actual)${promiseName ? `.${promiseName}` : ""}.${not}${name}`;
|
|
95
113
|
}
|
|
96
114
|
function recordAsyncExpect(_test, promise, assertion, error) {
|
|
97
115
|
const test = _test;
|
|
98
116
|
// record promise for test, that resolves before test ends
|
|
99
117
|
if (test && promise instanceof Promise) {
|
|
100
|
-
//
|
|
101
|
-
|
|
118
|
+
// if promise is explicitly awaited, remove it from the list
|
|
119
|
+
promise = promise.finally(() => {
|
|
102
120
|
if (!test.promises) return;
|
|
103
121
|
const index = test.promises.indexOf(promise);
|
|
104
122
|
if (index !== -1) test.promises.splice(index, 1);
|
|
105
|
-
})
|
|
123
|
+
});
|
|
124
|
+
// record promise
|
|
125
|
+
if (!test.promises) test.promises = [];
|
|
106
126
|
test.promises.push(promise);
|
|
107
127
|
let resolved = false;
|
|
108
|
-
|
|
128
|
+
test.onFinished ??= [];
|
|
129
|
+
test.onFinished.push(() => {
|
|
109
130
|
if (!resolved) {
|
|
110
131
|
const stack = (globalThis.__vitest_worker__?.onFilterStackTrace || ((s) => s || ""))(error.stack);
|
|
111
132
|
console.warn([
|
|
@@ -115,9 +136,11 @@ function recordAsyncExpect(_test, promise, assertion, error) {
|
|
|
115
136
|
stack
|
|
116
137
|
].join(""));
|
|
117
138
|
}
|
|
118
|
-
})
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
119
141
|
then(onFulfilled, onRejected) {
|
|
120
|
-
|
|
142
|
+
resolved = true;
|
|
143
|
+
return promise.then(onFulfilled, onRejected);
|
|
121
144
|
},
|
|
122
145
|
catch(onRejected) {
|
|
123
146
|
return promise.catch(onRejected);
|
|
@@ -165,9 +188,14 @@ const SnapshotPlugin = (chai, utils) => {
|
|
|
165
188
|
return test;
|
|
166
189
|
}
|
|
167
190
|
for (const key of ["matchSnapshot", "toMatchSnapshot"]) utils.addMethod(chai.Assertion.prototype, key, function(properties, message) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
191
|
+
utils.flag(this, "_name", key);
|
|
192
|
+
if (utils.flag(this, "negate")) throw new Error(`${key} cannot be used with "not"`);
|
|
193
|
+
const expected = utils.flag(this, "object");
|
|
194
|
+
const test = getTest(key, this);
|
|
195
|
+
if (typeof properties === "string" && typeof message === "undefined") {
|
|
196
|
+
message = properties;
|
|
197
|
+
properties = void 0;
|
|
198
|
+
}
|
|
171
199
|
const errorMessage = utils.flag(this, "message");
|
|
172
200
|
getSnapshotClient().assert({
|
|
173
201
|
received: expected,
|
|
@@ -179,22 +207,33 @@ const SnapshotPlugin = (chai, utils) => {
|
|
|
179
207
|
});
|
|
180
208
|
});
|
|
181
209
|
utils.addMethod(chai.Assertion.prototype, "toMatchFileSnapshot", function(file, message) {
|
|
182
|
-
|
|
183
|
-
|
|
210
|
+
utils.flag(this, "_name", "toMatchFileSnapshot");
|
|
211
|
+
if (utils.flag(this, "negate")) throw new Error("toMatchFileSnapshot cannot be used with \"not\"");
|
|
212
|
+
const error = /* @__PURE__ */ new Error("resolves");
|
|
213
|
+
const expected = utils.flag(this, "object");
|
|
214
|
+
const test = getTest("toMatchFileSnapshot", this);
|
|
215
|
+
const errorMessage = utils.flag(this, "message");
|
|
216
|
+
return recordAsyncExpect(test, getSnapshotClient().assertRaw({
|
|
184
217
|
received: expected,
|
|
185
218
|
message,
|
|
186
219
|
isInline: false,
|
|
187
220
|
rawSnapshot: { file },
|
|
188
221
|
errorMessage,
|
|
189
222
|
...getTestNames(test)
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
223
|
+
}), createAssertionMessage(utils, this), error);
|
|
224
|
+
});
|
|
225
|
+
utils.addMethod(chai.Assertion.prototype, "toMatchInlineSnapshot", function __INLINE_SNAPSHOT__(properties, inlineSnapshot, message) {
|
|
226
|
+
utils.flag(this, "_name", "toMatchInlineSnapshot");
|
|
227
|
+
if (utils.flag(this, "negate")) throw new Error("toMatchInlineSnapshot cannot be used with \"not\"");
|
|
194
228
|
const test = getTest("toMatchInlineSnapshot", this);
|
|
195
229
|
if (test.each || test.suite?.each) throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each");
|
|
196
|
-
const expected = utils.flag(this, "object")
|
|
197
|
-
|
|
230
|
+
const expected = utils.flag(this, "object");
|
|
231
|
+
const error = utils.flag(this, "error");
|
|
232
|
+
if (typeof properties === "string") {
|
|
233
|
+
message = inlineSnapshot;
|
|
234
|
+
inlineSnapshot = properties;
|
|
235
|
+
properties = void 0;
|
|
236
|
+
}
|
|
198
237
|
if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
|
|
199
238
|
const errorMessage = utils.flag(this, "message");
|
|
200
239
|
getSnapshotClient().assert({
|
|
@@ -207,20 +246,29 @@ const SnapshotPlugin = (chai, utils) => {
|
|
|
207
246
|
errorMessage,
|
|
208
247
|
...getTestNames(test)
|
|
209
248
|
});
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
|
|
249
|
+
});
|
|
250
|
+
utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingSnapshot", function(message) {
|
|
251
|
+
utils.flag(this, "_name", "toThrowErrorMatchingSnapshot");
|
|
252
|
+
if (utils.flag(this, "negate")) throw new Error("toThrowErrorMatchingSnapshot cannot be used with \"not\"");
|
|
253
|
+
const expected = utils.flag(this, "object");
|
|
254
|
+
const test = getTest("toThrowErrorMatchingSnapshot", this);
|
|
255
|
+
const promise = utils.flag(this, "promise");
|
|
256
|
+
const errorMessage = utils.flag(this, "message");
|
|
213
257
|
getSnapshotClient().assert({
|
|
214
258
|
received: getError(expected, promise),
|
|
215
259
|
message,
|
|
216
260
|
errorMessage,
|
|
217
261
|
...getTestNames(test)
|
|
218
262
|
});
|
|
219
|
-
})
|
|
263
|
+
});
|
|
264
|
+
utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingInlineSnapshot", function __INLINE_SNAPSHOT__(inlineSnapshot, message) {
|
|
220
265
|
if (utils.flag(this, "negate")) throw new Error("toThrowErrorMatchingInlineSnapshot cannot be used with \"not\"");
|
|
221
266
|
const test = getTest("toThrowErrorMatchingInlineSnapshot", this);
|
|
222
267
|
if (test.each || test.suite?.each) throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each");
|
|
223
|
-
const expected = utils.flag(this, "object")
|
|
268
|
+
const expected = utils.flag(this, "object");
|
|
269
|
+
const error = utils.flag(this, "error");
|
|
270
|
+
const promise = utils.flag(this, "promise");
|
|
271
|
+
const errorMessage = utils.flag(this, "message");
|
|
224
272
|
if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
|
|
225
273
|
getSnapshotClient().assert({
|
|
226
274
|
received: getError(expected, promise),
|
|
@@ -231,19 +279,30 @@ const SnapshotPlugin = (chai, utils) => {
|
|
|
231
279
|
errorMessage,
|
|
232
280
|
...getTestNames(test)
|
|
233
281
|
});
|
|
234
|
-
})
|
|
282
|
+
});
|
|
283
|
+
utils.addMethod(chai.expect, "addSnapshotSerializer", addSerializer);
|
|
235
284
|
};
|
|
236
285
|
|
|
237
|
-
chai.use(JestExtend)
|
|
286
|
+
chai.use(JestExtend);
|
|
287
|
+
chai.use(JestChaiExpect);
|
|
288
|
+
chai.use(SnapshotPlugin);
|
|
289
|
+
chai.use(JestAsymmetricMatchers);
|
|
238
290
|
|
|
239
291
|
function createExpect(test) {
|
|
240
292
|
const expect = ((value, message) => {
|
|
241
293
|
const { assertionCalls } = getState(expect);
|
|
242
294
|
setState({ assertionCalls: assertionCalls + 1 }, expect);
|
|
243
|
-
const assert = chai.expect(value, message)
|
|
244
|
-
|
|
295
|
+
const assert = chai.expect(value, message);
|
|
296
|
+
const _test = test || getCurrentTest();
|
|
297
|
+
if (_test)
|
|
298
|
+
// @ts-expect-error internal
|
|
299
|
+
return assert.withTest(_test);
|
|
300
|
+
else return assert;
|
|
245
301
|
});
|
|
246
|
-
Object.assign(expect, chai.expect)
|
|
302
|
+
Object.assign(expect, chai.expect);
|
|
303
|
+
Object.assign(expect, globalThis[ASYMMETRIC_MATCHERS_OBJECT]);
|
|
304
|
+
expect.getState = () => getState(expect);
|
|
305
|
+
expect.setState = (state) => setState(state, expect);
|
|
247
306
|
// @ts-expect-error global is not typed
|
|
248
307
|
const globalState = getState(globalThis[GLOBAL_EXPECT]) || {};
|
|
249
308
|
setState({
|
|
@@ -257,10 +316,17 @@ function createExpect(test) {
|
|
|
257
316
|
return getWorkerState().filepath;
|
|
258
317
|
},
|
|
259
318
|
currentTestName: test ? getTestName(test) : globalState.currentTestName
|
|
260
|
-
}, expect)
|
|
319
|
+
}, expect);
|
|
320
|
+
expect.assert = chai.assert;
|
|
321
|
+
// @ts-expect-error untyped
|
|
322
|
+
expect.extend = (matchers) => chai.expect.extend(expect, matchers);
|
|
323
|
+
expect.addEqualityTesters = (customTesters) => addCustomEqualityTesters(customTesters);
|
|
324
|
+
expect.soft = (...args) => {
|
|
261
325
|
// @ts-expect-error private soft access
|
|
262
326
|
return expect(...args).withContext({ soft: true });
|
|
263
|
-
}
|
|
327
|
+
};
|
|
328
|
+
expect.poll = createExpectPoll(expect);
|
|
329
|
+
expect.unreachable = (message) => {
|
|
264
330
|
chai.assert.fail(`expected${message ? ` "${message}" ` : " "}not to be reached`);
|
|
265
331
|
};
|
|
266
332
|
function assertions(expected) {
|
|
@@ -279,7 +345,10 @@ function createExpect(test) {
|
|
|
279
345
|
isExpectingAssertionsError: error
|
|
280
346
|
});
|
|
281
347
|
}
|
|
282
|
-
|
|
348
|
+
chai.util.addMethod(expect, "assertions", assertions);
|
|
349
|
+
chai.util.addMethod(expect, "hasAssertions", hasAssertions);
|
|
350
|
+
expect.extend(customMatchers);
|
|
351
|
+
return expect;
|
|
283
352
|
}
|
|
284
353
|
const globalExpect = createExpect();
|
|
285
354
|
Object.defineProperty(globalThis, GLOBAL_EXPECT, {
|
|
@@ -3406,7 +3475,11 @@ class FakeTimers {
|
|
|
3406
3475
|
_userConfig;
|
|
3407
3476
|
_now = RealDate.now;
|
|
3408
3477
|
constructor({ global, config }) {
|
|
3409
|
-
this._userConfig = config
|
|
3478
|
+
this._userConfig = config;
|
|
3479
|
+
this._fakingDate = null;
|
|
3480
|
+
this._fakingTime = false;
|
|
3481
|
+
this._fakeTimers = fakeTimersSrcExports.withGlobal(global);
|
|
3482
|
+
this._global = global;
|
|
3410
3483
|
}
|
|
3411
3484
|
clearAllTimers() {
|
|
3412
3485
|
if (this._fakingTime) this._clock.reset();
|
|
@@ -3427,13 +3500,19 @@ class FakeTimers {
|
|
|
3427
3500
|
if (this._checkFakeTimers()) await this._clock.runToLastAsync();
|
|
3428
3501
|
}
|
|
3429
3502
|
advanceTimersToNextTimer(steps = 1) {
|
|
3430
|
-
if (this._checkFakeTimers()) {
|
|
3431
|
-
|
|
3503
|
+
if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
|
|
3504
|
+
this._clock.next();
|
|
3505
|
+
// Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
|
|
3506
|
+
this._clock.tick(0);
|
|
3507
|
+
if (this._clock.countTimers() === 0) break;
|
|
3432
3508
|
}
|
|
3433
3509
|
}
|
|
3434
3510
|
async advanceTimersToNextTimerAsync(steps = 1) {
|
|
3435
|
-
if (this._checkFakeTimers()) {
|
|
3436
|
-
|
|
3511
|
+
if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
|
|
3512
|
+
await this._clock.nextAsync();
|
|
3513
|
+
// Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
|
|
3514
|
+
this._clock.tick(0);
|
|
3515
|
+
if (this._clock.countTimers() === 0) break;
|
|
3437
3516
|
}
|
|
3438
3517
|
}
|
|
3439
3518
|
advanceTimersByTime(msToRun) {
|
|
@@ -3451,12 +3530,21 @@ class FakeTimers {
|
|
|
3451
3530
|
this._clock.runMicrotasks();
|
|
3452
3531
|
}
|
|
3453
3532
|
useRealTimers() {
|
|
3454
|
-
if (this._fakingDate)
|
|
3455
|
-
|
|
3533
|
+
if (this._fakingDate) {
|
|
3534
|
+
resetDate();
|
|
3535
|
+
this._fakingDate = null;
|
|
3536
|
+
}
|
|
3537
|
+
if (this._fakingTime) {
|
|
3538
|
+
this._clock.uninstall();
|
|
3539
|
+
this._fakingTime = false;
|
|
3540
|
+
}
|
|
3456
3541
|
}
|
|
3457
3542
|
useFakeTimers() {
|
|
3458
3543
|
const fakeDate = this._fakingDate || Date.now();
|
|
3459
|
-
if (this._fakingDate)
|
|
3544
|
+
if (this._fakingDate) {
|
|
3545
|
+
resetDate();
|
|
3546
|
+
this._fakingDate = null;
|
|
3547
|
+
}
|
|
3460
3548
|
if (this._fakingTime) this._clock.uninstall();
|
|
3461
3549
|
const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick" && timer !== "queueMicrotask");
|
|
3462
3550
|
if (this._userConfig?.toFake?.includes("nextTick") && isChildProcess()) throw new Error("process.nextTick cannot be mocked inside child_process");
|
|
@@ -3465,18 +3553,23 @@ class FakeTimers {
|
|
|
3465
3553
|
...this._userConfig,
|
|
3466
3554
|
toFake: this._userConfig?.toFake || toFake,
|
|
3467
3555
|
ignoreMissingTimers: true
|
|
3468
|
-
})
|
|
3556
|
+
});
|
|
3557
|
+
this._fakingTime = true;
|
|
3469
3558
|
}
|
|
3470
3559
|
reset() {
|
|
3471
3560
|
if (this._checkFakeTimers()) {
|
|
3472
3561
|
const { now } = this._clock;
|
|
3473
|
-
this._clock.reset()
|
|
3562
|
+
this._clock.reset();
|
|
3563
|
+
this._clock.setSystemTime(now);
|
|
3474
3564
|
}
|
|
3475
3565
|
}
|
|
3476
3566
|
setSystemTime(now) {
|
|
3477
3567
|
const date = typeof now === "undefined" || now instanceof Date ? now : new Date(now);
|
|
3478
3568
|
if (this._fakingTime) this._clock.setSystemTime(date);
|
|
3479
|
-
else
|
|
3569
|
+
else {
|
|
3570
|
+
this._fakingDate = date ?? new Date(this.getRealSystemTime());
|
|
3571
|
+
mockDate(this._fakingDate);
|
|
3572
|
+
}
|
|
3480
3573
|
}
|
|
3481
3574
|
getMockedSystemTime() {
|
|
3482
3575
|
return this._fakingTime ? new Date(this._clock.now) : this._fakingDate;
|
|
@@ -3485,7 +3578,8 @@ class FakeTimers {
|
|
|
3485
3578
|
return this._now();
|
|
3486
3579
|
}
|
|
3487
3580
|
getTimerCount() {
|
|
3488
|
-
|
|
3581
|
+
if (this._checkFakeTimers()) return this._clock.countTimers();
|
|
3582
|
+
return 0;
|
|
3489
3583
|
}
|
|
3490
3584
|
configure(config) {
|
|
3491
3585
|
this._userConfig = config;
|
|
@@ -3504,68 +3598,96 @@ function copyStackTrace(target, source) {
|
|
|
3504
3598
|
return target;
|
|
3505
3599
|
}
|
|
3506
3600
|
function waitFor(callback, options = {}) {
|
|
3507
|
-
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers()
|
|
3601
|
+
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
|
|
3602
|
+
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
|
|
3603
|
+
const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
|
|
3508
3604
|
return new Promise((resolve, reject) => {
|
|
3509
|
-
let lastError
|
|
3605
|
+
let lastError;
|
|
3606
|
+
let promiseStatus = "idle";
|
|
3607
|
+
let timeoutId;
|
|
3608
|
+
let intervalId;
|
|
3510
3609
|
const onResolve = (result) => {
|
|
3511
3610
|
if (timeoutId) clearTimeout(timeoutId);
|
|
3512
3611
|
if (intervalId) clearInterval(intervalId);
|
|
3513
3612
|
resolve(result);
|
|
3514
|
-
}
|
|
3613
|
+
};
|
|
3614
|
+
const handleTimeout = () => {
|
|
3515
3615
|
if (intervalId) clearInterval(intervalId);
|
|
3516
3616
|
let error = lastError;
|
|
3517
3617
|
if (!error) error = copyStackTrace(/* @__PURE__ */ new Error("Timed out in waitFor!"), STACK_TRACE_ERROR);
|
|
3518
3618
|
reject(error);
|
|
3519
|
-
}
|
|
3619
|
+
};
|
|
3620
|
+
const checkCallback = () => {
|
|
3520
3621
|
if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
|
|
3521
|
-
if (promiseStatus
|
|
3622
|
+
if (promiseStatus === "pending") return;
|
|
3623
|
+
try {
|
|
3522
3624
|
const result = callback();
|
|
3523
3625
|
if (result !== null && typeof result === "object" && typeof result.then === "function") {
|
|
3524
3626
|
const thenable = result;
|
|
3525
|
-
promiseStatus = "pending"
|
|
3526
|
-
|
|
3627
|
+
promiseStatus = "pending";
|
|
3628
|
+
thenable.then((resolvedValue) => {
|
|
3629
|
+
promiseStatus = "resolved";
|
|
3630
|
+
onResolve(resolvedValue);
|
|
3527
3631
|
}, (rejectedValue) => {
|
|
3528
|
-
promiseStatus = "rejected"
|
|
3632
|
+
promiseStatus = "rejected";
|
|
3633
|
+
lastError = rejectedValue;
|
|
3529
3634
|
});
|
|
3530
|
-
} else
|
|
3635
|
+
} else {
|
|
3636
|
+
onResolve(result);
|
|
3637
|
+
return true;
|
|
3638
|
+
}
|
|
3531
3639
|
} catch (error) {
|
|
3532
3640
|
lastError = error;
|
|
3533
3641
|
}
|
|
3534
3642
|
};
|
|
3535
|
-
checkCallback()
|
|
3643
|
+
if (checkCallback() === true) return;
|
|
3644
|
+
timeoutId = setTimeout(handleTimeout, timeout);
|
|
3645
|
+
intervalId = setInterval(checkCallback, interval);
|
|
3536
3646
|
});
|
|
3537
3647
|
}
|
|
3538
3648
|
function waitUntil(callback, options = {}) {
|
|
3539
|
-
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers()
|
|
3649
|
+
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
|
|
3650
|
+
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
|
|
3651
|
+
const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
|
|
3540
3652
|
return new Promise((resolve, reject) => {
|
|
3541
|
-
let promiseStatus = "idle"
|
|
3653
|
+
let promiseStatus = "idle";
|
|
3654
|
+
let timeoutId;
|
|
3655
|
+
let intervalId;
|
|
3542
3656
|
const onReject = (error) => {
|
|
3543
3657
|
if (intervalId) clearInterval(intervalId);
|
|
3544
3658
|
if (!error) error = copyStackTrace(/* @__PURE__ */ new Error("Timed out in waitUntil!"), STACK_TRACE_ERROR);
|
|
3545
3659
|
reject(error);
|
|
3546
|
-
}
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3660
|
+
};
|
|
3661
|
+
const onResolve = (result) => {
|
|
3662
|
+
if (!result) return;
|
|
3663
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
3664
|
+
if (intervalId) clearInterval(intervalId);
|
|
3665
|
+
resolve(result);
|
|
3666
|
+
return true;
|
|
3667
|
+
};
|
|
3668
|
+
const checkCallback = () => {
|
|
3553
3669
|
if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
|
|
3554
|
-
if (promiseStatus
|
|
3670
|
+
if (promiseStatus === "pending") return;
|
|
3671
|
+
try {
|
|
3555
3672
|
const result = callback();
|
|
3556
3673
|
if (result !== null && typeof result === "object" && typeof result.then === "function") {
|
|
3557
3674
|
const thenable = result;
|
|
3558
|
-
promiseStatus = "pending"
|
|
3559
|
-
|
|
3675
|
+
promiseStatus = "pending";
|
|
3676
|
+
thenable.then((resolvedValue) => {
|
|
3677
|
+
promiseStatus = "resolved";
|
|
3678
|
+
onResolve(resolvedValue);
|
|
3560
3679
|
}, (rejectedValue) => {
|
|
3561
|
-
promiseStatus = "rejected"
|
|
3680
|
+
promiseStatus = "rejected";
|
|
3681
|
+
onReject(rejectedValue);
|
|
3562
3682
|
});
|
|
3563
3683
|
} else return onResolve(result);
|
|
3564
3684
|
} catch (error) {
|
|
3565
3685
|
onReject(error);
|
|
3566
3686
|
}
|
|
3567
3687
|
};
|
|
3568
|
-
checkCallback()
|
|
3688
|
+
if (checkCallback() === true) return;
|
|
3689
|
+
timeoutId = setTimeout(onReject, timeout);
|
|
3690
|
+
intervalId = setInterval(checkCallback, interval);
|
|
3569
3691
|
});
|
|
3570
3692
|
}
|
|
3571
3693
|
|
|
@@ -3576,11 +3698,15 @@ function createVitest() {
|
|
|
3576
3698
|
const timers = () => _timers ||= new FakeTimers({
|
|
3577
3699
|
global: globalThis,
|
|
3578
3700
|
config: state().config.fakeTimers
|
|
3579
|
-
})
|
|
3701
|
+
});
|
|
3702
|
+
const _stubsGlobal = /* @__PURE__ */ new Map();
|
|
3703
|
+
const _stubsEnv = /* @__PURE__ */ new Map();
|
|
3704
|
+
const _envBooleans = [
|
|
3580
3705
|
"PROD",
|
|
3581
3706
|
"DEV",
|
|
3582
3707
|
"SSR"
|
|
3583
|
-
]
|
|
3708
|
+
];
|
|
3709
|
+
const utils = {
|
|
3584
3710
|
useFakeTimers(config) {
|
|
3585
3711
|
if (isChildProcess()) {
|
|
3586
3712
|
if (config?.toFake?.includes("nextTick") || state().config?.fakeTimers?.toFake?.includes("nextTick")) throw new Error("vi.useFakeTimers({ toFake: [\"nextTick\"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.");
|
|
@@ -3590,49 +3716,62 @@ function createVitest() {
|
|
|
3590
3716
|
...config
|
|
3591
3717
|
});
|
|
3592
3718
|
else timers().configure(state().config.fakeTimers);
|
|
3593
|
-
|
|
3719
|
+
timers().useFakeTimers();
|
|
3720
|
+
return utils;
|
|
3594
3721
|
},
|
|
3595
3722
|
isFakeTimers() {
|
|
3596
3723
|
return timers().isFakeTimers();
|
|
3597
3724
|
},
|
|
3598
3725
|
useRealTimers() {
|
|
3599
|
-
|
|
3726
|
+
timers().useRealTimers();
|
|
3727
|
+
return utils;
|
|
3600
3728
|
},
|
|
3601
3729
|
runOnlyPendingTimers() {
|
|
3602
|
-
|
|
3730
|
+
timers().runOnlyPendingTimers();
|
|
3731
|
+
return utils;
|
|
3603
3732
|
},
|
|
3604
3733
|
async runOnlyPendingTimersAsync() {
|
|
3605
|
-
|
|
3734
|
+
await timers().runOnlyPendingTimersAsync();
|
|
3735
|
+
return utils;
|
|
3606
3736
|
},
|
|
3607
3737
|
runAllTimers() {
|
|
3608
|
-
|
|
3738
|
+
timers().runAllTimers();
|
|
3739
|
+
return utils;
|
|
3609
3740
|
},
|
|
3610
3741
|
async runAllTimersAsync() {
|
|
3611
|
-
|
|
3742
|
+
await timers().runAllTimersAsync();
|
|
3743
|
+
return utils;
|
|
3612
3744
|
},
|
|
3613
3745
|
runAllTicks() {
|
|
3614
|
-
|
|
3746
|
+
timers().runAllTicks();
|
|
3747
|
+
return utils;
|
|
3615
3748
|
},
|
|
3616
3749
|
advanceTimersByTime(ms) {
|
|
3617
|
-
|
|
3750
|
+
timers().advanceTimersByTime(ms);
|
|
3751
|
+
return utils;
|
|
3618
3752
|
},
|
|
3619
3753
|
async advanceTimersByTimeAsync(ms) {
|
|
3620
|
-
|
|
3754
|
+
await timers().advanceTimersByTimeAsync(ms);
|
|
3755
|
+
return utils;
|
|
3621
3756
|
},
|
|
3622
3757
|
advanceTimersToNextTimer() {
|
|
3623
|
-
|
|
3758
|
+
timers().advanceTimersToNextTimer();
|
|
3759
|
+
return utils;
|
|
3624
3760
|
},
|
|
3625
3761
|
async advanceTimersToNextTimerAsync() {
|
|
3626
|
-
|
|
3762
|
+
await timers().advanceTimersToNextTimerAsync();
|
|
3763
|
+
return utils;
|
|
3627
3764
|
},
|
|
3628
3765
|
advanceTimersToNextFrame() {
|
|
3629
|
-
|
|
3766
|
+
timers().advanceTimersToNextFrame();
|
|
3767
|
+
return utils;
|
|
3630
3768
|
},
|
|
3631
3769
|
getTimerCount() {
|
|
3632
3770
|
return timers().getTimerCount();
|
|
3633
3771
|
},
|
|
3634
3772
|
setSystemTime(time) {
|
|
3635
|
-
|
|
3773
|
+
timers().setSystemTime(time);
|
|
3774
|
+
return utils;
|
|
3636
3775
|
},
|
|
3637
3776
|
getMockedSystemTime() {
|
|
3638
3777
|
return timers().getMockedSystemTime();
|
|
@@ -3641,14 +3780,16 @@ function createVitest() {
|
|
|
3641
3780
|
return timers().getRealSystemTime();
|
|
3642
3781
|
},
|
|
3643
3782
|
clearAllTimers() {
|
|
3644
|
-
|
|
3783
|
+
timers().clearAllTimers();
|
|
3784
|
+
return utils;
|
|
3645
3785
|
},
|
|
3646
3786
|
spyOn,
|
|
3647
3787
|
fn,
|
|
3648
3788
|
waitFor,
|
|
3649
3789
|
waitUntil,
|
|
3650
3790
|
hoisted(factory) {
|
|
3651
|
-
|
|
3791
|
+
assertTypes(factory, "\"vi.hoisted\" factory", ["function"]);
|
|
3792
|
+
return factory();
|
|
3652
3793
|
},
|
|
3653
3794
|
mock(path, factory) {
|
|
3654
3795
|
if (typeof path !== "string") throw new TypeError(`vi.mock() expects a string path, but received a ${typeof path}`);
|
|
@@ -3687,22 +3828,26 @@ function createVitest() {
|
|
|
3687
3828
|
return isMockFunction(fn);
|
|
3688
3829
|
},
|
|
3689
3830
|
clearAllMocks() {
|
|
3690
|
-
|
|
3831
|
+
clearAllMocks();
|
|
3832
|
+
return utils;
|
|
3691
3833
|
},
|
|
3692
3834
|
resetAllMocks() {
|
|
3693
|
-
|
|
3835
|
+
resetAllMocks();
|
|
3836
|
+
return utils;
|
|
3694
3837
|
},
|
|
3695
3838
|
restoreAllMocks() {
|
|
3696
|
-
|
|
3839
|
+
restoreAllMocks();
|
|
3840
|
+
return utils;
|
|
3697
3841
|
},
|
|
3698
3842
|
stubGlobal(name, value) {
|
|
3699
3843
|
if (!_stubsGlobal.has(name)) _stubsGlobal.set(name, Object.getOwnPropertyDescriptor(globalThis, name));
|
|
3700
|
-
|
|
3844
|
+
Object.defineProperty(globalThis, name, {
|
|
3701
3845
|
value,
|
|
3702
3846
|
writable: true,
|
|
3703
3847
|
configurable: true,
|
|
3704
3848
|
enumerable: true
|
|
3705
|
-
})
|
|
3849
|
+
});
|
|
3850
|
+
return utils;
|
|
3706
3851
|
},
|
|
3707
3852
|
stubEnv(name, value) {
|
|
3708
3853
|
const env = state().metaEnv;
|
|
@@ -3713,20 +3858,25 @@ function createVitest() {
|
|
|
3713
3858
|
return utils;
|
|
3714
3859
|
},
|
|
3715
3860
|
unstubAllGlobals() {
|
|
3716
|
-
|
|
3861
|
+
_stubsGlobal.forEach((original, name) => {
|
|
3717
3862
|
if (!original) Reflect.deleteProperty(globalThis, name);
|
|
3718
3863
|
else Object.defineProperty(globalThis, name, original);
|
|
3719
|
-
})
|
|
3864
|
+
});
|
|
3865
|
+
_stubsGlobal.clear();
|
|
3866
|
+
return utils;
|
|
3720
3867
|
},
|
|
3721
3868
|
unstubAllEnvs() {
|
|
3722
3869
|
const env = state().metaEnv;
|
|
3723
|
-
|
|
3870
|
+
_stubsEnv.forEach((original, name) => {
|
|
3724
3871
|
if (original === void 0) delete env[name];
|
|
3725
3872
|
else env[name] = original;
|
|
3726
|
-
})
|
|
3873
|
+
});
|
|
3874
|
+
_stubsEnv.clear();
|
|
3875
|
+
return utils;
|
|
3727
3876
|
},
|
|
3728
3877
|
resetModules() {
|
|
3729
|
-
|
|
3878
|
+
resetModules(state().evaluatedModules);
|
|
3879
|
+
return utils;
|
|
3730
3880
|
},
|
|
3731
3881
|
async dynamicImportSettled() {
|
|
3732
3882
|
return waitForImportsToResolve();
|
|
@@ -3750,10 +3900,10 @@ function _mocker() {
|
|
|
3750
3900
|
} });
|
|
3751
3901
|
}
|
|
3752
3902
|
function getImporter(name) {
|
|
3753
|
-
const stackArray = createSimpleStackTrace({ stackTraceLimit: 5 }).split("\n")
|
|
3903
|
+
const stackArray = createSimpleStackTrace({ stackTraceLimit: 5 }).split("\n");
|
|
3904
|
+
return parseSingleStack(stackArray[stackArray.findLastIndex((stack) => {
|
|
3754
3905
|
return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`);
|
|
3755
|
-
});
|
|
3756
|
-
return parseSingleStack(stackArray[importerStackIndex + 1])?.file || "";
|
|
3906
|
+
}) + 1])?.file || "";
|
|
3757
3907
|
}
|
|
3758
3908
|
|
|
3759
3909
|
export { getSnapshotClient as a, assert as b, createExpect as c, vitest as d, globalExpect as g, inject as i, should as s, vi as v };
|