vitest 0.26.3 → 0.27.0

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.
Files changed (39) hide show
  1. package/LICENSE.md +2 -54
  2. package/dist/browser.d.ts +3 -3
  3. package/dist/browser.js +15 -15
  4. package/dist/{chunk-api-setup.47a09f0f.js → chunk-api-setup.16ac28c0.js} +9 -4
  5. package/dist/{chunk-integrations-coverage.befed097.js → chunk-integrations-coverage.44413252.js} +19 -1
  6. package/dist/chunk-integrations-globals.3dfaeb99.js +27 -0
  7. package/dist/{chunk-typecheck-constants.06e1fe5b.js → chunk-mock-date.a1c85759.js} +9 -27
  8. package/dist/{chunk-node-git.a90c0582.js → chunk-node-git.543e964a.js} +1 -2
  9. package/dist/{chunk-runtime-chain.f51aa930.js → chunk-runtime-chain.6df5a66b.js} +1191 -1027
  10. package/dist/{chunk-runtime-error.f5c8aaf2.js → chunk-runtime-error.fad2c32b.js} +2 -2
  11. package/dist/{chunk-runtime-mocker.887bf8c8.js → chunk-runtime-mocker.a677dd28.js} +8 -6
  12. package/dist/{chunk-runtime-rpc.54d72169.js → chunk-runtime-rpc.7f83c8a9.js} +2 -2
  13. package/dist/{chunk-runtime-setup.a06d5c72.js → chunk-runtime-setup.731b2b04.js} +51 -52
  14. package/dist/{chunk-snapshot-manager.70695b70.js → chunk-snapshot-manager.700322bf.js} +408 -272
  15. package/dist/{chunk-utils-env.3fdc1793.js → chunk-utils-env.b861e3a0.js} +1 -63
  16. package/dist/{chunk-utils-import.e7f64637.js → chunk-utils-import.2baa69a9.js} +22 -8
  17. package/dist/chunk-utils-source-map.60562959.js +408 -0
  18. package/dist/{chunk-utils-timers.715da787.js → chunk-utils-timers.52534f96.js} +2977 -3458
  19. package/dist/cli-wrapper.js +11 -11
  20. package/dist/cli.js +12 -624
  21. package/dist/config.cjs +2 -1
  22. package/dist/config.d.ts +1 -1
  23. package/dist/config.js +2 -1
  24. package/dist/entry.js +14 -14
  25. package/dist/environments.d.ts +1 -1
  26. package/dist/{index-761e769b.d.ts → index-2d10c3fd.d.ts} +1 -1
  27. package/dist/index.d.ts +4 -4
  28. package/dist/index.js +12 -12
  29. package/dist/loader.js +3 -3
  30. package/dist/node.d.ts +2 -2
  31. package/dist/node.js +8 -8
  32. package/dist/spy.js +2 -102
  33. package/dist/suite.js +10 -10
  34. package/dist/{types-bae746aa.d.ts → types-e1e1d1e5.d.ts} +88 -76
  35. package/dist/vendor-index.723a074f.js +102 -0
  36. package/dist/worker.js +7 -7
  37. package/package.json +9 -5
  38. package/dist/chunk-integrations-globals.ee28730b.js +0 -27
  39. package/dist/chunk-utils-source-map.5278ee22.js +0 -86
@@ -1,15 +1,16 @@
1
1
  import util$1 from 'util';
2
2
  import * as chai$2 from 'chai';
3
- import { expect, AssertionError, util } from 'chai';
4
- import { i as isObject, b as getCallLastIndex, s as slash, g as getWorkerState, c as getNames, d as assertTypes, e as getCurrentEnvironment, f as getFullName, o as objectAttr, n as noop, h as isRunningInTest, j as isRunningInBenchmark } from './chunk-typecheck-constants.06e1fe5b.js';
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.a1c85759.js';
5
5
  import { c as commonjsGlobal } from './vendor-_commonjsHelpers.addc3445.js';
6
- import { r as rpc } from './chunk-runtime-rpc.54d72169.js';
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.60562959.js';
10
+ import { r as rpc } from './chunk-runtime-rpc.7f83c8a9.js';
7
11
  import fs from 'node:fs';
8
- import { j as join, d as dirname, p as picocolors } from './chunk-utils-env.3fdc1793.js';
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.b861e3a0.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
- var naturalCompare$1 = {exports: {}};
383
-
384
- /*
385
- * @version 1.4.0
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
- return `[MockFunction${nameString}]${callsString}`;
448
- };
449
- const test$1 = (val) => val && !!val._isMockFunction;
450
- const plugin = { serialize: serialize$1, test: test$1 };
451
-
452
- const {
453
- DOMCollection,
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
- function printBacktickString(str) {
520
- return `\`${escapeBacktickString(str)}\``;
521
- }
522
- function ensureDirectoryExists(filePath) {
523
- try {
524
- fs.mkdirSync(join(dirname(filePath)), { recursive: true });
525
- } catch {
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
- function normalizeNewlines(string) {
529
- return string.replace(/\r\n|\r/g, "\n");
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
- const startIndent = findStartIndent();
561
- let expectedTrimmed = expected == null ? void 0 : expected.trim();
562
- if (startIndent) {
563
- expectedTrimmed = expectedTrimmed == null ? void 0 : expectedTrimmed.replace(new RegExp(`^${" ".repeat(startIndent)}`, "gm"), "").replace(/ +}$/, "}");
615
+ toString() {
616
+ return "Anything";
617
+ }
618
+ toAsymmetricMatcher() {
619
+ return "Anything";
564
620
  }
565
- return expectedTrimmed;
566
621
  }
567
- function deepMergeArray(target = [], source = []) {
568
- const mergedOutput = Array.from(target);
569
- source.forEach((sourceElement, index) => {
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
- const indentation = match[1];
674
- const lines = inlineSnapshot.split(/\n/g);
675
- if (lines.length <= 2) {
676
- return inlineSnapshot;
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
- if (lines[0].trim() !== "" || lines[lines.length - 1].trim() !== "") {
679
- return inlineSnapshot;
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
- for (let i = 1; i < lines.length - 1; i++) {
682
- if (lines[i] !== "") {
683
- if (lines[i].indexOf(indentation) !== 0) {
684
- return inlineSnapshot;
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
- lines[lines.length - 1] = "";
690
- inlineSnapshot = lines.join("\n");
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
- markSnapshotsAsCheckedForTest(testName) {
720
- this._uncheckedKeys.forEach((uncheckedKey) => {
721
- if (keyToTestName(uncheckedKey) === testName)
722
- this._uncheckedKeys.delete(uncheckedKey);
723
- });
658
+ getExpectedType() {
659
+ return "object";
724
660
  }
725
- _inferInlineSnapshotStack(stacks) {
726
- const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/));
727
- if (promiseIndex !== -1)
728
- return stacks[promiseIndex + 3];
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
- _addSnapshot(key, receivedSerialized, options) {
733
- this._dirty = true;
734
- if (options.isInline) {
735
- const error = options.error || new Error("Unknown error");
736
- const stacks = parseStacktrace(error, true);
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
- clear() {
755
- this._snapshotData = this._initialData;
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
- async save() {
764
- const hasExternalSnapshots = Object.keys(this._snapshotData).length;
765
- const hasInlineSnapshots = this._inlineSnapshots.length;
766
- const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots;
767
- const status = {
768
- deleted: false,
769
- saved: false
770
- };
771
- if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) {
772
- if (hasExternalSnapshots)
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
- return status;
691
+ super(sample);
783
692
  }
784
- getUncheckedCount() {
785
- return this._uncheckedKeys.size || 0;
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
- getUncheckedKeys() {
788
- return Array.from(this._uncheckedKeys);
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
- removeUncheckedKeys() {
791
- if (this._updateSnapshot === "all" && this._uncheckedKeys.size) {
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
- match({
798
- testName,
799
- received,
800
- key,
801
- inlineSnapshot,
802
- isInline,
803
- error
804
- }) {
805
- this._counters.set(testName, (this._counters.get(testName) || 0) + 1);
806
- const count = Number(this._counters.get(testName));
807
- if (!key)
808
- key = testNameToKey(testName, count);
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
- async pack() {
865
- const snapshot = {
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
- class SnapshotClient {
892
- constructor() {
893
- this.snapshotStateMap = /* @__PURE__ */ new Map();
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
- assert(options) {
925
- const {
926
- test = this.test,
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
- async saveCurrent() {
973
- if (!this.snapshotState)
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
- clear() {
980
- this.snapshotStateMap.clear();
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.Assertion.prototype,
1034
- "toMatchInlineSnapshot",
1035
- function __VITEST_INLINE_SNAPSHOT__(properties, inlineSnapshot, message) {
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.Assertion.prototype,
1061
- "toThrowErrorMatchingSnapshot",
1062
- function(message) {
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.Assertion.prototype,
1077
- "toThrowErrorMatchingInlineSnapshot",
1078
- function __VITEST_INLINE_SNAPSHOT__(inlineSnapshot, message) {
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
- var chai$1 = /*#__PURE__*/Object.freeze({
1098
- __proto__: null,
1099
- getSnapshotClient: getSnapshotClient,
1100
- SnapshotPlugin: SnapshotPlugin
1101
- });
1102
-
1103
- const GLOBAL_EXPECT = Symbol.for("expect-global");
1104
- const MATCHERS_OBJECT = Symbol.for("matchers-object");
1105
- const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
1106
-
1107
- if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
1108
- const globalState = /* @__PURE__ */ new WeakMap();
1109
- const matchers = /* @__PURE__ */ Object.create(null);
1110
- Object.defineProperty(globalThis, MATCHERS_OBJECT, {
1111
- get: () => globalState
1112
- });
1113
- Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
1114
- configurable: true,
1115
- get: () => ({
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 += picocolors.exports.gray(`
1097
+ msg += c.gray(`
1434
1098
 
1435
1099
  Received:
1436
1100
  ${spy.mock.calls.map((callArg, i) => {
1437
- let methodCall = picocolors.exports.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
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 += picocolors.exports.gray(`
1111
+ msg += c.gray(`
1448
1112
 
1449
- Number of calls: ${picocolors.exports.bold(spy.mock.calls.length)}
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 += picocolors.exports.gray(`
1118
+ msg += c.gray(`
1455
1119
 
1456
1120
  Received:
1457
1121
  ${spy.mock.results.map((callReturn, i) => {
1458
- let methodCall = picocolors.exports.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
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 += picocolors.exports.gray(`
1132
+ msg += c.gray(`
1469
1133
 
1470
- Number of calls: ${picocolors.exports.bold(spy.mock.calls.length)}
1134
+ Number of calls: ${c.bold(spy.mock.calls.length)}
1471
1135
  `);
1472
1136
  return msg;
1473
1137
  };
@@ -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 "${toString(err)}" instead of resolving`);
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 "${toString(value)}" instead of rejecting`);
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 proxy;
1753
- });
1754
- utils.addMethod(
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
- class AsymmetricMatcher {
1769
- constructor(sample, inverse = false) {
1770
- this.sample = sample;
1771
- this.inverse = inverse;
1772
- this.$$typeof = Symbol.for("jest.asymmetricMatcher");
1773
- }
1774
- getMatcherContext(expect) {
1775
- return {
1776
- ...getState(expect || globalThis[GLOBAL_EXPECT]),
1777
- equals,
1778
- isNot: this.inverse,
1779
- utils: matcherUtils
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
- class StringContaining extends AsymmetricMatcher {
1784
- constructor(sample, inverse = false) {
1785
- if (!isA("String", sample))
1786
- throw new Error("Expected is not a string");
1787
- super(sample, inverse);
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
- asymmetricMatch(other) {
1790
- const result = isA("String", other) && other.includes(this.sample);
1791
- return this.inverse ? !result : result;
1802
+ const indentation = match[1];
1803
+ const lines = inlineSnapshot.split(/\n/g);
1804
+ if (lines.length <= 2) {
1805
+ return inlineSnapshot;
1792
1806
  }
1793
- toString() {
1794
- return `String${this.inverse ? "Not" : ""}Containing`;
1807
+ if (lines[0].trim() !== "" || lines[lines.length - 1].trim() !== "") {
1808
+ return inlineSnapshot;
1795
1809
  }
1796
- getExpectedType() {
1797
- return "string";
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
- class Anything extends AsymmetricMatcher {
1801
- asymmetricMatch(other) {
1802
- return other != null;
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
- toString() {
1805
- return "Anything";
1848
+ markSnapshotsAsCheckedForTest(testName) {
1849
+ this._uncheckedKeys.forEach((uncheckedKey) => {
1850
+ if (keyToTestName(uncheckedKey) === testName)
1851
+ this._uncheckedKeys.delete(uncheckedKey);
1852
+ });
1806
1853
  }
1807
- toAsymmetricMatcher() {
1808
- return "Anything";
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
- class ObjectContaining extends AsymmetricMatcher {
1812
- constructor(sample, inverse = false) {
1813
- super(sample, inverse);
1913
+ getUncheckedCount() {
1914
+ return this._uncheckedKeys.size || 0;
1814
1915
  }
1815
- getPrototype(obj) {
1816
- if (Object.getPrototypeOf)
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
- hasProperty(obj, property) {
1823
- if (!obj)
1824
- return false;
1825
- if (Object.prototype.hasOwnProperty.call(obj, property))
1826
- return true;
1827
- return this.hasProperty(this.getPrototype(obj), property);
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
- asymmetricMatch(other) {
1830
- if (typeof this.sample !== "object") {
1831
- throw new TypeError(
1832
- `You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`
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
- let result = true;
1836
- for (const property in this.sample) {
1837
- if (!this.hasProperty(other, property) || !equals(this.sample[property], other[property])) {
1838
- result = false;
1839
- break;
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
- getExpectedType() {
1848
- return "object";
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
- class ArrayContaining extends AsymmetricMatcher {
1852
- constructor(sample, inverse = false) {
1853
- super(sample, inverse);
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
- class Any extends AsymmetricMatcher {
1874
- constructor(sample) {
1875
- if (typeof sample === "undefined") {
1876
- throw new TypeError(
1877
- "any() expects to be passed a constructor function. Please pass one or use anything() to match any object."
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
- fnNameFor(func) {
1883
- if (func.name)
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
- asymmetricMatch(other) {
1890
- if (this.sample === String)
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
- toString() {
1907
- return "Any";
2049
+ skipTestSnapshots(test) {
2050
+ var _a;
2051
+ (_a = this.snapshotState) == null ? void 0 : _a.markSnapshotsAsCheckedForTest(test.name);
1908
2052
  }
1909
- getExpectedType() {
1910
- if (this.sample === String)
1911
- return "string";
1912
- if (this.sample === Number)
1913
- return "number";
1914
- if (this.sample === Function)
1915
- return "function";
1916
- if (this.sample === Object)
1917
- return "object";
1918
- if (this.sample === Boolean)
1919
- return "boolean";
1920
- return this.fnNameFor(this.sample);
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
- toAsymmetricMatcher() {
1923
- return `Any<${this.fnNameFor(this.sample)}>`;
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
- class StringMatching extends AsymmetricMatcher {
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
- asymmetricMatch(other) {
1933
- const result = isA("String", other) && this.sample.test(other);
1934
- return this.inverse ? !result : result;
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
- toString() {
1937
- return `String${this.inverse ? "Not" : ""}Matching`;
2130
+ try {
2131
+ expected();
2132
+ } catch (e) {
2133
+ return getErrorMessage(e);
1938
2134
  }
1939
- getExpectedType() {
1940
- return "string";
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.expect,
1956
- "stringContaining",
1957
- (expected) => new StringContaining(expected)
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.expect,
1961
- "objectContaining",
1962
- (expected) => new ObjectContaining(expected)
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.expect,
1966
- "arrayContaining",
1967
- (expected) => new ArrayContaining(expected)
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
- "stringMatching",
1972
- (expected) => new StringMatching(expected)
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
- const isAsyncFunction = (fn) => typeof fn === "function" && fn[Symbol.toStringTag] === "AsyncFunction";
1983
- const getMatcherState = (assertion, expect) => {
1984
- const obj = assertion._obj;
1985
- const isNot = util.flag(assertion, "negate");
1986
- const promise = util.flag(assertion, "promise") || "";
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: (_a = test == null ? void 0 : test.suite.file) == null ? void 0 : _a.filepath,
2103
- currentTestName: test ? getFullName(test) : void 0
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, getState as p, createSuiteHooks as q, chai$1 as r, suite as s, test as t, withTimeout as w };
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 };