vitest 0.26.3 → 0.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +15 -66
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +15 -15
- package/dist/{chunk-api-setup.47a09f0f.js → chunk-api-setup.2be3cc38.js} +60 -31
- package/dist/{chunk-install-pkg.6dd2bae6.js → chunk-install-pkg.7b006b3e.js} +8 -8
- package/dist/{chunk-integrations-coverage.befed097.js → chunk-integrations-coverage.44413252.js} +19 -1
- package/dist/chunk-integrations-globals.02f1259c.js +27 -0
- package/dist/{chunk-typecheck-constants.06e1fe5b.js → chunk-mock-date.149ed990.js} +19 -32
- package/dist/{chunk-node-git.a90c0582.js → chunk-node-git.125c9008.js} +3 -4
- package/dist/{chunk-runtime-chain.f51aa930.js → chunk-runtime-chain.4e2aa823.js} +1193 -1029
- package/dist/{chunk-runtime-error.f5c8aaf2.js → chunk-runtime-error.97854396.js} +2 -2
- package/dist/{chunk-runtime-mocker.887bf8c8.js → chunk-runtime-mocker.4755840f.js} +10 -8
- package/dist/{chunk-runtime-rpc.54d72169.js → chunk-runtime-rpc.25cc9413.js} +2 -2
- package/dist/{chunk-runtime-setup.a06d5c72.js → chunk-runtime-setup.56d71d30.js} +51 -52
- package/dist/{chunk-snapshot-manager.70695b70.js → chunk-snapshot-manager.1a2dbf96.js} +468 -302
- package/dist/{chunk-utils-env.3fdc1793.js → chunk-utils-env.f4a39d2c.js} +8 -70
- package/dist/{chunk-utils-import.e7f64637.js → chunk-utils-import.16d9fb0d.js} +22 -8
- package/dist/chunk-utils-source-map.4e9b891d.js +408 -0
- package/dist/{chunk-utils-timers.715da787.js → chunk-utils-timers.52534f96.js} +2977 -3458
- package/dist/cli-wrapper.js +15 -15
- package/dist/cli.js +15 -627
- package/dist/config.cjs +2 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +2 -1
- package/dist/entry.js +14 -14
- package/dist/environments.d.ts +1 -1
- package/dist/{index-761e769b.d.ts → index-1cfc7f58.d.ts} +4 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +12 -12
- package/dist/loader.js +9 -10
- package/dist/node.d.ts +2 -2
- package/dist/node.js +14 -12
- package/dist/spy.js +2 -102
- package/dist/suite.js +10 -10
- package/dist/{types-bae746aa.d.ts → types-5617096e.d.ts} +97 -77
- package/dist/{vendor-index.b2fdde54.js → vendor-index.451e37bc.js} +1 -1
- package/dist/vendor-index.723a074f.js +102 -0
- package/dist/vendor-index.b0346fe4.js +395 -0
- package/dist/{vendor-index.7a2cebfe.js → vendor-index.e6c27006.js} +12 -12
- package/dist/worker.js +24 -19
- package/package.json +13 -8
- package/dist/chunk-integrations-globals.ee28730b.js +0 -27
- package/dist/chunk-utils-source-map.5278ee22.js +0 -86
- package/dist/vendor-index.2e96c50b.js +0 -215
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import util$1 from 'util';
|
|
2
2
|
import * as chai$2 from 'chai';
|
|
3
|
-
import {
|
|
4
|
-
import { i as isObject, b as getCallLastIndex, s as slash, g as getWorkerState, c as getNames, d as
|
|
3
|
+
import { AssertionError, util, expect } from 'chai';
|
|
4
|
+
import { i as isObject$1, b as getCallLastIndex, s as slash, g as getWorkerState, c as getNames, d as getCurrentEnvironment, e as getFullName, o as objectAttr, n as noop, f as isRunningInTest, h as isRunningInBenchmark } from './chunk-mock-date.149ed990.js';
|
|
5
5
|
import { c as commonjsGlobal } from './vendor-_commonjsHelpers.addc3445.js';
|
|
6
|
-
import
|
|
6
|
+
import c from 'picocolors';
|
|
7
|
+
import { c as createPatch, a as stringify, p as plugins_1, f as format_1, s as safeSetTimeout, b as safeClearTimeout } from './chunk-utils-timers.52534f96.js';
|
|
8
|
+
import { i as isMockFunction } from './vendor-index.723a074f.js';
|
|
9
|
+
import { c as cliTruncate, a as positionToOffset, o as offsetToLineNumber, l as lineSplitRE, b as parseStacktrace } from './chunk-utils-source-map.4e9b891d.js';
|
|
10
|
+
import { r as rpc } from './chunk-runtime-rpc.25cc9413.js';
|
|
7
11
|
import fs from 'node:fs';
|
|
8
|
-
import { j as join, d as dirname
|
|
9
|
-
import { p as plugins_1, f as format_1, u as unifiedDiff, a as stringify, m as matcherUtils, s as safeSetTimeout, b as safeClearTimeout } from './chunk-utils-timers.715da787.js';
|
|
10
|
-
import { a as positionToOffset, o as offsetToLineNumber, l as lineSplitRE, p as parseStacktrace } from './chunk-utils-source-map.5278ee22.js';
|
|
12
|
+
import { j as join, d as dirname } from './chunk-utils-env.f4a39d2c.js';
|
|
11
13
|
import { promises } from 'fs';
|
|
12
|
-
import { isMockFunction } from './spy.js';
|
|
13
14
|
|
|
14
15
|
function createChainable(keys, fn) {
|
|
15
16
|
function create(context) {
|
|
@@ -121,6 +122,203 @@ var chaiSubset = {exports: {}};
|
|
|
121
122
|
|
|
122
123
|
var Subset = chaiSubset.exports;
|
|
123
124
|
|
|
125
|
+
function formatLine(line, outputTruncateLength) {
|
|
126
|
+
var _a;
|
|
127
|
+
return cliTruncate(line, (outputTruncateLength ?? (((_a = process.stdout) == null ? void 0 : _a.columns) || 80)) - 4);
|
|
128
|
+
}
|
|
129
|
+
function unifiedDiff(actual, expected, options = {}) {
|
|
130
|
+
if (actual === expected)
|
|
131
|
+
return "";
|
|
132
|
+
const { outputTruncateLength, outputDiffLines, outputDiffMaxLines, noColor, showLegend = true } = options;
|
|
133
|
+
const indent = " ";
|
|
134
|
+
const diffLimit = outputDiffLines || 15;
|
|
135
|
+
const diffMaxLines = outputDiffMaxLines || 50;
|
|
136
|
+
const counts = {
|
|
137
|
+
"+": 0,
|
|
138
|
+
"-": 0
|
|
139
|
+
};
|
|
140
|
+
let previousState = null;
|
|
141
|
+
let previousCount = 0;
|
|
142
|
+
const str = (str2) => str2;
|
|
143
|
+
const dim = noColor ? str : c.dim;
|
|
144
|
+
const green = noColor ? str : c.green;
|
|
145
|
+
const red = noColor ? str : c.red;
|
|
146
|
+
function preprocess(line) {
|
|
147
|
+
if (!line || line.match(/\\ No newline/))
|
|
148
|
+
return;
|
|
149
|
+
const char = line[0];
|
|
150
|
+
if ("-+".includes(char)) {
|
|
151
|
+
if (previousState !== char) {
|
|
152
|
+
previousState = char;
|
|
153
|
+
previousCount = 0;
|
|
154
|
+
}
|
|
155
|
+
previousCount++;
|
|
156
|
+
counts[char]++;
|
|
157
|
+
if (previousCount === diffLimit)
|
|
158
|
+
return dim(`${char} ...`);
|
|
159
|
+
else if (previousCount > diffLimit)
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
return line;
|
|
163
|
+
}
|
|
164
|
+
const msg = createPatch("string", expected, actual);
|
|
165
|
+
let lines = msg.split("\n").slice(5).map(preprocess).filter(Boolean);
|
|
166
|
+
let moreLines = 0;
|
|
167
|
+
const isCompact = counts["+"] === 1 && counts["-"] === 1 && lines.length === 2;
|
|
168
|
+
if (lines.length > diffMaxLines) {
|
|
169
|
+
const firstDiff = lines.findIndex((line) => line[0] === "-" || line[0] === "+");
|
|
170
|
+
const displayLines = lines.slice(firstDiff - 2, diffMaxLines);
|
|
171
|
+
const lastDisplayedIndex = firstDiff - 2 + diffMaxLines;
|
|
172
|
+
if (lastDisplayedIndex < lines.length)
|
|
173
|
+
moreLines = lines.length - lastDisplayedIndex;
|
|
174
|
+
lines = displayLines;
|
|
175
|
+
}
|
|
176
|
+
let formatted = lines.map((line) => {
|
|
177
|
+
line = line.replace(/\\"/g, '"');
|
|
178
|
+
if (line[0] === "-") {
|
|
179
|
+
line = formatLine(line.slice(1), outputTruncateLength);
|
|
180
|
+
if (isCompact)
|
|
181
|
+
return green(line);
|
|
182
|
+
return green(`- ${formatLine(line, outputTruncateLength)}`);
|
|
183
|
+
}
|
|
184
|
+
if (line[0] === "+") {
|
|
185
|
+
line = formatLine(line.slice(1), outputTruncateLength);
|
|
186
|
+
if (isCompact)
|
|
187
|
+
return red(line);
|
|
188
|
+
return red(`+ ${formatLine(line, outputTruncateLength)}`);
|
|
189
|
+
}
|
|
190
|
+
if (line.match(/@@/))
|
|
191
|
+
return "--";
|
|
192
|
+
return ` ${line}`;
|
|
193
|
+
});
|
|
194
|
+
if (moreLines)
|
|
195
|
+
formatted.push(dim(`... ${moreLines} more lines`));
|
|
196
|
+
if (showLegend) {
|
|
197
|
+
if (isCompact) {
|
|
198
|
+
formatted = [
|
|
199
|
+
`${green("- Expected")} ${formatted[0]}`,
|
|
200
|
+
`${red("+ Received")} ${formatted[1]}`
|
|
201
|
+
];
|
|
202
|
+
} else {
|
|
203
|
+
if (formatted[0].includes('"'))
|
|
204
|
+
formatted[0] = formatted[0].replace('"', "");
|
|
205
|
+
const last = formatted.length - 1;
|
|
206
|
+
if (formatted[last].endsWith('"'))
|
|
207
|
+
formatted[last] = formatted[last].slice(0, formatted[last].length - 1);
|
|
208
|
+
formatted.unshift(
|
|
209
|
+
green(`- Expected - ${counts["-"]}`),
|
|
210
|
+
red(`+ Received + ${counts["+"]}`),
|
|
211
|
+
""
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return formatted.map((i) => i ? indent + i : i).join("\n");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function assertTypes(value, name, types) {
|
|
219
|
+
const receivedType = typeof value;
|
|
220
|
+
const pass = types.includes(receivedType);
|
|
221
|
+
if (!pass)
|
|
222
|
+
throw new TypeError(`${name} value must be ${types.join(" or ")}, received "${receivedType}"`);
|
|
223
|
+
}
|
|
224
|
+
function isObject(item) {
|
|
225
|
+
return item != null && typeof item === "object" && !Array.isArray(item);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const MATCHERS_OBJECT = Symbol.for("matchers-object");
|
|
229
|
+
const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
|
|
230
|
+
const GLOBAL_EXPECT = Symbol.for("expect-global");
|
|
231
|
+
if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
|
|
232
|
+
const globalState = /* @__PURE__ */ new WeakMap();
|
|
233
|
+
const matchers = /* @__PURE__ */ Object.create(null);
|
|
234
|
+
Object.defineProperty(globalThis, MATCHERS_OBJECT, {
|
|
235
|
+
get: () => globalState
|
|
236
|
+
});
|
|
237
|
+
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
|
|
238
|
+
configurable: true,
|
|
239
|
+
get: () => ({
|
|
240
|
+
state: globalState.get(globalThis[GLOBAL_EXPECT]),
|
|
241
|
+
matchers
|
|
242
|
+
})
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
const getState = (expect) => globalThis[MATCHERS_OBJECT].get(expect);
|
|
246
|
+
const setState = (state, expect) => {
|
|
247
|
+
const map = globalThis[MATCHERS_OBJECT];
|
|
248
|
+
const current = map.get(expect) || {};
|
|
249
|
+
Object.assign(current, state);
|
|
250
|
+
map.set(expect, current);
|
|
251
|
+
};
|
|
252
|
+
const EXPECTED_COLOR = c.green;
|
|
253
|
+
const RECEIVED_COLOR = c.red;
|
|
254
|
+
const INVERTED_COLOR = c.inverse;
|
|
255
|
+
const BOLD_WEIGHT = c.bold;
|
|
256
|
+
const DIM_COLOR = c.dim;
|
|
257
|
+
function matcherHint(matcherName, received = "received", expected = "expected", options = {}) {
|
|
258
|
+
const {
|
|
259
|
+
comment = "",
|
|
260
|
+
isDirectExpectCall = false,
|
|
261
|
+
isNot = false,
|
|
262
|
+
promise = "",
|
|
263
|
+
secondArgument = "",
|
|
264
|
+
expectedColor = EXPECTED_COLOR,
|
|
265
|
+
receivedColor = RECEIVED_COLOR,
|
|
266
|
+
secondArgumentColor = EXPECTED_COLOR
|
|
267
|
+
} = options;
|
|
268
|
+
let hint = "";
|
|
269
|
+
let dimString = "expect";
|
|
270
|
+
if (!isDirectExpectCall && received !== "") {
|
|
271
|
+
hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
|
|
272
|
+
dimString = ")";
|
|
273
|
+
}
|
|
274
|
+
if (promise !== "") {
|
|
275
|
+
hint += DIM_COLOR(`${dimString}.`) + promise;
|
|
276
|
+
dimString = "";
|
|
277
|
+
}
|
|
278
|
+
if (isNot) {
|
|
279
|
+
hint += `${DIM_COLOR(`${dimString}.`)}not`;
|
|
280
|
+
dimString = "";
|
|
281
|
+
}
|
|
282
|
+
if (matcherName.includes(".")) {
|
|
283
|
+
dimString += matcherName;
|
|
284
|
+
} else {
|
|
285
|
+
hint += DIM_COLOR(`${dimString}.`) + matcherName;
|
|
286
|
+
dimString = "";
|
|
287
|
+
}
|
|
288
|
+
if (expected === "") {
|
|
289
|
+
dimString += "()";
|
|
290
|
+
} else {
|
|
291
|
+
hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
|
|
292
|
+
if (secondArgument)
|
|
293
|
+
hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
|
|
294
|
+
dimString = ")";
|
|
295
|
+
}
|
|
296
|
+
if (comment !== "")
|
|
297
|
+
dimString += ` // ${comment}`;
|
|
298
|
+
if (dimString !== "")
|
|
299
|
+
hint += DIM_COLOR(dimString);
|
|
300
|
+
return hint;
|
|
301
|
+
}
|
|
302
|
+
const SPACE_SYMBOL = "\xB7";
|
|
303
|
+
const replaceTrailingSpaces = (text) => text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
|
|
304
|
+
const printReceived = (object) => RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
|
|
305
|
+
const printExpected = (value) => EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
|
|
306
|
+
function diff(a, b, options) {
|
|
307
|
+
return unifiedDiff(stringify(b), stringify(a));
|
|
308
|
+
}
|
|
309
|
+
var matcherUtils = /* @__PURE__ */ Object.freeze({
|
|
310
|
+
__proto__: null,
|
|
311
|
+
stringify,
|
|
312
|
+
EXPECTED_COLOR,
|
|
313
|
+
RECEIVED_COLOR,
|
|
314
|
+
INVERTED_COLOR,
|
|
315
|
+
BOLD_WEIGHT,
|
|
316
|
+
DIM_COLOR,
|
|
317
|
+
matcherHint,
|
|
318
|
+
printReceived,
|
|
319
|
+
printExpected,
|
|
320
|
+
diff
|
|
321
|
+
});
|
|
124
322
|
function equals(a, b, customTesters, strictCheck) {
|
|
125
323
|
customTesters = customTesters || [];
|
|
126
324
|
return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey);
|
|
@@ -378,752 +576,218 @@ Received: serializes to the same string
|
|
|
378
576
|
`;
|
|
379
577
|
return toBeMessage;
|
|
380
578
|
};
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
* @date 2015-10-26
|
|
387
|
-
* @stability 3 - Stable
|
|
388
|
-
* @author Lauri Rooden (https://github.com/litejs/natural-compare-lite)
|
|
389
|
-
* @license MIT License
|
|
390
|
-
*/
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
var naturalCompare = function(a, b) {
|
|
394
|
-
var i, codeA
|
|
395
|
-
, codeB = 1
|
|
396
|
-
, posA = 0
|
|
397
|
-
, posB = 0
|
|
398
|
-
, alphabet = String.alphabet;
|
|
399
|
-
|
|
400
|
-
function getCode(str, pos, code) {
|
|
401
|
-
if (code) {
|
|
402
|
-
for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i;
|
|
403
|
-
return +str.slice(pos - 1, i)
|
|
404
|
-
}
|
|
405
|
-
code = alphabet && alphabet.indexOf(str.charAt(pos));
|
|
406
|
-
return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code
|
|
407
|
-
: code < 46 ? 65 // -
|
|
408
|
-
: code < 48 ? code - 1
|
|
409
|
-
: code < 58 ? code + 18 // 0-9
|
|
410
|
-
: code < 65 ? code - 11
|
|
411
|
-
: code < 91 ? code + 11 // A-Z
|
|
412
|
-
: code < 97 ? code - 37
|
|
413
|
-
: code < 123 ? code + 5 // a-z
|
|
414
|
-
: code - 63
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if ((a+="") != (b+="")) for (;codeB;) {
|
|
419
|
-
codeA = getCode(a, posA++);
|
|
420
|
-
codeB = getCode(b, posB++);
|
|
421
|
-
|
|
422
|
-
if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) {
|
|
423
|
-
codeA = getCode(a, posA, posA);
|
|
424
|
-
codeB = getCode(b, posB, posA = i);
|
|
425
|
-
posB = i;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
if (codeA != codeB) return (codeA < codeB) ? -1 : 1
|
|
429
|
-
}
|
|
430
|
-
return 0
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
try {
|
|
434
|
-
naturalCompare$1.exports = naturalCompare;
|
|
435
|
-
} catch (e) {
|
|
436
|
-
String.naturalCompare = naturalCompare;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
const serialize$1 = (val, config, indentation, depth, refs, printer) => {
|
|
440
|
-
const name = val.getMockName();
|
|
441
|
-
const nameString = name === "vi.fn()" ? "" : ` ${name}`;
|
|
442
|
-
let callsString = "";
|
|
443
|
-
if (val.mock.calls.length !== 0) {
|
|
444
|
-
const indentationNext = indentation + config.indent;
|
|
445
|
-
callsString = ` {${config.spacingOuter}${indentationNext}"calls": ${printer(val.mock.calls, config, indentationNext, depth, refs)}${config.min ? ", " : ","}${config.spacingOuter}${indentationNext}"results": ${printer(val.mock.results, config, indentationNext, depth, refs)}${config.min ? "" : ","}${config.spacingOuter}${indentation}}`;
|
|
579
|
+
class AsymmetricMatcher$1 {
|
|
580
|
+
constructor(sample, inverse = false) {
|
|
581
|
+
this.sample = sample;
|
|
582
|
+
this.inverse = inverse;
|
|
583
|
+
this.$$typeof = Symbol.for("jest.asymmetricMatcher");
|
|
446
584
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
DOMElement,
|
|
455
|
-
Immutable,
|
|
456
|
-
ReactElement,
|
|
457
|
-
ReactTestComponent,
|
|
458
|
-
AsymmetricMatcher: AsymmetricMatcher$1
|
|
459
|
-
} = plugins_1;
|
|
460
|
-
let PLUGINS = [
|
|
461
|
-
ReactTestComponent,
|
|
462
|
-
ReactElement,
|
|
463
|
-
DOMElement,
|
|
464
|
-
DOMCollection,
|
|
465
|
-
Immutable,
|
|
466
|
-
AsymmetricMatcher$1,
|
|
467
|
-
plugin
|
|
468
|
-
];
|
|
469
|
-
const addSerializer = (plugin) => {
|
|
470
|
-
PLUGINS = [plugin].concat(PLUGINS);
|
|
471
|
-
};
|
|
472
|
-
const getSerializers = () => PLUGINS;
|
|
473
|
-
|
|
474
|
-
const SNAPSHOT_VERSION = "1";
|
|
475
|
-
const writeSnapshotVersion = () => `// Vitest Snapshot v${SNAPSHOT_VERSION}`;
|
|
476
|
-
const testNameToKey = (testName, count) => `${testName} ${count}`;
|
|
477
|
-
const keyToTestName = (key) => {
|
|
478
|
-
if (!/ \d+$/.test(key))
|
|
479
|
-
throw new Error("Snapshot keys must end with a number.");
|
|
480
|
-
return key.replace(/ \d+$/, "");
|
|
481
|
-
};
|
|
482
|
-
const getSnapshotData = (snapshotPath, update) => {
|
|
483
|
-
const data = /* @__PURE__ */ Object.create(null);
|
|
484
|
-
let snapshotContents = "";
|
|
485
|
-
let dirty = false;
|
|
486
|
-
if (fs.existsSync(snapshotPath)) {
|
|
487
|
-
try {
|
|
488
|
-
snapshotContents = fs.readFileSync(snapshotPath, "utf8");
|
|
489
|
-
const populate = new Function("exports", snapshotContents);
|
|
490
|
-
populate(data);
|
|
491
|
-
} catch {
|
|
492
|
-
}
|
|
585
|
+
getMatcherContext(expect) {
|
|
586
|
+
return {
|
|
587
|
+
...getState(expect || globalThis[GLOBAL_EXPECT]),
|
|
588
|
+
equals,
|
|
589
|
+
isNot: this.inverse,
|
|
590
|
+
utils: matcherUtils
|
|
591
|
+
};
|
|
493
592
|
}
|
|
494
|
-
const isInvalid = snapshotContents;
|
|
495
|
-
if ((update === "all" || update === "new") && isInvalid)
|
|
496
|
-
dirty = true;
|
|
497
|
-
return { data, dirty };
|
|
498
|
-
};
|
|
499
|
-
const addExtraLineBreaks = (string) => string.includes("\n") ? `
|
|
500
|
-
${string}
|
|
501
|
-
` : string;
|
|
502
|
-
const removeExtraLineBreaks = (string) => string.length > 2 && string.startsWith("\n") && string.endsWith("\n") ? string.slice(1, -1) : string;
|
|
503
|
-
const escapeRegex = true;
|
|
504
|
-
const printFunctionName = false;
|
|
505
|
-
function serialize(val, indent = 2, formatOverrides = {}) {
|
|
506
|
-
return normalizeNewlines(
|
|
507
|
-
format_1(val, {
|
|
508
|
-
escapeRegex,
|
|
509
|
-
indent,
|
|
510
|
-
plugins: getSerializers(),
|
|
511
|
-
printFunctionName,
|
|
512
|
-
...formatOverrides
|
|
513
|
-
})
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
function escapeBacktickString(str) {
|
|
517
|
-
return str.replace(/`|\\|\${/g, "\\$&");
|
|
518
593
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
594
|
+
class StringContaining extends AsymmetricMatcher$1 {
|
|
595
|
+
constructor(sample, inverse = false) {
|
|
596
|
+
if (!isA("String", sample))
|
|
597
|
+
throw new Error("Expected is not a string");
|
|
598
|
+
super(sample, inverse);
|
|
599
|
+
}
|
|
600
|
+
asymmetricMatch(other) {
|
|
601
|
+
const result = isA("String", other) && other.includes(this.sample);
|
|
602
|
+
return this.inverse ? !result : result;
|
|
603
|
+
}
|
|
604
|
+
toString() {
|
|
605
|
+
return `String${this.inverse ? "Not" : ""}Containing`;
|
|
606
|
+
}
|
|
607
|
+
getExpectedType() {
|
|
608
|
+
return "string";
|
|
526
609
|
}
|
|
527
610
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
async function saveSnapshotFile(snapshotData, snapshotPath) {
|
|
532
|
-
var _a, _b;
|
|
533
|
-
const snapshots = Object.keys(snapshotData).sort(naturalCompare$1.exports).map(
|
|
534
|
-
(key) => `exports[${printBacktickString(key)}] = ${printBacktickString(normalizeNewlines(snapshotData[key]))};`
|
|
535
|
-
);
|
|
536
|
-
const content = `${writeSnapshotVersion()}
|
|
537
|
-
|
|
538
|
-
${snapshots.join("\n\n")}
|
|
539
|
-
`;
|
|
540
|
-
const skipWriting = fs.existsSync(snapshotPath) && await ((_a = fs) == null ? void 0 : _a.promises.readFile(snapshotPath, "utf8")) === content;
|
|
541
|
-
if (skipWriting)
|
|
542
|
-
return;
|
|
543
|
-
ensureDirectoryExists(snapshotPath);
|
|
544
|
-
await ((_b = fs) == null ? void 0 : _b.promises.writeFile(
|
|
545
|
-
snapshotPath,
|
|
546
|
-
content,
|
|
547
|
-
"utf-8"
|
|
548
|
-
));
|
|
549
|
-
}
|
|
550
|
-
function prepareExpected(expected) {
|
|
551
|
-
function findStartIndent() {
|
|
552
|
-
var _a, _b;
|
|
553
|
-
const matchObject = /^( +)}\s+$/m.exec(expected || "");
|
|
554
|
-
const objectIndent = (_a = matchObject == null ? void 0 : matchObject[1]) == null ? void 0 : _a.length;
|
|
555
|
-
if (objectIndent)
|
|
556
|
-
return objectIndent;
|
|
557
|
-
const matchText = /^\n( +)"/.exec(expected || "");
|
|
558
|
-
return ((_b = matchText == null ? void 0 : matchText[1]) == null ? void 0 : _b.length) || 0;
|
|
611
|
+
class Anything extends AsymmetricMatcher$1 {
|
|
612
|
+
asymmetricMatch(other) {
|
|
613
|
+
return other != null;
|
|
559
614
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
615
|
+
toString() {
|
|
616
|
+
return "Anything";
|
|
617
|
+
}
|
|
618
|
+
toAsymmetricMatcher() {
|
|
619
|
+
return "Anything";
|
|
564
620
|
}
|
|
565
|
-
return expectedTrimmed;
|
|
566
621
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
const targetElement = mergedOutput[index];
|
|
571
|
-
if (Array.isArray(target[index])) {
|
|
572
|
-
mergedOutput[index] = deepMergeArray(target[index], sourceElement);
|
|
573
|
-
} else if (isObject(targetElement)) {
|
|
574
|
-
mergedOutput[index] = deepMergeSnapshot(target[index], sourceElement);
|
|
575
|
-
} else {
|
|
576
|
-
mergedOutput[index] = sourceElement;
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
return mergedOutput;
|
|
580
|
-
}
|
|
581
|
-
function deepMergeSnapshot(target, source) {
|
|
582
|
-
if (isObject(target) && isObject(source)) {
|
|
583
|
-
const mergedOutput = { ...target };
|
|
584
|
-
Object.keys(source).forEach((key) => {
|
|
585
|
-
if (isObject(source[key]) && !source[key].$$typeof) {
|
|
586
|
-
if (!(key in target))
|
|
587
|
-
Object.assign(mergedOutput, { [key]: source[key] });
|
|
588
|
-
else
|
|
589
|
-
mergedOutput[key] = deepMergeSnapshot(target[key], source[key]);
|
|
590
|
-
} else if (Array.isArray(source[key])) {
|
|
591
|
-
mergedOutput[key] = deepMergeArray(target[key], source[key]);
|
|
592
|
-
} else {
|
|
593
|
-
Object.assign(mergedOutput, { [key]: source[key] });
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
return mergedOutput;
|
|
597
|
-
} else if (Array.isArray(target) && Array.isArray(source)) {
|
|
598
|
-
return deepMergeArray(target, source);
|
|
599
|
-
}
|
|
600
|
-
return target;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
async function saveInlineSnapshots(snapshots) {
|
|
604
|
-
const MagicString = (await import('./chunk-magic-string.3a794426.js')).default;
|
|
605
|
-
const files = new Set(snapshots.map((i) => i.file));
|
|
606
|
-
await Promise.all(Array.from(files).map(async (file) => {
|
|
607
|
-
const snaps = snapshots.filter((i) => i.file === file);
|
|
608
|
-
const code = await promises.readFile(file, "utf8");
|
|
609
|
-
const s = new MagicString(code);
|
|
610
|
-
for (const snap of snaps) {
|
|
611
|
-
const index = positionToOffset(code, snap.line, snap.column);
|
|
612
|
-
replaceInlineSnap(code, s, index, snap.snapshot);
|
|
613
|
-
}
|
|
614
|
-
const transformed = s.toString();
|
|
615
|
-
if (transformed !== code)
|
|
616
|
-
await promises.writeFile(file, transformed, "utf-8");
|
|
617
|
-
}));
|
|
618
|
-
}
|
|
619
|
-
const startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*({)/m;
|
|
620
|
-
function replaceObjectSnap(code, s, index, newSnap) {
|
|
621
|
-
code = code.slice(index);
|
|
622
|
-
const startMatch = startObjectRegex.exec(code);
|
|
623
|
-
if (!startMatch)
|
|
624
|
-
return false;
|
|
625
|
-
code = code.slice(startMatch.index);
|
|
626
|
-
const charIndex = getCallLastIndex(code);
|
|
627
|
-
if (charIndex === null)
|
|
628
|
-
return false;
|
|
629
|
-
s.appendLeft(index + startMatch.index + charIndex, `, ${prepareSnapString(newSnap, code, index)}`);
|
|
630
|
-
return true;
|
|
631
|
-
}
|
|
632
|
-
function prepareSnapString(snap, source, index) {
|
|
633
|
-
const lineNumber = offsetToLineNumber(source, index);
|
|
634
|
-
const line = source.split(lineSplitRE)[lineNumber - 1];
|
|
635
|
-
const indent = line.match(/^\s*/)[0] || "";
|
|
636
|
-
const indentNext = indent.includes(" ") ? `${indent} ` : `${indent} `;
|
|
637
|
-
const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
|
|
638
|
-
const isOneline = lines.length <= 1;
|
|
639
|
-
const quote = isOneline ? "'" : "`";
|
|
640
|
-
if (isOneline)
|
|
641
|
-
return `'${lines.join("\n").replace(/'/g, "\\'")}'`;
|
|
642
|
-
else
|
|
643
|
-
return `${quote}
|
|
644
|
-
${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\${/g, "\\${")}
|
|
645
|
-
${indent}${quote}`;
|
|
646
|
-
}
|
|
647
|
-
const startRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*[\w_$]*(['"`\)])/m;
|
|
648
|
-
function replaceInlineSnap(code, s, index, newSnap) {
|
|
649
|
-
const startMatch = startRegex.exec(code.slice(index));
|
|
650
|
-
if (!startMatch)
|
|
651
|
-
return replaceObjectSnap(code, s, index, newSnap);
|
|
652
|
-
const quote = startMatch[1];
|
|
653
|
-
const startIndex = index + startMatch.index + startMatch[0].length;
|
|
654
|
-
const snapString = prepareSnapString(newSnap, code, index);
|
|
655
|
-
if (quote === ")") {
|
|
656
|
-
s.appendRight(startIndex - 1, snapString);
|
|
657
|
-
return true;
|
|
658
|
-
}
|
|
659
|
-
const quoteEndRE = new RegExp(`(?:^|[^\\\\])${quote}`);
|
|
660
|
-
const endMatch = quoteEndRE.exec(code.slice(startIndex));
|
|
661
|
-
if (!endMatch)
|
|
662
|
-
return false;
|
|
663
|
-
const endIndex = startIndex + endMatch.index + endMatch[0].length;
|
|
664
|
-
s.overwrite(startIndex - 1, endIndex, snapString);
|
|
665
|
-
return true;
|
|
666
|
-
}
|
|
667
|
-
const INDENTATION_REGEX = /^([^\S\n]*)\S/m;
|
|
668
|
-
function stripSnapshotIndentation(inlineSnapshot) {
|
|
669
|
-
const match = inlineSnapshot.match(INDENTATION_REGEX);
|
|
670
|
-
if (!match || !match[1]) {
|
|
671
|
-
return inlineSnapshot;
|
|
622
|
+
class ObjectContaining extends AsymmetricMatcher$1 {
|
|
623
|
+
constructor(sample, inverse = false) {
|
|
624
|
+
super(sample, inverse);
|
|
672
625
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
626
|
+
getPrototype(obj) {
|
|
627
|
+
if (Object.getPrototypeOf)
|
|
628
|
+
return Object.getPrototypeOf(obj);
|
|
629
|
+
if (obj.constructor.prototype === obj)
|
|
630
|
+
return null;
|
|
631
|
+
return obj.constructor.prototype;
|
|
677
632
|
}
|
|
678
|
-
|
|
679
|
-
|
|
633
|
+
hasProperty(obj, property) {
|
|
634
|
+
if (!obj)
|
|
635
|
+
return false;
|
|
636
|
+
if (Object.prototype.hasOwnProperty.call(obj, property))
|
|
637
|
+
return true;
|
|
638
|
+
return this.hasProperty(this.getPrototype(obj), property);
|
|
680
639
|
}
|
|
681
|
-
|
|
682
|
-
if (
|
|
683
|
-
|
|
684
|
-
|
|
640
|
+
asymmetricMatch(other) {
|
|
641
|
+
if (typeof this.sample !== "object") {
|
|
642
|
+
throw new TypeError(
|
|
643
|
+
`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
let result = true;
|
|
647
|
+
for (const property in this.sample) {
|
|
648
|
+
if (!this.hasProperty(other, property) || !equals(this.sample[property], other[property])) {
|
|
649
|
+
result = false;
|
|
650
|
+
break;
|
|
685
651
|
}
|
|
686
|
-
lines[i] = lines[i].substring(indentation.length);
|
|
687
652
|
}
|
|
653
|
+
return this.inverse ? !result : result;
|
|
688
654
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
return inlineSnapshot;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
class SnapshotState {
|
|
695
|
-
constructor(testFilePath, snapshotPath, options) {
|
|
696
|
-
this.testFilePath = testFilePath;
|
|
697
|
-
this.snapshotPath = snapshotPath;
|
|
698
|
-
const { data, dirty } = getSnapshotData(
|
|
699
|
-
this.snapshotPath,
|
|
700
|
-
options.updateSnapshot
|
|
701
|
-
);
|
|
702
|
-
this._initialData = data;
|
|
703
|
-
this._snapshotData = data;
|
|
704
|
-
this._dirty = dirty;
|
|
705
|
-
this._inlineSnapshots = [];
|
|
706
|
-
this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
|
|
707
|
-
this._counters = /* @__PURE__ */ new Map();
|
|
708
|
-
this.expand = options.expand || false;
|
|
709
|
-
this.added = 0;
|
|
710
|
-
this.matched = 0;
|
|
711
|
-
this.unmatched = 0;
|
|
712
|
-
this._updateSnapshot = options.updateSnapshot;
|
|
713
|
-
this.updated = 0;
|
|
714
|
-
this._snapshotFormat = {
|
|
715
|
-
printBasicPrototype: false,
|
|
716
|
-
...options.snapshotFormat
|
|
717
|
-
};
|
|
655
|
+
toString() {
|
|
656
|
+
return `Object${this.inverse ? "Not" : ""}Containing`;
|
|
718
657
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
if (keyToTestName(uncheckedKey) === testName)
|
|
722
|
-
this._uncheckedKeys.delete(uncheckedKey);
|
|
723
|
-
});
|
|
658
|
+
getExpectedType() {
|
|
659
|
+
return "object";
|
|
724
660
|
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
const stackIndex = stacks.findIndex((i) => i.method.includes("__VITEST_INLINE_SNAPSHOT__"));
|
|
730
|
-
return stackIndex !== -1 ? stacks[stackIndex + 2] : null;
|
|
661
|
+
}
|
|
662
|
+
class ArrayContaining extends AsymmetricMatcher$1 {
|
|
663
|
+
constructor(sample, inverse = false) {
|
|
664
|
+
super(sample, inverse);
|
|
731
665
|
}
|
|
732
|
-
|
|
733
|
-
this.
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
stacks.forEach((i) => i.file = slash(i.file));
|
|
738
|
-
const stack = this._inferInlineSnapshotStack(stacks);
|
|
739
|
-
if (!stack) {
|
|
740
|
-
throw new Error(
|
|
741
|
-
`Vitest: Couldn't infer stack frame for inline snapshot.
|
|
742
|
-
${JSON.stringify(stacks)}`
|
|
743
|
-
);
|
|
744
|
-
}
|
|
745
|
-
stack.column--;
|
|
746
|
-
this._inlineSnapshots.push({
|
|
747
|
-
snapshot: receivedSerialized,
|
|
748
|
-
...stack
|
|
749
|
-
});
|
|
750
|
-
} else {
|
|
751
|
-
this._snapshotData[key] = receivedSerialized;
|
|
666
|
+
asymmetricMatch(other) {
|
|
667
|
+
if (!Array.isArray(this.sample)) {
|
|
668
|
+
throw new TypeError(
|
|
669
|
+
`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`
|
|
670
|
+
);
|
|
752
671
|
}
|
|
672
|
+
const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every(
|
|
673
|
+
(item) => other.some((another) => equals(item, another))
|
|
674
|
+
);
|
|
675
|
+
return this.inverse ? !result : result;
|
|
753
676
|
}
|
|
754
|
-
|
|
755
|
-
this.
|
|
756
|
-
this._counters = /* @__PURE__ */ new Map();
|
|
757
|
-
this.added = 0;
|
|
758
|
-
this.matched = 0;
|
|
759
|
-
this.unmatched = 0;
|
|
760
|
-
this.updated = 0;
|
|
761
|
-
this._dirty = false;
|
|
677
|
+
toString() {
|
|
678
|
+
return `Array${this.inverse ? "Not" : ""}Containing`;
|
|
762
679
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
await saveSnapshotFile(this._snapshotData, this.snapshotPath);
|
|
774
|
-
if (hasInlineSnapshots)
|
|
775
|
-
await saveInlineSnapshots(this._inlineSnapshots);
|
|
776
|
-
status.saved = true;
|
|
777
|
-
} else if (!hasExternalSnapshots && fs.existsSync(this.snapshotPath)) {
|
|
778
|
-
if (this._updateSnapshot === "all")
|
|
779
|
-
fs.unlinkSync(this.snapshotPath);
|
|
780
|
-
status.deleted = true;
|
|
680
|
+
getExpectedType() {
|
|
681
|
+
return "array";
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
class Any extends AsymmetricMatcher$1 {
|
|
685
|
+
constructor(sample) {
|
|
686
|
+
if (typeof sample === "undefined") {
|
|
687
|
+
throw new TypeError(
|
|
688
|
+
"any() expects to be passed a constructor function. Please pass one or use anything() to match any object."
|
|
689
|
+
);
|
|
781
690
|
}
|
|
782
|
-
|
|
691
|
+
super(sample);
|
|
783
692
|
}
|
|
784
|
-
|
|
785
|
-
|
|
693
|
+
fnNameFor(func) {
|
|
694
|
+
if (func.name)
|
|
695
|
+
return func.name;
|
|
696
|
+
const functionToString2 = Function.prototype.toString;
|
|
697
|
+
const matches = functionToString2.call(func).match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/);
|
|
698
|
+
return matches ? matches[1] : "<anonymous>";
|
|
786
699
|
}
|
|
787
|
-
|
|
788
|
-
|
|
700
|
+
asymmetricMatch(other) {
|
|
701
|
+
if (this.sample === String)
|
|
702
|
+
return typeof other == "string" || other instanceof String;
|
|
703
|
+
if (this.sample === Number)
|
|
704
|
+
return typeof other == "number" || other instanceof Number;
|
|
705
|
+
if (this.sample === Function)
|
|
706
|
+
return typeof other == "function" || other instanceof Function;
|
|
707
|
+
if (this.sample === Boolean)
|
|
708
|
+
return typeof other == "boolean" || other instanceof Boolean;
|
|
709
|
+
if (this.sample === BigInt)
|
|
710
|
+
return typeof other == "bigint" || other instanceof BigInt;
|
|
711
|
+
if (this.sample === Symbol)
|
|
712
|
+
return typeof other == "symbol" || other instanceof Symbol;
|
|
713
|
+
if (this.sample === Object)
|
|
714
|
+
return typeof other == "object";
|
|
715
|
+
return other instanceof this.sample;
|
|
789
716
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
this._dirty = true;
|
|
793
|
-
this._uncheckedKeys.forEach((key) => delete this._snapshotData[key]);
|
|
794
|
-
this._uncheckedKeys.clear();
|
|
795
|
-
}
|
|
717
|
+
toString() {
|
|
718
|
+
return "Any";
|
|
796
719
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
if (!(isInline && this._snapshotData[key] !== void 0))
|
|
810
|
-
this._uncheckedKeys.delete(key);
|
|
811
|
-
const receivedSerialized = addExtraLineBreaks(serialize(received, void 0, this._snapshotFormat));
|
|
812
|
-
const expected = isInline ? inlineSnapshot : this._snapshotData[key];
|
|
813
|
-
const expectedTrimmed = prepareExpected(expected);
|
|
814
|
-
const pass = expectedTrimmed === prepareExpected(receivedSerialized);
|
|
815
|
-
const hasSnapshot = expected !== void 0;
|
|
816
|
-
const snapshotIsPersisted = isInline || fs.existsSync(this.snapshotPath);
|
|
817
|
-
if (pass && !isInline) {
|
|
818
|
-
this._snapshotData[key] = receivedSerialized;
|
|
819
|
-
}
|
|
820
|
-
if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
|
|
821
|
-
if (this._updateSnapshot === "all") {
|
|
822
|
-
if (!pass) {
|
|
823
|
-
if (hasSnapshot)
|
|
824
|
-
this.updated++;
|
|
825
|
-
else
|
|
826
|
-
this.added++;
|
|
827
|
-
this._addSnapshot(key, receivedSerialized, { error, isInline });
|
|
828
|
-
} else {
|
|
829
|
-
this.matched++;
|
|
830
|
-
}
|
|
831
|
-
} else {
|
|
832
|
-
this._addSnapshot(key, receivedSerialized, { error, isInline });
|
|
833
|
-
this.added++;
|
|
834
|
-
}
|
|
835
|
-
return {
|
|
836
|
-
actual: "",
|
|
837
|
-
count,
|
|
838
|
-
expected: "",
|
|
839
|
-
key,
|
|
840
|
-
pass: true
|
|
841
|
-
};
|
|
842
|
-
} else {
|
|
843
|
-
if (!pass) {
|
|
844
|
-
this.unmatched++;
|
|
845
|
-
return {
|
|
846
|
-
actual: removeExtraLineBreaks(receivedSerialized),
|
|
847
|
-
count,
|
|
848
|
-
expected: expectedTrimmed !== void 0 ? removeExtraLineBreaks(expectedTrimmed) : void 0,
|
|
849
|
-
key,
|
|
850
|
-
pass: false
|
|
851
|
-
};
|
|
852
|
-
} else {
|
|
853
|
-
this.matched++;
|
|
854
|
-
return {
|
|
855
|
-
actual: "",
|
|
856
|
-
count,
|
|
857
|
-
expected: "",
|
|
858
|
-
key,
|
|
859
|
-
pass: true
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
}
|
|
720
|
+
getExpectedType() {
|
|
721
|
+
if (this.sample === String)
|
|
722
|
+
return "string";
|
|
723
|
+
if (this.sample === Number)
|
|
724
|
+
return "number";
|
|
725
|
+
if (this.sample === Function)
|
|
726
|
+
return "function";
|
|
727
|
+
if (this.sample === Object)
|
|
728
|
+
return "object";
|
|
729
|
+
if (this.sample === Boolean)
|
|
730
|
+
return "boolean";
|
|
731
|
+
return this.fnNameFor(this.sample);
|
|
863
732
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
filepath: this.testFilePath,
|
|
867
|
-
added: 0,
|
|
868
|
-
fileDeleted: false,
|
|
869
|
-
matched: 0,
|
|
870
|
-
unchecked: 0,
|
|
871
|
-
uncheckedKeys: [],
|
|
872
|
-
unmatched: 0,
|
|
873
|
-
updated: 0
|
|
874
|
-
};
|
|
875
|
-
const uncheckedCount = this.getUncheckedCount();
|
|
876
|
-
const uncheckedKeys = this.getUncheckedKeys();
|
|
877
|
-
if (uncheckedCount)
|
|
878
|
-
this.removeUncheckedKeys();
|
|
879
|
-
const status = await this.save();
|
|
880
|
-
snapshot.fileDeleted = status.deleted;
|
|
881
|
-
snapshot.added = this.added;
|
|
882
|
-
snapshot.matched = this.matched;
|
|
883
|
-
snapshot.unmatched = this.unmatched;
|
|
884
|
-
snapshot.updated = this.updated;
|
|
885
|
-
snapshot.unchecked = !status.deleted ? uncheckedCount : 0;
|
|
886
|
-
snapshot.uncheckedKeys = Array.from(uncheckedKeys);
|
|
887
|
-
return snapshot;
|
|
733
|
+
toAsymmetricMatcher() {
|
|
734
|
+
return `Any<${this.fnNameFor(this.sample)}>`;
|
|
888
735
|
}
|
|
889
736
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
async setTest(test) {
|
|
896
|
-
var _a;
|
|
897
|
-
this.test = test;
|
|
898
|
-
if (((_a = this.snapshotState) == null ? void 0 : _a.testFilePath) !== this.test.file.filepath) {
|
|
899
|
-
this.saveCurrent();
|
|
900
|
-
const filePath = this.test.file.filepath;
|
|
901
|
-
if (!this.getSnapshotState(test)) {
|
|
902
|
-
this.snapshotStateMap.set(
|
|
903
|
-
filePath,
|
|
904
|
-
new SnapshotState(
|
|
905
|
-
filePath,
|
|
906
|
-
await rpc().resolveSnapshotPath(filePath),
|
|
907
|
-
getWorkerState().config.snapshotOptions
|
|
908
|
-
)
|
|
909
|
-
);
|
|
910
|
-
}
|
|
911
|
-
this.snapshotState = this.getSnapshotState(test);
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
getSnapshotState(test) {
|
|
915
|
-
return this.snapshotStateMap.get(test.file.filepath);
|
|
916
|
-
}
|
|
917
|
-
clearTest() {
|
|
918
|
-
this.test = void 0;
|
|
919
|
-
}
|
|
920
|
-
skipTestSnapshots(test) {
|
|
921
|
-
var _a;
|
|
922
|
-
(_a = this.snapshotState) == null ? void 0 : _a.markSnapshotsAsCheckedForTest(test.name);
|
|
737
|
+
class StringMatching extends AsymmetricMatcher$1 {
|
|
738
|
+
constructor(sample, inverse = false) {
|
|
739
|
+
if (!isA("String", sample) && !isA("RegExp", sample))
|
|
740
|
+
throw new Error("Expected is not a String or a RegExp");
|
|
741
|
+
super(new RegExp(sample), inverse);
|
|
923
742
|
}
|
|
924
|
-
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
message,
|
|
928
|
-
isInline = false,
|
|
929
|
-
properties,
|
|
930
|
-
inlineSnapshot,
|
|
931
|
-
error,
|
|
932
|
-
errorMessage
|
|
933
|
-
} = options;
|
|
934
|
-
let { received } = options;
|
|
935
|
-
if (!test)
|
|
936
|
-
throw new Error("Snapshot cannot be used outside of test");
|
|
937
|
-
if (typeof properties === "object") {
|
|
938
|
-
if (typeof received !== "object" || !received)
|
|
939
|
-
throw new Error("Received value must be an object when the matcher has properties");
|
|
940
|
-
try {
|
|
941
|
-
const pass2 = equals(received, properties, [iterableEquality, subsetEquality]);
|
|
942
|
-
if (!pass2)
|
|
943
|
-
expect(received).equals(properties);
|
|
944
|
-
else
|
|
945
|
-
received = deepMergeSnapshot(received, properties);
|
|
946
|
-
} catch (err) {
|
|
947
|
-
err.message = errorMessage || "Snapshot mismatched";
|
|
948
|
-
throw err;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
const testName = [
|
|
952
|
-
...getNames(test).slice(1),
|
|
953
|
-
...message ? [message] : []
|
|
954
|
-
].join(" > ");
|
|
955
|
-
const snapshotState = this.getSnapshotState(test);
|
|
956
|
-
const { actual, expected, key, pass } = snapshotState.match({
|
|
957
|
-
testName,
|
|
958
|
-
received,
|
|
959
|
-
isInline,
|
|
960
|
-
error,
|
|
961
|
-
inlineSnapshot
|
|
962
|
-
});
|
|
963
|
-
if (!pass) {
|
|
964
|
-
try {
|
|
965
|
-
expect(actual.trim()).equals(expected ? expected.trim() : "");
|
|
966
|
-
} catch (error2) {
|
|
967
|
-
error2.message = errorMessage || `Snapshot \`${key || "unknown"}\` mismatched`;
|
|
968
|
-
throw error2;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
743
|
+
asymmetricMatch(other) {
|
|
744
|
+
const result = isA("String", other) && this.sample.test(other);
|
|
745
|
+
return this.inverse ? !result : result;
|
|
971
746
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
return;
|
|
975
|
-
const result = await this.snapshotState.pack();
|
|
976
|
-
await rpc().snapshotSaved(result);
|
|
977
|
-
this.snapshotState = void 0;
|
|
747
|
+
toString() {
|
|
748
|
+
return `String${this.inverse ? "Not" : ""}Matching`;
|
|
978
749
|
}
|
|
979
|
-
|
|
980
|
-
|
|
750
|
+
getExpectedType() {
|
|
751
|
+
return "string";
|
|
981
752
|
}
|
|
982
753
|
}
|
|
983
|
-
|
|
984
|
-
let _client;
|
|
985
|
-
function getSnapshotClient() {
|
|
986
|
-
if (!_client)
|
|
987
|
-
_client = new SnapshotClient();
|
|
988
|
-
return _client;
|
|
989
|
-
}
|
|
990
|
-
const getErrorMessage = (err) => {
|
|
991
|
-
if (err instanceof Error)
|
|
992
|
-
return err.message;
|
|
993
|
-
return err;
|
|
994
|
-
};
|
|
995
|
-
const getErrorString = (expected, promise) => {
|
|
996
|
-
if (typeof expected !== "function") {
|
|
997
|
-
if (!promise)
|
|
998
|
-
throw new Error(`expected must be a function, received ${typeof expected}`);
|
|
999
|
-
return getErrorMessage(expected);
|
|
1000
|
-
}
|
|
1001
|
-
try {
|
|
1002
|
-
expected();
|
|
1003
|
-
} catch (e) {
|
|
1004
|
-
return getErrorMessage(e);
|
|
1005
|
-
}
|
|
1006
|
-
throw new Error("snapshot function didn't throw");
|
|
1007
|
-
};
|
|
1008
|
-
const SnapshotPlugin = (chai, utils) => {
|
|
1009
|
-
for (const key of ["matchSnapshot", "toMatchSnapshot"]) {
|
|
1010
|
-
utils.addMethod(
|
|
1011
|
-
chai.Assertion.prototype,
|
|
1012
|
-
key,
|
|
1013
|
-
function(properties, message) {
|
|
1014
|
-
const expected = utils.flag(this, "object");
|
|
1015
|
-
const test = utils.flag(this, "vitest-test");
|
|
1016
|
-
if (typeof properties === "string" && typeof message === "undefined") {
|
|
1017
|
-
message = properties;
|
|
1018
|
-
properties = void 0;
|
|
1019
|
-
}
|
|
1020
|
-
const errorMessage = utils.flag(this, "message");
|
|
1021
|
-
getSnapshotClient().assert({
|
|
1022
|
-
received: expected,
|
|
1023
|
-
test,
|
|
1024
|
-
message,
|
|
1025
|
-
isInline: false,
|
|
1026
|
-
properties,
|
|
1027
|
-
errorMessage
|
|
1028
|
-
});
|
|
1029
|
-
}
|
|
1030
|
-
);
|
|
1031
|
-
}
|
|
754
|
+
const JestAsymmetricMatchers = (chai, utils) => {
|
|
1032
755
|
utils.addMethod(
|
|
1033
|
-
chai.
|
|
1034
|
-
"
|
|
1035
|
-
|
|
1036
|
-
const expected = utils.flag(this, "object");
|
|
1037
|
-
const error = utils.flag(this, "error");
|
|
1038
|
-
const test = utils.flag(this, "vitest-test");
|
|
1039
|
-
if (typeof properties === "string") {
|
|
1040
|
-
message = inlineSnapshot;
|
|
1041
|
-
inlineSnapshot = properties;
|
|
1042
|
-
properties = void 0;
|
|
1043
|
-
}
|
|
1044
|
-
if (inlineSnapshot)
|
|
1045
|
-
inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
|
|
1046
|
-
const errorMessage = utils.flag(this, "message");
|
|
1047
|
-
getSnapshotClient().assert({
|
|
1048
|
-
received: expected,
|
|
1049
|
-
test,
|
|
1050
|
-
message,
|
|
1051
|
-
isInline: true,
|
|
1052
|
-
properties,
|
|
1053
|
-
inlineSnapshot,
|
|
1054
|
-
error,
|
|
1055
|
-
errorMessage
|
|
1056
|
-
});
|
|
1057
|
-
}
|
|
756
|
+
chai.expect,
|
|
757
|
+
"anything",
|
|
758
|
+
() => new Anything()
|
|
1058
759
|
);
|
|
1059
760
|
utils.addMethod(
|
|
1060
|
-
chai.
|
|
1061
|
-
"
|
|
1062
|
-
|
|
1063
|
-
const expected = utils.flag(this, "object");
|
|
1064
|
-
const test = utils.flag(this, "vitest-test");
|
|
1065
|
-
const promise = utils.flag(this, "promise");
|
|
1066
|
-
const errorMessage = utils.flag(this, "message");
|
|
1067
|
-
getSnapshotClient().assert({
|
|
1068
|
-
received: getErrorString(expected, promise),
|
|
1069
|
-
test,
|
|
1070
|
-
message,
|
|
1071
|
-
errorMessage
|
|
1072
|
-
});
|
|
1073
|
-
}
|
|
761
|
+
chai.expect,
|
|
762
|
+
"any",
|
|
763
|
+
(expected) => new Any(expected)
|
|
1074
764
|
);
|
|
1075
765
|
utils.addMethod(
|
|
1076
|
-
chai.
|
|
1077
|
-
"
|
|
1078
|
-
|
|
1079
|
-
const expected = utils.flag(this, "object");
|
|
1080
|
-
const error = utils.flag(this, "error");
|
|
1081
|
-
const test = utils.flag(this, "vitest-test");
|
|
1082
|
-
const promise = utils.flag(this, "promise");
|
|
1083
|
-
const errorMessage = utils.flag(this, "message");
|
|
1084
|
-
getSnapshotClient().assert({
|
|
1085
|
-
received: getErrorString(expected, promise),
|
|
1086
|
-
test,
|
|
1087
|
-
message,
|
|
1088
|
-
inlineSnapshot,
|
|
1089
|
-
isInline: true,
|
|
1090
|
-
error,
|
|
1091
|
-
errorMessage
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
766
|
+
chai.expect,
|
|
767
|
+
"stringContaining",
|
|
768
|
+
(expected) => new StringContaining(expected)
|
|
1094
769
|
);
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
state: globalState.get(globalThis[GLOBAL_EXPECT]),
|
|
1117
|
-
matchers
|
|
1118
|
-
})
|
|
1119
|
-
});
|
|
1120
|
-
}
|
|
1121
|
-
const getState = (expect) => globalThis[MATCHERS_OBJECT].get(expect);
|
|
1122
|
-
const setState = (state, expect) => {
|
|
1123
|
-
const map = globalThis[MATCHERS_OBJECT];
|
|
1124
|
-
const current = map.get(expect) || {};
|
|
1125
|
-
Object.assign(current, state);
|
|
1126
|
-
map.set(expect, current);
|
|
770
|
+
utils.addMethod(
|
|
771
|
+
chai.expect,
|
|
772
|
+
"objectContaining",
|
|
773
|
+
(expected) => new ObjectContaining(expected)
|
|
774
|
+
);
|
|
775
|
+
utils.addMethod(
|
|
776
|
+
chai.expect,
|
|
777
|
+
"arrayContaining",
|
|
778
|
+
(expected) => new ArrayContaining(expected)
|
|
779
|
+
);
|
|
780
|
+
utils.addMethod(
|
|
781
|
+
chai.expect,
|
|
782
|
+
"stringMatching",
|
|
783
|
+
(expected) => new StringMatching(expected)
|
|
784
|
+
);
|
|
785
|
+
chai.expect.not = {
|
|
786
|
+
stringContaining: (expected) => new StringContaining(expected, true),
|
|
787
|
+
objectContaining: (expected) => new ObjectContaining(expected, true),
|
|
788
|
+
arrayContaining: (expected) => new ArrayContaining(expected, true),
|
|
789
|
+
stringMatching: (expected) => new StringMatching(expected, true)
|
|
790
|
+
};
|
|
1127
791
|
};
|
|
1128
792
|
const JestChaiExpect = (chai, utils) => {
|
|
1129
793
|
function def(name, fn) {
|
|
@@ -1430,11 +1094,11 @@ const JestChaiExpect = (chai, utils) => {
|
|
|
1430
1094
|
return `${i}th`;
|
|
1431
1095
|
};
|
|
1432
1096
|
const formatCalls = (spy, msg, actualCall) => {
|
|
1433
|
-
msg +=
|
|
1097
|
+
msg += c.gray(`
|
|
1434
1098
|
|
|
1435
1099
|
Received:
|
|
1436
1100
|
${spy.mock.calls.map((callArg, i) => {
|
|
1437
|
-
let methodCall =
|
|
1101
|
+
let methodCall = c.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
|
|
1438
1102
|
|
|
1439
1103
|
`);
|
|
1440
1104
|
if (actualCall)
|
|
@@ -1444,18 +1108,18 @@ ${spy.mock.calls.map((callArg, i) => {
|
|
|
1444
1108
|
methodCall += "\n";
|
|
1445
1109
|
return methodCall;
|
|
1446
1110
|
}).join("\n")}`);
|
|
1447
|
-
msg +=
|
|
1111
|
+
msg += c.gray(`
|
|
1448
1112
|
|
|
1449
|
-
Number of calls: ${
|
|
1113
|
+
Number of calls: ${c.bold(spy.mock.calls.length)}
|
|
1450
1114
|
`);
|
|
1451
1115
|
return msg;
|
|
1452
1116
|
};
|
|
1453
1117
|
const formatReturns = (spy, msg, actualReturn) => {
|
|
1454
|
-
msg +=
|
|
1118
|
+
msg += c.gray(`
|
|
1455
1119
|
|
|
1456
1120
|
Received:
|
|
1457
1121
|
${spy.mock.results.map((callReturn, i) => {
|
|
1458
|
-
let methodCall =
|
|
1122
|
+
let methodCall = c.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
|
|
1459
1123
|
|
|
1460
1124
|
`);
|
|
1461
1125
|
if (actualReturn)
|
|
@@ -1465,9 +1129,9 @@ ${spy.mock.results.map((callReturn, i) => {
|
|
|
1465
1129
|
methodCall += "\n";
|
|
1466
1130
|
return methodCall;
|
|
1467
1131
|
}).join("\n")}`);
|
|
1468
|
-
msg +=
|
|
1132
|
+
msg += c.gray(`
|
|
1469
1133
|
|
|
1470
|
-
Number of calls: ${
|
|
1134
|
+
Number of calls: ${c.bold(spy.mock.calls.length)}
|
|
1471
1135
|
`);
|
|
1472
1136
|
return msg;
|
|
1473
1137
|
};
|
|
@@ -1511,7 +1175,7 @@ Number of calls: ${picocolors.exports.bold(spy.mock.calls.length)}
|
|
|
1511
1175
|
]
|
|
1512
1176
|
);
|
|
1513
1177
|
if (called && isNot)
|
|
1514
|
-
msg
|
|
1178
|
+
msg = formatCalls(spy, msg);
|
|
1515
1179
|
if (called && isNot || !called && !isNot) {
|
|
1516
1180
|
const err = new Error(msg);
|
|
1517
1181
|
err.name = "AssertionError";
|
|
@@ -1533,7 +1197,7 @@ Number of calls: ${picocolors.exports.bold(spy.mock.calls.length)}
|
|
|
1533
1197
|
]
|
|
1534
1198
|
);
|
|
1535
1199
|
if (pass && isNot || !pass && !isNot) {
|
|
1536
|
-
msg
|
|
1200
|
+
msg = formatCalls(spy, msg, args);
|
|
1537
1201
|
const err = new Error(msg);
|
|
1538
1202
|
err.name = "AssertionError";
|
|
1539
1203
|
throw err;
|
|
@@ -1716,7 +1380,7 @@ Number of calls: ${picocolors.exports.bold(spy.mock.calls.length)}
|
|
|
1716
1380
|
return result.call(this, ...args);
|
|
1717
1381
|
},
|
|
1718
1382
|
(err) => {
|
|
1719
|
-
throw new Error(`promise rejected "${
|
|
1383
|
+
throw new Error(`promise rejected "${String(err)}" instead of resolving`);
|
|
1720
1384
|
}
|
|
1721
1385
|
);
|
|
1722
1386
|
};
|
|
@@ -1724,353 +1388,851 @@ Number of calls: ${picocolors.exports.bold(spy.mock.calls.length)}
|
|
|
1724
1388
|
});
|
|
1725
1389
|
return proxy;
|
|
1726
1390
|
});
|
|
1727
|
-
utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() {
|
|
1728
|
-
utils.flag(this, "promise", "rejects");
|
|
1729
|
-
utils.flag(this, "error", new Error("rejects"));
|
|
1730
|
-
const obj = utils.flag(this, "object");
|
|
1731
|
-
const wrapper = typeof obj === "function" ? obj() : obj;
|
|
1732
|
-
if (typeof (wrapper == null ? void 0 : wrapper.then) !== "function")
|
|
1733
|
-
throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`);
|
|
1734
|
-
const proxy = new Proxy(this, {
|
|
1735
|
-
get: (target, key, receiver) => {
|
|
1736
|
-
const result = Reflect.get(target, key, receiver);
|
|
1737
|
-
if (typeof result !== "function")
|
|
1738
|
-
return result instanceof chai.Assertion ? proxy : result;
|
|
1739
|
-
return async (...args) => {
|
|
1740
|
-
return wrapper.then(
|
|
1741
|
-
(value) => {
|
|
1742
|
-
throw new Error(`promise resolved "${
|
|
1743
|
-
},
|
|
1744
|
-
(err) => {
|
|
1745
|
-
utils.flag(this, "object", err);
|
|
1746
|
-
return result.call(this, ...args);
|
|
1747
|
-
}
|
|
1748
|
-
);
|
|
1749
|
-
};
|
|
1391
|
+
utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() {
|
|
1392
|
+
utils.flag(this, "promise", "rejects");
|
|
1393
|
+
utils.flag(this, "error", new Error("rejects"));
|
|
1394
|
+
const obj = utils.flag(this, "object");
|
|
1395
|
+
const wrapper = typeof obj === "function" ? obj() : obj;
|
|
1396
|
+
if (typeof (wrapper == null ? void 0 : wrapper.then) !== "function")
|
|
1397
|
+
throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`);
|
|
1398
|
+
const proxy = new Proxy(this, {
|
|
1399
|
+
get: (target, key, receiver) => {
|
|
1400
|
+
const result = Reflect.get(target, key, receiver);
|
|
1401
|
+
if (typeof result !== "function")
|
|
1402
|
+
return result instanceof chai.Assertion ? proxy : result;
|
|
1403
|
+
return async (...args) => {
|
|
1404
|
+
return wrapper.then(
|
|
1405
|
+
(value) => {
|
|
1406
|
+
throw new Error(`promise resolved "${String(value)}" instead of rejecting`);
|
|
1407
|
+
},
|
|
1408
|
+
(err) => {
|
|
1409
|
+
utils.flag(this, "object", err);
|
|
1410
|
+
return result.call(this, ...args);
|
|
1411
|
+
}
|
|
1412
|
+
);
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1416
|
+
return proxy;
|
|
1417
|
+
});
|
|
1418
|
+
};
|
|
1419
|
+
const isAsyncFunction = (fn) => typeof fn === "function" && fn[Symbol.toStringTag] === "AsyncFunction";
|
|
1420
|
+
const getMatcherState = (assertion, expect) => {
|
|
1421
|
+
const obj = assertion._obj;
|
|
1422
|
+
const isNot = util.flag(assertion, "negate");
|
|
1423
|
+
const promise = util.flag(assertion, "promise") || "";
|
|
1424
|
+
const jestUtils = {
|
|
1425
|
+
...matcherUtils,
|
|
1426
|
+
iterableEquality,
|
|
1427
|
+
subsetEquality
|
|
1428
|
+
};
|
|
1429
|
+
const matcherState = {
|
|
1430
|
+
...getState(expect),
|
|
1431
|
+
isNot,
|
|
1432
|
+
utils: jestUtils,
|
|
1433
|
+
promise,
|
|
1434
|
+
equals,
|
|
1435
|
+
suppressedErrors: []
|
|
1436
|
+
};
|
|
1437
|
+
return {
|
|
1438
|
+
state: matcherState,
|
|
1439
|
+
isNot,
|
|
1440
|
+
obj
|
|
1441
|
+
};
|
|
1442
|
+
};
|
|
1443
|
+
class JestExtendError extends Error {
|
|
1444
|
+
constructor(message, actual, expected) {
|
|
1445
|
+
super(message);
|
|
1446
|
+
this.actual = actual;
|
|
1447
|
+
this.expected = expected;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
function JestExtendPlugin(expect, matchers) {
|
|
1451
|
+
return (c2, utils) => {
|
|
1452
|
+
Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
|
|
1453
|
+
function expectSyncWrapper(...args) {
|
|
1454
|
+
const { state, isNot, obj } = getMatcherState(this, expect);
|
|
1455
|
+
const { pass, message, actual, expected } = expectAssertion.call(state, obj, ...args);
|
|
1456
|
+
if (pass && isNot || !pass && !isNot)
|
|
1457
|
+
throw new JestExtendError(message(), actual, expected);
|
|
1458
|
+
}
|
|
1459
|
+
async function expectAsyncWrapper(...args) {
|
|
1460
|
+
const { state, isNot, obj } = getMatcherState(this, expect);
|
|
1461
|
+
const { pass, message, actual, expected } = await expectAssertion.call(state, obj, ...args);
|
|
1462
|
+
if (pass && isNot || !pass && !isNot)
|
|
1463
|
+
throw new JestExtendError(message(), actual, expected);
|
|
1464
|
+
}
|
|
1465
|
+
const expectAssertionWrapper = isAsyncFunction(expectAssertion) ? expectAsyncWrapper : expectSyncWrapper;
|
|
1466
|
+
utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, expectAssertionWrapper);
|
|
1467
|
+
utils.addMethod(c2.Assertion.prototype, expectAssertionName, expectAssertionWrapper);
|
|
1468
|
+
class CustomMatcher extends AsymmetricMatcher$1 {
|
|
1469
|
+
constructor(inverse = false, ...sample) {
|
|
1470
|
+
super(sample, inverse);
|
|
1471
|
+
}
|
|
1472
|
+
asymmetricMatch(other) {
|
|
1473
|
+
const { pass } = expectAssertion.call(
|
|
1474
|
+
this.getMatcherContext(expect),
|
|
1475
|
+
other,
|
|
1476
|
+
...this.sample
|
|
1477
|
+
);
|
|
1478
|
+
return this.inverse ? !pass : pass;
|
|
1479
|
+
}
|
|
1480
|
+
toString() {
|
|
1481
|
+
return `${this.inverse ? "not." : ""}${expectAssertionName}`;
|
|
1482
|
+
}
|
|
1483
|
+
getExpectedType() {
|
|
1484
|
+
return "any";
|
|
1485
|
+
}
|
|
1486
|
+
toAsymmetricMatcher() {
|
|
1487
|
+
return `${this.toString()}<${this.sample.map(String).join(", ")}>`;
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
Object.defineProperty(expect, expectAssertionName, {
|
|
1491
|
+
configurable: true,
|
|
1492
|
+
enumerable: true,
|
|
1493
|
+
value: (...sample) => new CustomMatcher(false, ...sample),
|
|
1494
|
+
writable: true
|
|
1495
|
+
});
|
|
1496
|
+
Object.defineProperty(expect.not, expectAssertionName, {
|
|
1497
|
+
configurable: true,
|
|
1498
|
+
enumerable: true,
|
|
1499
|
+
value: (...sample) => new CustomMatcher(true, ...sample),
|
|
1500
|
+
writable: true
|
|
1501
|
+
});
|
|
1502
|
+
});
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
const JestExtend = (chai, utils) => {
|
|
1506
|
+
utils.addMethod(chai.expect, "extend", (expect, expects) => {
|
|
1507
|
+
chai.use(JestExtendPlugin(expect, expects));
|
|
1508
|
+
});
|
|
1509
|
+
};
|
|
1510
|
+
|
|
1511
|
+
var naturalCompare$1 = {exports: {}};
|
|
1512
|
+
|
|
1513
|
+
/*
|
|
1514
|
+
* @version 1.4.0
|
|
1515
|
+
* @date 2015-10-26
|
|
1516
|
+
* @stability 3 - Stable
|
|
1517
|
+
* @author Lauri Rooden (https://github.com/litejs/natural-compare-lite)
|
|
1518
|
+
* @license MIT License
|
|
1519
|
+
*/
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
var naturalCompare = function(a, b) {
|
|
1523
|
+
var i, codeA
|
|
1524
|
+
, codeB = 1
|
|
1525
|
+
, posA = 0
|
|
1526
|
+
, posB = 0
|
|
1527
|
+
, alphabet = String.alphabet;
|
|
1528
|
+
|
|
1529
|
+
function getCode(str, pos, code) {
|
|
1530
|
+
if (code) {
|
|
1531
|
+
for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i;
|
|
1532
|
+
return +str.slice(pos - 1, i)
|
|
1533
|
+
}
|
|
1534
|
+
code = alphabet && alphabet.indexOf(str.charAt(pos));
|
|
1535
|
+
return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code
|
|
1536
|
+
: code < 46 ? 65 // -
|
|
1537
|
+
: code < 48 ? code - 1
|
|
1538
|
+
: code < 58 ? code + 18 // 0-9
|
|
1539
|
+
: code < 65 ? code - 11
|
|
1540
|
+
: code < 91 ? code + 11 // A-Z
|
|
1541
|
+
: code < 97 ? code - 37
|
|
1542
|
+
: code < 123 ? code + 5 // a-z
|
|
1543
|
+
: code - 63
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
if ((a+="") != (b+="")) for (;codeB;) {
|
|
1548
|
+
codeA = getCode(a, posA++);
|
|
1549
|
+
codeB = getCode(b, posB++);
|
|
1550
|
+
|
|
1551
|
+
if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) {
|
|
1552
|
+
codeA = getCode(a, posA, posA);
|
|
1553
|
+
codeB = getCode(b, posB, posA = i);
|
|
1554
|
+
posB = i;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
if (codeA != codeB) return (codeA < codeB) ? -1 : 1
|
|
1558
|
+
}
|
|
1559
|
+
return 0
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
try {
|
|
1563
|
+
naturalCompare$1.exports = naturalCompare;
|
|
1564
|
+
} catch (e) {
|
|
1565
|
+
String.naturalCompare = naturalCompare;
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
const serialize$1 = (val, config, indentation, depth, refs, printer) => {
|
|
1569
|
+
const name = val.getMockName();
|
|
1570
|
+
const nameString = name === "vi.fn()" ? "" : ` ${name}`;
|
|
1571
|
+
let callsString = "";
|
|
1572
|
+
if (val.mock.calls.length !== 0) {
|
|
1573
|
+
const indentationNext = indentation + config.indent;
|
|
1574
|
+
callsString = ` {${config.spacingOuter}${indentationNext}"calls": ${printer(val.mock.calls, config, indentationNext, depth, refs)}${config.min ? ", " : ","}${config.spacingOuter}${indentationNext}"results": ${printer(val.mock.results, config, indentationNext, depth, refs)}${config.min ? "" : ","}${config.spacingOuter}${indentation}}`;
|
|
1575
|
+
}
|
|
1576
|
+
return `[MockFunction${nameString}]${callsString}`;
|
|
1577
|
+
};
|
|
1578
|
+
const test$1 = (val) => val && !!val._isMockFunction;
|
|
1579
|
+
const plugin = { serialize: serialize$1, test: test$1 };
|
|
1580
|
+
|
|
1581
|
+
const {
|
|
1582
|
+
DOMCollection,
|
|
1583
|
+
DOMElement,
|
|
1584
|
+
Immutable,
|
|
1585
|
+
ReactElement,
|
|
1586
|
+
ReactTestComponent,
|
|
1587
|
+
AsymmetricMatcher
|
|
1588
|
+
} = plugins_1;
|
|
1589
|
+
let PLUGINS = [
|
|
1590
|
+
ReactTestComponent,
|
|
1591
|
+
ReactElement,
|
|
1592
|
+
DOMElement,
|
|
1593
|
+
DOMCollection,
|
|
1594
|
+
Immutable,
|
|
1595
|
+
AsymmetricMatcher,
|
|
1596
|
+
plugin
|
|
1597
|
+
];
|
|
1598
|
+
const addSerializer = (plugin) => {
|
|
1599
|
+
PLUGINS = [plugin].concat(PLUGINS);
|
|
1600
|
+
};
|
|
1601
|
+
const getSerializers = () => PLUGINS;
|
|
1602
|
+
|
|
1603
|
+
const SNAPSHOT_VERSION = "1";
|
|
1604
|
+
const writeSnapshotVersion = () => `// Vitest Snapshot v${SNAPSHOT_VERSION}`;
|
|
1605
|
+
const testNameToKey = (testName, count) => `${testName} ${count}`;
|
|
1606
|
+
const keyToTestName = (key) => {
|
|
1607
|
+
if (!/ \d+$/.test(key))
|
|
1608
|
+
throw new Error("Snapshot keys must end with a number.");
|
|
1609
|
+
return key.replace(/ \d+$/, "");
|
|
1610
|
+
};
|
|
1611
|
+
const getSnapshotData = (snapshotPath, update) => {
|
|
1612
|
+
const data = /* @__PURE__ */ Object.create(null);
|
|
1613
|
+
let snapshotContents = "";
|
|
1614
|
+
let dirty = false;
|
|
1615
|
+
if (fs.existsSync(snapshotPath)) {
|
|
1616
|
+
try {
|
|
1617
|
+
snapshotContents = fs.readFileSync(snapshotPath, "utf8");
|
|
1618
|
+
const populate = new Function("exports", snapshotContents);
|
|
1619
|
+
populate(data);
|
|
1620
|
+
} catch {
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
const isInvalid = snapshotContents;
|
|
1624
|
+
if ((update === "all" || update === "new") && isInvalid)
|
|
1625
|
+
dirty = true;
|
|
1626
|
+
return { data, dirty };
|
|
1627
|
+
};
|
|
1628
|
+
const addExtraLineBreaks = (string) => string.includes("\n") ? `
|
|
1629
|
+
${string}
|
|
1630
|
+
` : string;
|
|
1631
|
+
const removeExtraLineBreaks = (string) => string.length > 2 && string.startsWith("\n") && string.endsWith("\n") ? string.slice(1, -1) : string;
|
|
1632
|
+
const escapeRegex = true;
|
|
1633
|
+
const printFunctionName = false;
|
|
1634
|
+
function serialize(val, indent = 2, formatOverrides = {}) {
|
|
1635
|
+
return normalizeNewlines(
|
|
1636
|
+
format_1(val, {
|
|
1637
|
+
escapeRegex,
|
|
1638
|
+
indent,
|
|
1639
|
+
plugins: getSerializers(),
|
|
1640
|
+
printFunctionName,
|
|
1641
|
+
...formatOverrides
|
|
1642
|
+
})
|
|
1643
|
+
);
|
|
1644
|
+
}
|
|
1645
|
+
function escapeBacktickString(str) {
|
|
1646
|
+
return str.replace(/`|\\|\${/g, "\\$&");
|
|
1647
|
+
}
|
|
1648
|
+
function printBacktickString(str) {
|
|
1649
|
+
return `\`${escapeBacktickString(str)}\``;
|
|
1650
|
+
}
|
|
1651
|
+
function ensureDirectoryExists(filePath) {
|
|
1652
|
+
try {
|
|
1653
|
+
fs.mkdirSync(join(dirname(filePath)), { recursive: true });
|
|
1654
|
+
} catch {
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
function normalizeNewlines(string) {
|
|
1658
|
+
return string.replace(/\r\n|\r/g, "\n");
|
|
1659
|
+
}
|
|
1660
|
+
async function saveSnapshotFile(snapshotData, snapshotPath) {
|
|
1661
|
+
var _a, _b;
|
|
1662
|
+
const snapshots = Object.keys(snapshotData).sort(naturalCompare$1.exports).map(
|
|
1663
|
+
(key) => `exports[${printBacktickString(key)}] = ${printBacktickString(normalizeNewlines(snapshotData[key]))};`
|
|
1664
|
+
);
|
|
1665
|
+
const content = `${writeSnapshotVersion()}
|
|
1666
|
+
|
|
1667
|
+
${snapshots.join("\n\n")}
|
|
1668
|
+
`;
|
|
1669
|
+
const skipWriting = fs.existsSync(snapshotPath) && await ((_a = fs) == null ? void 0 : _a.promises.readFile(snapshotPath, "utf8")) === content;
|
|
1670
|
+
if (skipWriting)
|
|
1671
|
+
return;
|
|
1672
|
+
ensureDirectoryExists(snapshotPath);
|
|
1673
|
+
await ((_b = fs) == null ? void 0 : _b.promises.writeFile(
|
|
1674
|
+
snapshotPath,
|
|
1675
|
+
content,
|
|
1676
|
+
"utf-8"
|
|
1677
|
+
));
|
|
1678
|
+
}
|
|
1679
|
+
function prepareExpected(expected) {
|
|
1680
|
+
function findStartIndent() {
|
|
1681
|
+
var _a, _b;
|
|
1682
|
+
const matchObject = /^( +)}\s+$/m.exec(expected || "");
|
|
1683
|
+
const objectIndent = (_a = matchObject == null ? void 0 : matchObject[1]) == null ? void 0 : _a.length;
|
|
1684
|
+
if (objectIndent)
|
|
1685
|
+
return objectIndent;
|
|
1686
|
+
const matchText = /^\n( +)"/.exec(expected || "");
|
|
1687
|
+
return ((_b = matchText == null ? void 0 : matchText[1]) == null ? void 0 : _b.length) || 0;
|
|
1688
|
+
}
|
|
1689
|
+
const startIndent = findStartIndent();
|
|
1690
|
+
let expectedTrimmed = expected == null ? void 0 : expected.trim();
|
|
1691
|
+
if (startIndent) {
|
|
1692
|
+
expectedTrimmed = expectedTrimmed == null ? void 0 : expectedTrimmed.replace(new RegExp(`^${" ".repeat(startIndent)}`, "gm"), "").replace(/ +}$/, "}");
|
|
1693
|
+
}
|
|
1694
|
+
return expectedTrimmed;
|
|
1695
|
+
}
|
|
1696
|
+
function deepMergeArray(target = [], source = []) {
|
|
1697
|
+
const mergedOutput = Array.from(target);
|
|
1698
|
+
source.forEach((sourceElement, index) => {
|
|
1699
|
+
const targetElement = mergedOutput[index];
|
|
1700
|
+
if (Array.isArray(target[index])) {
|
|
1701
|
+
mergedOutput[index] = deepMergeArray(target[index], sourceElement);
|
|
1702
|
+
} else if (isObject$1(targetElement)) {
|
|
1703
|
+
mergedOutput[index] = deepMergeSnapshot(target[index], sourceElement);
|
|
1704
|
+
} else {
|
|
1705
|
+
mergedOutput[index] = sourceElement;
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1708
|
+
return mergedOutput;
|
|
1709
|
+
}
|
|
1710
|
+
function deepMergeSnapshot(target, source) {
|
|
1711
|
+
if (isObject$1(target) && isObject$1(source)) {
|
|
1712
|
+
const mergedOutput = { ...target };
|
|
1713
|
+
Object.keys(source).forEach((key) => {
|
|
1714
|
+
if (isObject$1(source[key]) && !source[key].$$typeof) {
|
|
1715
|
+
if (!(key in target))
|
|
1716
|
+
Object.assign(mergedOutput, { [key]: source[key] });
|
|
1717
|
+
else
|
|
1718
|
+
mergedOutput[key] = deepMergeSnapshot(target[key], source[key]);
|
|
1719
|
+
} else if (Array.isArray(source[key])) {
|
|
1720
|
+
mergedOutput[key] = deepMergeArray(target[key], source[key]);
|
|
1721
|
+
} else {
|
|
1722
|
+
Object.assign(mergedOutput, { [key]: source[key] });
|
|
1750
1723
|
}
|
|
1751
1724
|
});
|
|
1752
|
-
return
|
|
1753
|
-
})
|
|
1754
|
-
|
|
1755
|
-
chai.expect,
|
|
1756
|
-
"addSnapshotSerializer",
|
|
1757
|
-
addSerializer
|
|
1758
|
-
);
|
|
1759
|
-
};
|
|
1760
|
-
function toString(value) {
|
|
1761
|
-
try {
|
|
1762
|
-
return `${value}`;
|
|
1763
|
-
} catch (_error) {
|
|
1764
|
-
return "unknown";
|
|
1725
|
+
return mergedOutput;
|
|
1726
|
+
} else if (Array.isArray(target) && Array.isArray(source)) {
|
|
1727
|
+
return deepMergeArray(target, source);
|
|
1765
1728
|
}
|
|
1729
|
+
return target;
|
|
1766
1730
|
}
|
|
1767
1731
|
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1732
|
+
async function saveInlineSnapshots(snapshots) {
|
|
1733
|
+
const MagicString = (await import('./chunk-magic-string.3a794426.js')).default;
|
|
1734
|
+
const files = new Set(snapshots.map((i) => i.file));
|
|
1735
|
+
await Promise.all(Array.from(files).map(async (file) => {
|
|
1736
|
+
const snaps = snapshots.filter((i) => i.file === file);
|
|
1737
|
+
const code = await promises.readFile(file, "utf8");
|
|
1738
|
+
const s = new MagicString(code);
|
|
1739
|
+
for (const snap of snaps) {
|
|
1740
|
+
const index = positionToOffset(code, snap.line, snap.column);
|
|
1741
|
+
replaceInlineSnap(code, s, index, snap.snapshot);
|
|
1742
|
+
}
|
|
1743
|
+
const transformed = s.toString();
|
|
1744
|
+
if (transformed !== code)
|
|
1745
|
+
await promises.writeFile(file, transformed, "utf-8");
|
|
1746
|
+
}));
|
|
1747
|
+
}
|
|
1748
|
+
const startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*({)/m;
|
|
1749
|
+
function replaceObjectSnap(code, s, index, newSnap) {
|
|
1750
|
+
code = code.slice(index);
|
|
1751
|
+
const startMatch = startObjectRegex.exec(code);
|
|
1752
|
+
if (!startMatch)
|
|
1753
|
+
return false;
|
|
1754
|
+
code = code.slice(startMatch.index);
|
|
1755
|
+
const charIndex = getCallLastIndex(code);
|
|
1756
|
+
if (charIndex === null)
|
|
1757
|
+
return false;
|
|
1758
|
+
s.appendLeft(index + startMatch.index + charIndex, `, ${prepareSnapString(newSnap, code, index)}`);
|
|
1759
|
+
return true;
|
|
1760
|
+
}
|
|
1761
|
+
function prepareSnapString(snap, source, index) {
|
|
1762
|
+
const lineNumber = offsetToLineNumber(source, index);
|
|
1763
|
+
const line = source.split(lineSplitRE)[lineNumber - 1];
|
|
1764
|
+
const indent = line.match(/^\s*/)[0] || "";
|
|
1765
|
+
const indentNext = indent.includes(" ") ? `${indent} ` : `${indent} `;
|
|
1766
|
+
const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
|
|
1767
|
+
const isOneline = lines.length <= 1;
|
|
1768
|
+
const quote = isOneline ? "'" : "`";
|
|
1769
|
+
if (isOneline)
|
|
1770
|
+
return `'${lines.join("\n").replace(/'/g, "\\'")}'`;
|
|
1771
|
+
else
|
|
1772
|
+
return `${quote}
|
|
1773
|
+
${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\${/g, "\\${")}
|
|
1774
|
+
${indent}${quote}`;
|
|
1775
|
+
}
|
|
1776
|
+
const startRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*[\w_$]*(['"`\)])/m;
|
|
1777
|
+
function replaceInlineSnap(code, s, index, newSnap) {
|
|
1778
|
+
const startMatch = startRegex.exec(code.slice(index));
|
|
1779
|
+
if (!startMatch)
|
|
1780
|
+
return replaceObjectSnap(code, s, index, newSnap);
|
|
1781
|
+
const quote = startMatch[1];
|
|
1782
|
+
const startIndex = index + startMatch.index + startMatch[0].length;
|
|
1783
|
+
const snapString = prepareSnapString(newSnap, code, index);
|
|
1784
|
+
if (quote === ")") {
|
|
1785
|
+
s.appendRight(startIndex - 1, snapString);
|
|
1786
|
+
return true;
|
|
1781
1787
|
}
|
|
1788
|
+
const quoteEndRE = new RegExp(`(?:^|[^\\\\])${quote}`);
|
|
1789
|
+
const endMatch = quoteEndRE.exec(code.slice(startIndex));
|
|
1790
|
+
if (!endMatch)
|
|
1791
|
+
return false;
|
|
1792
|
+
const endIndex = startIndex + endMatch.index + endMatch[0].length;
|
|
1793
|
+
s.overwrite(startIndex - 1, endIndex, snapString);
|
|
1794
|
+
return true;
|
|
1782
1795
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1796
|
+
const INDENTATION_REGEX = /^([^\S\n]*)\S/m;
|
|
1797
|
+
function stripSnapshotIndentation(inlineSnapshot) {
|
|
1798
|
+
const match = inlineSnapshot.match(INDENTATION_REGEX);
|
|
1799
|
+
if (!match || !match[1]) {
|
|
1800
|
+
return inlineSnapshot;
|
|
1788
1801
|
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1802
|
+
const indentation = match[1];
|
|
1803
|
+
const lines = inlineSnapshot.split(/\n/g);
|
|
1804
|
+
if (lines.length <= 2) {
|
|
1805
|
+
return inlineSnapshot;
|
|
1792
1806
|
}
|
|
1793
|
-
|
|
1794
|
-
return
|
|
1807
|
+
if (lines[0].trim() !== "" || lines[lines.length - 1].trim() !== "") {
|
|
1808
|
+
return inlineSnapshot;
|
|
1795
1809
|
}
|
|
1796
|
-
|
|
1797
|
-
|
|
1810
|
+
for (let i = 1; i < lines.length - 1; i++) {
|
|
1811
|
+
if (lines[i] !== "") {
|
|
1812
|
+
if (lines[i].indexOf(indentation) !== 0) {
|
|
1813
|
+
return inlineSnapshot;
|
|
1814
|
+
}
|
|
1815
|
+
lines[i] = lines[i].substring(indentation.length);
|
|
1816
|
+
}
|
|
1798
1817
|
}
|
|
1818
|
+
lines[lines.length - 1] = "";
|
|
1819
|
+
inlineSnapshot = lines.join("\n");
|
|
1820
|
+
return inlineSnapshot;
|
|
1799
1821
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1822
|
+
|
|
1823
|
+
class SnapshotState {
|
|
1824
|
+
constructor(testFilePath, snapshotPath, options) {
|
|
1825
|
+
this.testFilePath = testFilePath;
|
|
1826
|
+
this.snapshotPath = snapshotPath;
|
|
1827
|
+
const { data, dirty } = getSnapshotData(
|
|
1828
|
+
this.snapshotPath,
|
|
1829
|
+
options.updateSnapshot
|
|
1830
|
+
);
|
|
1831
|
+
this._initialData = data;
|
|
1832
|
+
this._snapshotData = data;
|
|
1833
|
+
this._dirty = dirty;
|
|
1834
|
+
this._inlineSnapshots = [];
|
|
1835
|
+
this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
|
|
1836
|
+
this._counters = /* @__PURE__ */ new Map();
|
|
1837
|
+
this.expand = options.expand || false;
|
|
1838
|
+
this.added = 0;
|
|
1839
|
+
this.matched = 0;
|
|
1840
|
+
this.unmatched = 0;
|
|
1841
|
+
this._updateSnapshot = options.updateSnapshot;
|
|
1842
|
+
this.updated = 0;
|
|
1843
|
+
this._snapshotFormat = {
|
|
1844
|
+
printBasicPrototype: false,
|
|
1845
|
+
...options.snapshotFormat
|
|
1846
|
+
};
|
|
1803
1847
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1848
|
+
markSnapshotsAsCheckedForTest(testName) {
|
|
1849
|
+
this._uncheckedKeys.forEach((uncheckedKey) => {
|
|
1850
|
+
if (keyToTestName(uncheckedKey) === testName)
|
|
1851
|
+
this._uncheckedKeys.delete(uncheckedKey);
|
|
1852
|
+
});
|
|
1806
1853
|
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1854
|
+
_inferInlineSnapshotStack(stacks) {
|
|
1855
|
+
const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/));
|
|
1856
|
+
if (promiseIndex !== -1)
|
|
1857
|
+
return stacks[promiseIndex + 3];
|
|
1858
|
+
const stackIndex = stacks.findIndex((i) => i.method.includes("__VITEST_INLINE_SNAPSHOT__"));
|
|
1859
|
+
return stackIndex !== -1 ? stacks[stackIndex + 2] : null;
|
|
1860
|
+
}
|
|
1861
|
+
_addSnapshot(key, receivedSerialized, options) {
|
|
1862
|
+
this._dirty = true;
|
|
1863
|
+
if (options.isInline) {
|
|
1864
|
+
const error = options.error || new Error("Unknown error");
|
|
1865
|
+
const stacks = parseStacktrace(error, true);
|
|
1866
|
+
stacks.forEach((i) => i.file = slash(i.file));
|
|
1867
|
+
const stack = this._inferInlineSnapshotStack(stacks);
|
|
1868
|
+
if (!stack) {
|
|
1869
|
+
throw new Error(
|
|
1870
|
+
`Vitest: Couldn't infer stack frame for inline snapshot.
|
|
1871
|
+
${JSON.stringify(stacks)}`
|
|
1872
|
+
);
|
|
1873
|
+
}
|
|
1874
|
+
stack.column--;
|
|
1875
|
+
this._inlineSnapshots.push({
|
|
1876
|
+
snapshot: receivedSerialized,
|
|
1877
|
+
...stack
|
|
1878
|
+
});
|
|
1879
|
+
} else {
|
|
1880
|
+
this._snapshotData[key] = receivedSerialized;
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
clear() {
|
|
1884
|
+
this._snapshotData = this._initialData;
|
|
1885
|
+
this._counters = /* @__PURE__ */ new Map();
|
|
1886
|
+
this.added = 0;
|
|
1887
|
+
this.matched = 0;
|
|
1888
|
+
this.unmatched = 0;
|
|
1889
|
+
this.updated = 0;
|
|
1890
|
+
this._dirty = false;
|
|
1891
|
+
}
|
|
1892
|
+
async save() {
|
|
1893
|
+
const hasExternalSnapshots = Object.keys(this._snapshotData).length;
|
|
1894
|
+
const hasInlineSnapshots = this._inlineSnapshots.length;
|
|
1895
|
+
const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots;
|
|
1896
|
+
const status = {
|
|
1897
|
+
deleted: false,
|
|
1898
|
+
saved: false
|
|
1899
|
+
};
|
|
1900
|
+
if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) {
|
|
1901
|
+
if (hasExternalSnapshots)
|
|
1902
|
+
await saveSnapshotFile(this._snapshotData, this.snapshotPath);
|
|
1903
|
+
if (hasInlineSnapshots)
|
|
1904
|
+
await saveInlineSnapshots(this._inlineSnapshots);
|
|
1905
|
+
status.saved = true;
|
|
1906
|
+
} else if (!hasExternalSnapshots && fs.existsSync(this.snapshotPath)) {
|
|
1907
|
+
if (this._updateSnapshot === "all")
|
|
1908
|
+
fs.unlinkSync(this.snapshotPath);
|
|
1909
|
+
status.deleted = true;
|
|
1910
|
+
}
|
|
1911
|
+
return status;
|
|
1809
1912
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
constructor(sample, inverse = false) {
|
|
1813
|
-
super(sample, inverse);
|
|
1913
|
+
getUncheckedCount() {
|
|
1914
|
+
return this._uncheckedKeys.size || 0;
|
|
1814
1915
|
}
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
return Object.getPrototypeOf(obj);
|
|
1818
|
-
if (obj.constructor.prototype === obj)
|
|
1819
|
-
return null;
|
|
1820
|
-
return obj.constructor.prototype;
|
|
1916
|
+
getUncheckedKeys() {
|
|
1917
|
+
return Array.from(this._uncheckedKeys);
|
|
1821
1918
|
}
|
|
1822
|
-
|
|
1823
|
-
if (
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1919
|
+
removeUncheckedKeys() {
|
|
1920
|
+
if (this._updateSnapshot === "all" && this._uncheckedKeys.size) {
|
|
1921
|
+
this._dirty = true;
|
|
1922
|
+
this._uncheckedKeys.forEach((key) => delete this._snapshotData[key]);
|
|
1923
|
+
this._uncheckedKeys.clear();
|
|
1924
|
+
}
|
|
1828
1925
|
}
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1926
|
+
match({
|
|
1927
|
+
testName,
|
|
1928
|
+
received,
|
|
1929
|
+
key,
|
|
1930
|
+
inlineSnapshot,
|
|
1931
|
+
isInline,
|
|
1932
|
+
error
|
|
1933
|
+
}) {
|
|
1934
|
+
this._counters.set(testName, (this._counters.get(testName) || 0) + 1);
|
|
1935
|
+
const count = Number(this._counters.get(testName));
|
|
1936
|
+
if (!key)
|
|
1937
|
+
key = testNameToKey(testName, count);
|
|
1938
|
+
if (!(isInline && this._snapshotData[key] !== void 0))
|
|
1939
|
+
this._uncheckedKeys.delete(key);
|
|
1940
|
+
const receivedSerialized = addExtraLineBreaks(serialize(received, void 0, this._snapshotFormat));
|
|
1941
|
+
const expected = isInline ? inlineSnapshot : this._snapshotData[key];
|
|
1942
|
+
const expectedTrimmed = prepareExpected(expected);
|
|
1943
|
+
const pass = expectedTrimmed === prepareExpected(receivedSerialized);
|
|
1944
|
+
const hasSnapshot = expected !== void 0;
|
|
1945
|
+
const snapshotIsPersisted = isInline || fs.existsSync(this.snapshotPath);
|
|
1946
|
+
if (pass && !isInline) {
|
|
1947
|
+
this._snapshotData[key] = receivedSerialized;
|
|
1834
1948
|
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1949
|
+
if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
|
|
1950
|
+
if (this._updateSnapshot === "all") {
|
|
1951
|
+
if (!pass) {
|
|
1952
|
+
if (hasSnapshot)
|
|
1953
|
+
this.updated++;
|
|
1954
|
+
else
|
|
1955
|
+
this.added++;
|
|
1956
|
+
this._addSnapshot(key, receivedSerialized, { error, isInline });
|
|
1957
|
+
} else {
|
|
1958
|
+
this.matched++;
|
|
1959
|
+
}
|
|
1960
|
+
} else {
|
|
1961
|
+
this._addSnapshot(key, receivedSerialized, { error, isInline });
|
|
1962
|
+
this.added++;
|
|
1963
|
+
}
|
|
1964
|
+
return {
|
|
1965
|
+
actual: "",
|
|
1966
|
+
count,
|
|
1967
|
+
expected: "",
|
|
1968
|
+
key,
|
|
1969
|
+
pass: true
|
|
1970
|
+
};
|
|
1971
|
+
} else {
|
|
1972
|
+
if (!pass) {
|
|
1973
|
+
this.unmatched++;
|
|
1974
|
+
return {
|
|
1975
|
+
actual: removeExtraLineBreaks(receivedSerialized),
|
|
1976
|
+
count,
|
|
1977
|
+
expected: expectedTrimmed !== void 0 ? removeExtraLineBreaks(expectedTrimmed) : void 0,
|
|
1978
|
+
key,
|
|
1979
|
+
pass: false
|
|
1980
|
+
};
|
|
1981
|
+
} else {
|
|
1982
|
+
this.matched++;
|
|
1983
|
+
return {
|
|
1984
|
+
actual: "",
|
|
1985
|
+
count,
|
|
1986
|
+
expected: "",
|
|
1987
|
+
key,
|
|
1988
|
+
pass: true
|
|
1989
|
+
};
|
|
1840
1990
|
}
|
|
1841
1991
|
}
|
|
1842
|
-
return this.inverse ? !result : result;
|
|
1843
|
-
}
|
|
1844
|
-
toString() {
|
|
1845
|
-
return `Object${this.inverse ? "Not" : ""}Containing`;
|
|
1846
1992
|
}
|
|
1847
|
-
|
|
1848
|
-
|
|
1993
|
+
async pack() {
|
|
1994
|
+
const snapshot = {
|
|
1995
|
+
filepath: this.testFilePath,
|
|
1996
|
+
added: 0,
|
|
1997
|
+
fileDeleted: false,
|
|
1998
|
+
matched: 0,
|
|
1999
|
+
unchecked: 0,
|
|
2000
|
+
uncheckedKeys: [],
|
|
2001
|
+
unmatched: 0,
|
|
2002
|
+
updated: 0
|
|
2003
|
+
};
|
|
2004
|
+
const uncheckedCount = this.getUncheckedCount();
|
|
2005
|
+
const uncheckedKeys = this.getUncheckedKeys();
|
|
2006
|
+
if (uncheckedCount)
|
|
2007
|
+
this.removeUncheckedKeys();
|
|
2008
|
+
const status = await this.save();
|
|
2009
|
+
snapshot.fileDeleted = status.deleted;
|
|
2010
|
+
snapshot.added = this.added;
|
|
2011
|
+
snapshot.matched = this.matched;
|
|
2012
|
+
snapshot.unmatched = this.unmatched;
|
|
2013
|
+
snapshot.updated = this.updated;
|
|
2014
|
+
snapshot.unchecked = !status.deleted ? uncheckedCount : 0;
|
|
2015
|
+
snapshot.uncheckedKeys = Array.from(uncheckedKeys);
|
|
2016
|
+
return snapshot;
|
|
1849
2017
|
}
|
|
1850
2018
|
}
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
asymmetricMatch(other) {
|
|
1856
|
-
if (!Array.isArray(this.sample)) {
|
|
1857
|
-
throw new TypeError(
|
|
1858
|
-
`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`
|
|
1859
|
-
);
|
|
1860
|
-
}
|
|
1861
|
-
const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every(
|
|
1862
|
-
(item) => other.some((another) => equals(item, another))
|
|
1863
|
-
);
|
|
1864
|
-
return this.inverse ? !result : result;
|
|
1865
|
-
}
|
|
1866
|
-
toString() {
|
|
1867
|
-
return `Array${this.inverse ? "Not" : ""}Containing`;
|
|
1868
|
-
}
|
|
1869
|
-
getExpectedType() {
|
|
1870
|
-
return "array";
|
|
2019
|
+
|
|
2020
|
+
class SnapshotClient {
|
|
2021
|
+
constructor() {
|
|
2022
|
+
this.snapshotStateMap = /* @__PURE__ */ new Map();
|
|
1871
2023
|
}
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
if (
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
)
|
|
2024
|
+
async setTest(test) {
|
|
2025
|
+
var _a;
|
|
2026
|
+
this.test = test;
|
|
2027
|
+
if (((_a = this.snapshotState) == null ? void 0 : _a.testFilePath) !== this.test.file.filepath) {
|
|
2028
|
+
this.saveCurrent();
|
|
2029
|
+
const filePath = this.test.file.filepath;
|
|
2030
|
+
if (!this.getSnapshotState(test)) {
|
|
2031
|
+
this.snapshotStateMap.set(
|
|
2032
|
+
filePath,
|
|
2033
|
+
new SnapshotState(
|
|
2034
|
+
filePath,
|
|
2035
|
+
await rpc().resolveSnapshotPath(filePath),
|
|
2036
|
+
getWorkerState().config.snapshotOptions
|
|
2037
|
+
)
|
|
2038
|
+
);
|
|
2039
|
+
}
|
|
2040
|
+
this.snapshotState = this.getSnapshotState(test);
|
|
1879
2041
|
}
|
|
1880
|
-
super(sample);
|
|
1881
2042
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
return func.name;
|
|
1885
|
-
const functionToString = Function.prototype.toString;
|
|
1886
|
-
const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/);
|
|
1887
|
-
return matches ? matches[1] : "<anonymous>";
|
|
2043
|
+
getSnapshotState(test) {
|
|
2044
|
+
return this.snapshotStateMap.get(test.file.filepath);
|
|
1888
2045
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
return typeof other == "string" || other instanceof String;
|
|
1892
|
-
if (this.sample === Number)
|
|
1893
|
-
return typeof other == "number" || other instanceof Number;
|
|
1894
|
-
if (this.sample === Function)
|
|
1895
|
-
return typeof other == "function" || other instanceof Function;
|
|
1896
|
-
if (this.sample === Boolean)
|
|
1897
|
-
return typeof other == "boolean" || other instanceof Boolean;
|
|
1898
|
-
if (this.sample === BigInt)
|
|
1899
|
-
return typeof other == "bigint" || other instanceof BigInt;
|
|
1900
|
-
if (this.sample === Symbol)
|
|
1901
|
-
return typeof other == "symbol" || other instanceof Symbol;
|
|
1902
|
-
if (this.sample === Object)
|
|
1903
|
-
return typeof other == "object";
|
|
1904
|
-
return other instanceof this.sample;
|
|
2046
|
+
clearTest() {
|
|
2047
|
+
this.test = void 0;
|
|
1905
2048
|
}
|
|
1906
|
-
|
|
1907
|
-
|
|
2049
|
+
skipTestSnapshots(test) {
|
|
2050
|
+
var _a;
|
|
2051
|
+
(_a = this.snapshotState) == null ? void 0 : _a.markSnapshotsAsCheckedForTest(test.name);
|
|
1908
2052
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2053
|
+
assert(options) {
|
|
2054
|
+
const {
|
|
2055
|
+
test = this.test,
|
|
2056
|
+
message,
|
|
2057
|
+
isInline = false,
|
|
2058
|
+
properties,
|
|
2059
|
+
inlineSnapshot,
|
|
2060
|
+
error,
|
|
2061
|
+
errorMessage
|
|
2062
|
+
} = options;
|
|
2063
|
+
let { received } = options;
|
|
2064
|
+
if (!test)
|
|
2065
|
+
throw new Error("Snapshot cannot be used outside of test");
|
|
2066
|
+
if (typeof properties === "object") {
|
|
2067
|
+
if (typeof received !== "object" || !received)
|
|
2068
|
+
throw new Error("Received value must be an object when the matcher has properties");
|
|
2069
|
+
try {
|
|
2070
|
+
const pass2 = equals(received, properties, [iterableEquality, subsetEquality]);
|
|
2071
|
+
if (!pass2)
|
|
2072
|
+
expect(received).equals(properties);
|
|
2073
|
+
else
|
|
2074
|
+
received = deepMergeSnapshot(received, properties);
|
|
2075
|
+
} catch (err) {
|
|
2076
|
+
err.message = errorMessage || "Snapshot mismatched";
|
|
2077
|
+
throw err;
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
const testName = [
|
|
2081
|
+
...getNames(test).slice(1),
|
|
2082
|
+
...message ? [message] : []
|
|
2083
|
+
].join(" > ");
|
|
2084
|
+
const snapshotState = this.getSnapshotState(test);
|
|
2085
|
+
const { actual, expected, key, pass } = snapshotState.match({
|
|
2086
|
+
testName,
|
|
2087
|
+
received,
|
|
2088
|
+
isInline,
|
|
2089
|
+
error,
|
|
2090
|
+
inlineSnapshot
|
|
2091
|
+
});
|
|
2092
|
+
if (!pass) {
|
|
2093
|
+
try {
|
|
2094
|
+
expect(actual.trim()).equals(expected ? expected.trim() : "");
|
|
2095
|
+
} catch (error2) {
|
|
2096
|
+
error2.message = errorMessage || `Snapshot \`${key || "unknown"}\` mismatched`;
|
|
2097
|
+
throw error2;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
1921
2100
|
}
|
|
1922
|
-
|
|
1923
|
-
|
|
2101
|
+
async saveCurrent() {
|
|
2102
|
+
if (!this.snapshotState)
|
|
2103
|
+
return;
|
|
2104
|
+
const result = await this.snapshotState.pack();
|
|
2105
|
+
await rpc().snapshotSaved(result);
|
|
2106
|
+
this.snapshotState = void 0;
|
|
1924
2107
|
}
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
constructor(sample, inverse = false) {
|
|
1928
|
-
if (!isA("String", sample) && !isA("RegExp", sample))
|
|
1929
|
-
throw new Error("Expected is not a String or a RegExp");
|
|
1930
|
-
super(new RegExp(sample), inverse);
|
|
2108
|
+
clear() {
|
|
2109
|
+
this.snapshotStateMap.clear();
|
|
1931
2110
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
let _client;
|
|
2114
|
+
function getSnapshotClient() {
|
|
2115
|
+
if (!_client)
|
|
2116
|
+
_client = new SnapshotClient();
|
|
2117
|
+
return _client;
|
|
2118
|
+
}
|
|
2119
|
+
const getErrorMessage = (err) => {
|
|
2120
|
+
if (err instanceof Error)
|
|
2121
|
+
return err.message;
|
|
2122
|
+
return err;
|
|
2123
|
+
};
|
|
2124
|
+
const getErrorString = (expected, promise) => {
|
|
2125
|
+
if (typeof expected !== "function") {
|
|
2126
|
+
if (!promise)
|
|
2127
|
+
throw new Error(`expected must be a function, received ${typeof expected}`);
|
|
2128
|
+
return getErrorMessage(expected);
|
|
1935
2129
|
}
|
|
1936
|
-
|
|
1937
|
-
|
|
2130
|
+
try {
|
|
2131
|
+
expected();
|
|
2132
|
+
} catch (e) {
|
|
2133
|
+
return getErrorMessage(e);
|
|
1938
2134
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
2135
|
+
throw new Error("snapshot function didn't throw");
|
|
2136
|
+
};
|
|
2137
|
+
const SnapshotPlugin = (chai, utils) => {
|
|
2138
|
+
for (const key of ["matchSnapshot", "toMatchSnapshot"]) {
|
|
2139
|
+
utils.addMethod(
|
|
2140
|
+
chai.Assertion.prototype,
|
|
2141
|
+
key,
|
|
2142
|
+
function(properties, message) {
|
|
2143
|
+
const expected = utils.flag(this, "object");
|
|
2144
|
+
const test = utils.flag(this, "vitest-test");
|
|
2145
|
+
if (typeof properties === "string" && typeof message === "undefined") {
|
|
2146
|
+
message = properties;
|
|
2147
|
+
properties = void 0;
|
|
2148
|
+
}
|
|
2149
|
+
const errorMessage = utils.flag(this, "message");
|
|
2150
|
+
getSnapshotClient().assert({
|
|
2151
|
+
received: expected,
|
|
2152
|
+
test,
|
|
2153
|
+
message,
|
|
2154
|
+
isInline: false,
|
|
2155
|
+
properties,
|
|
2156
|
+
errorMessage
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
);
|
|
1941
2160
|
}
|
|
1942
|
-
}
|
|
1943
|
-
const JestAsymmetricMatchers = (chai, utils) => {
|
|
1944
|
-
utils.addMethod(
|
|
1945
|
-
chai.expect,
|
|
1946
|
-
"anything",
|
|
1947
|
-
() => new Anything()
|
|
1948
|
-
);
|
|
1949
|
-
utils.addMethod(
|
|
1950
|
-
chai.expect,
|
|
1951
|
-
"any",
|
|
1952
|
-
(expected) => new Any(expected)
|
|
1953
|
-
);
|
|
1954
2161
|
utils.addMethod(
|
|
1955
|
-
chai.
|
|
1956
|
-
"
|
|
1957
|
-
(
|
|
2162
|
+
chai.Assertion.prototype,
|
|
2163
|
+
"toMatchInlineSnapshot",
|
|
2164
|
+
function __VITEST_INLINE_SNAPSHOT__(properties, inlineSnapshot, message) {
|
|
2165
|
+
const expected = utils.flag(this, "object");
|
|
2166
|
+
const error = utils.flag(this, "error");
|
|
2167
|
+
const test = utils.flag(this, "vitest-test");
|
|
2168
|
+
if (typeof properties === "string") {
|
|
2169
|
+
message = inlineSnapshot;
|
|
2170
|
+
inlineSnapshot = properties;
|
|
2171
|
+
properties = void 0;
|
|
2172
|
+
}
|
|
2173
|
+
if (inlineSnapshot)
|
|
2174
|
+
inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
|
|
2175
|
+
const errorMessage = utils.flag(this, "message");
|
|
2176
|
+
getSnapshotClient().assert({
|
|
2177
|
+
received: expected,
|
|
2178
|
+
test,
|
|
2179
|
+
message,
|
|
2180
|
+
isInline: true,
|
|
2181
|
+
properties,
|
|
2182
|
+
inlineSnapshot,
|
|
2183
|
+
error,
|
|
2184
|
+
errorMessage
|
|
2185
|
+
});
|
|
2186
|
+
}
|
|
1958
2187
|
);
|
|
1959
2188
|
utils.addMethod(
|
|
1960
|
-
chai.
|
|
1961
|
-
"
|
|
1962
|
-
(
|
|
2189
|
+
chai.Assertion.prototype,
|
|
2190
|
+
"toThrowErrorMatchingSnapshot",
|
|
2191
|
+
function(message) {
|
|
2192
|
+
const expected = utils.flag(this, "object");
|
|
2193
|
+
const test = utils.flag(this, "vitest-test");
|
|
2194
|
+
const promise = utils.flag(this, "promise");
|
|
2195
|
+
const errorMessage = utils.flag(this, "message");
|
|
2196
|
+
getSnapshotClient().assert({
|
|
2197
|
+
received: getErrorString(expected, promise),
|
|
2198
|
+
test,
|
|
2199
|
+
message,
|
|
2200
|
+
errorMessage
|
|
2201
|
+
});
|
|
2202
|
+
}
|
|
1963
2203
|
);
|
|
1964
2204
|
utils.addMethod(
|
|
1965
|
-
chai.
|
|
1966
|
-
"
|
|
1967
|
-
(
|
|
2205
|
+
chai.Assertion.prototype,
|
|
2206
|
+
"toThrowErrorMatchingInlineSnapshot",
|
|
2207
|
+
function __VITEST_INLINE_SNAPSHOT__(inlineSnapshot, message) {
|
|
2208
|
+
const expected = utils.flag(this, "object");
|
|
2209
|
+
const error = utils.flag(this, "error");
|
|
2210
|
+
const test = utils.flag(this, "vitest-test");
|
|
2211
|
+
const promise = utils.flag(this, "promise");
|
|
2212
|
+
const errorMessage = utils.flag(this, "message");
|
|
2213
|
+
getSnapshotClient().assert({
|
|
2214
|
+
received: getErrorString(expected, promise),
|
|
2215
|
+
test,
|
|
2216
|
+
message,
|
|
2217
|
+
inlineSnapshot,
|
|
2218
|
+
isInline: true,
|
|
2219
|
+
error,
|
|
2220
|
+
errorMessage
|
|
2221
|
+
});
|
|
2222
|
+
}
|
|
1968
2223
|
);
|
|
1969
2224
|
utils.addMethod(
|
|
1970
2225
|
chai.expect,
|
|
1971
|
-
"
|
|
1972
|
-
|
|
2226
|
+
"addSnapshotSerializer",
|
|
2227
|
+
addSerializer
|
|
1973
2228
|
);
|
|
1974
|
-
chai.expect.not = {
|
|
1975
|
-
stringContaining: (expected) => new StringContaining(expected, true),
|
|
1976
|
-
objectContaining: (expected) => new ObjectContaining(expected, true),
|
|
1977
|
-
arrayContaining: (expected) => new ArrayContaining(expected, true),
|
|
1978
|
-
stringMatching: (expected) => new StringMatching(expected, true)
|
|
1979
|
-
};
|
|
1980
2229
|
};
|
|
1981
2230
|
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
const jestUtils = {
|
|
1988
|
-
...matcherUtils,
|
|
1989
|
-
iterableEquality,
|
|
1990
|
-
subsetEquality
|
|
1991
|
-
};
|
|
1992
|
-
const matcherState = {
|
|
1993
|
-
...getState(expect),
|
|
1994
|
-
isNot,
|
|
1995
|
-
utils: jestUtils,
|
|
1996
|
-
promise,
|
|
1997
|
-
equals,
|
|
1998
|
-
suppressedErrors: [],
|
|
1999
|
-
snapshotState: getSnapshotClient().snapshotState
|
|
2000
|
-
};
|
|
2001
|
-
return {
|
|
2002
|
-
state: matcherState,
|
|
2003
|
-
isNot,
|
|
2004
|
-
obj
|
|
2005
|
-
};
|
|
2006
|
-
};
|
|
2007
|
-
class JestExtendError extends Error {
|
|
2008
|
-
constructor(message, actual, expected) {
|
|
2009
|
-
super(message);
|
|
2010
|
-
this.actual = actual;
|
|
2011
|
-
this.expected = expected;
|
|
2012
|
-
}
|
|
2013
|
-
}
|
|
2014
|
-
function JestExtendPlugin(expect, matchers) {
|
|
2015
|
-
return (c, utils) => {
|
|
2016
|
-
Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
|
|
2017
|
-
function expectSyncWrapper(...args) {
|
|
2018
|
-
const { state, isNot, obj } = getMatcherState(this, expect);
|
|
2019
|
-
const { pass, message, actual, expected } = expectAssertion.call(state, obj, ...args);
|
|
2020
|
-
if (pass && isNot || !pass && !isNot)
|
|
2021
|
-
throw new JestExtendError(message(), actual, expected);
|
|
2022
|
-
}
|
|
2023
|
-
async function expectAsyncWrapper(...args) {
|
|
2024
|
-
const { state, isNot, obj } = getMatcherState(this, expect);
|
|
2025
|
-
const { pass, message, actual, expected } = await expectAssertion.call(state, obj, ...args);
|
|
2026
|
-
if (pass && isNot || !pass && !isNot)
|
|
2027
|
-
throw new JestExtendError(message(), actual, expected);
|
|
2028
|
-
}
|
|
2029
|
-
const expectAssertionWrapper = isAsyncFunction(expectAssertion) ? expectAsyncWrapper : expectSyncWrapper;
|
|
2030
|
-
utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, expectAssertionWrapper);
|
|
2031
|
-
utils.addMethod(c.Assertion.prototype, expectAssertionName, expectAssertionWrapper);
|
|
2032
|
-
class CustomMatcher extends AsymmetricMatcher {
|
|
2033
|
-
constructor(inverse = false, ...sample) {
|
|
2034
|
-
super(sample, inverse);
|
|
2035
|
-
}
|
|
2036
|
-
asymmetricMatch(other) {
|
|
2037
|
-
const { pass } = expectAssertion.call(
|
|
2038
|
-
this.getMatcherContext(expect),
|
|
2039
|
-
other,
|
|
2040
|
-
...this.sample
|
|
2041
|
-
);
|
|
2042
|
-
return this.inverse ? !pass : pass;
|
|
2043
|
-
}
|
|
2044
|
-
toString() {
|
|
2045
|
-
return `${this.inverse ? "not." : ""}${expectAssertionName}`;
|
|
2046
|
-
}
|
|
2047
|
-
getExpectedType() {
|
|
2048
|
-
return "any";
|
|
2049
|
-
}
|
|
2050
|
-
toAsymmetricMatcher() {
|
|
2051
|
-
return `${this.toString()}<${this.sample.map(String).join(", ")}>`;
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
Object.defineProperty(expect, expectAssertionName, {
|
|
2055
|
-
configurable: true,
|
|
2056
|
-
enumerable: true,
|
|
2057
|
-
value: (...sample) => new CustomMatcher(false, ...sample),
|
|
2058
|
-
writable: true
|
|
2059
|
-
});
|
|
2060
|
-
Object.defineProperty(expect.not, expectAssertionName, {
|
|
2061
|
-
configurable: true,
|
|
2062
|
-
enumerable: true,
|
|
2063
|
-
value: (...sample) => new CustomMatcher(true, ...sample),
|
|
2064
|
-
writable: true
|
|
2065
|
-
});
|
|
2066
|
-
});
|
|
2067
|
-
};
|
|
2068
|
-
}
|
|
2069
|
-
const JestExtend = (chai, utils) => {
|
|
2070
|
-
utils.addMethod(chai.expect, "extend", (expect, expects) => {
|
|
2071
|
-
chai.use(JestExtendPlugin(expect, expects));
|
|
2072
|
-
});
|
|
2073
|
-
};
|
|
2231
|
+
var chai$1 = /*#__PURE__*/Object.freeze({
|
|
2232
|
+
__proto__: null,
|
|
2233
|
+
getSnapshotClient: getSnapshotClient,
|
|
2234
|
+
SnapshotPlugin: SnapshotPlugin
|
|
2235
|
+
});
|
|
2074
2236
|
|
|
2075
2237
|
chai$2.use(JestExtend);
|
|
2076
2238
|
chai$2.use(JestChaiExpect);
|
|
@@ -2092,15 +2254,17 @@ function createExpect(test) {
|
|
|
2092
2254
|
Object.assign(expect, chai$2.expect);
|
|
2093
2255
|
expect.getState = () => getState(expect);
|
|
2094
2256
|
expect.setState = (state) => setState(state, expect);
|
|
2257
|
+
const globalState = getState(globalThis[GLOBAL_EXPECT]) || {};
|
|
2095
2258
|
setState({
|
|
2259
|
+
...globalState,
|
|
2096
2260
|
assertionCalls: 0,
|
|
2097
2261
|
isExpectingAssertions: false,
|
|
2098
2262
|
isExpectingAssertionsError: null,
|
|
2099
2263
|
expectedAssertionsNumber: null,
|
|
2100
2264
|
expectedAssertionsNumberErrorGen: null,
|
|
2101
2265
|
environment: getCurrentEnvironment(),
|
|
2102
|
-
testPath:
|
|
2103
|
-
currentTestName: test ? getFullName(test) :
|
|
2266
|
+
testPath: test ? (_a = test.suite.file) == null ? void 0 : _a.filepath : globalState.testPath,
|
|
2267
|
+
currentTestName: test ? getFullName(test) : globalState.currentTestName
|
|
2104
2268
|
}, expect);
|
|
2105
2269
|
expect.extend = (matchers) => chai$2.expect.extend(expect, matchers);
|
|
2106
2270
|
function assertions(expected) {
|
|
@@ -2408,7 +2572,7 @@ function formatTitle(template, items, idx) {
|
|
|
2408
2572
|
}
|
|
2409
2573
|
const count = template.split("%").length - 1;
|
|
2410
2574
|
let formatted = util$1.format(template, ...items.slice(0, count));
|
|
2411
|
-
if (isObject(items[0])) {
|
|
2575
|
+
if (isObject$1(items[0])) {
|
|
2412
2576
|
formatted = formatted.replace(
|
|
2413
2577
|
/\$([$\w_.]+)/g,
|
|
2414
2578
|
(_, key) => util.objDisplay(objectAttr(items[0], key))
|
|
@@ -2428,4 +2592,4 @@ function formatTemplateString(cases, args) {
|
|
|
2428
2592
|
return res;
|
|
2429
2593
|
}
|
|
2430
2594
|
|
|
2431
|
-
export { GLOBAL_EXPECT as G, getDefaultHookTimeout as a, bench as b, createExpect as c, describe as d, globalExpect as e, clearCollectorContext as f, getCurrentSuite as g, defaultSuite as h, it as i, setHooks as j, getHooks as k, collectorContext as l, getBenchOptions as m, getFn as n, setState as o,
|
|
2595
|
+
export { GLOBAL_EXPECT as G, getDefaultHookTimeout as a, bench as b, createExpect as c, describe as d, globalExpect as e, clearCollectorContext as f, getCurrentSuite as g, defaultSuite as h, it as i, setHooks as j, getHooks as k, collectorContext as l, getBenchOptions as m, getFn as n, setState as o, getSnapshotClient as p, getState as q, createSuiteHooks as r, suite as s, test as t, chai$1 as u, withTimeout as w };
|