@vitest/snapshot 3.1.0-beta.1 → 3.1.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.
- package/dist/environment.js +33 -36
- package/dist/index.js +899 -998
- package/dist/manager.js +63 -66
- package/package.json +3 -3
package/dist/index.js
CHANGED
@@ -577,221 +577,238 @@ function traceSegmentInternal(segments, memo, line, column, bias) {
|
|
577
577
|
return index;
|
578
578
|
}
|
579
579
|
|
580
|
+
/**
|
581
|
+
* Get original stacktrace without source map support the most performant way.
|
582
|
+
* - Create only 1 stack frame.
|
583
|
+
* - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms).
|
584
|
+
*/
|
580
585
|
function notNullish(v) {
|
581
|
-
|
586
|
+
return v != null;
|
582
587
|
}
|
583
588
|
function isPrimitive(value) {
|
584
|
-
|
589
|
+
return value === null || typeof value !== "function" && typeof value !== "object";
|
585
590
|
}
|
586
591
|
function isObject(item) {
|
587
|
-
|
592
|
+
return item != null && typeof item === "object" && !Array.isArray(item);
|
588
593
|
}
|
594
|
+
/**
|
595
|
+
* If code starts with a function call, will return its last index, respecting arguments.
|
596
|
+
* This will return 25 - last ending character of toMatch ")"
|
597
|
+
* Also works with callbacks
|
598
|
+
* ```
|
599
|
+
* toMatch({ test: '123' });
|
600
|
+
* toBeAliased('123')
|
601
|
+
* ```
|
602
|
+
*/
|
589
603
|
function getCallLastIndex(code) {
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
604
|
+
let charIndex = -1;
|
605
|
+
let inString = null;
|
606
|
+
let startedBracers = 0;
|
607
|
+
let endedBracers = 0;
|
608
|
+
let beforeChar = null;
|
609
|
+
while (charIndex <= code.length) {
|
610
|
+
beforeChar = code[charIndex];
|
611
|
+
charIndex++;
|
612
|
+
const char = code[charIndex];
|
613
|
+
const isCharString = char === "\"" || char === "'" || char === "`";
|
614
|
+
if (isCharString && beforeChar !== "\\") {
|
615
|
+
if (inString === char) {
|
616
|
+
inString = null;
|
617
|
+
} else if (!inString) {
|
618
|
+
inString = char;
|
619
|
+
}
|
620
|
+
}
|
621
|
+
if (!inString) {
|
622
|
+
if (char === "(") {
|
623
|
+
startedBracers++;
|
624
|
+
}
|
625
|
+
if (char === ")") {
|
626
|
+
endedBracers++;
|
627
|
+
}
|
628
|
+
}
|
629
|
+
if (startedBracers && endedBracers && startedBracers === endedBracers) {
|
630
|
+
return charIndex;
|
631
|
+
}
|
632
|
+
}
|
633
|
+
return null;
|
620
634
|
}
|
621
635
|
|
622
636
|
const CHROME_IE_STACK_REGEXP = /^\s*at .*(?:\S:\d+|\(native\))/m;
|
623
637
|
const SAFARI_NATIVE_CODE_REGEXP = /^(?:eval@)?(?:\[native code\])?$/;
|
624
638
|
const stackIgnorePatterns = [
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
/\/deps\/vitest_/
|
639
|
+
"node:internal",
|
640
|
+
/\/packages\/\w+\/dist\//,
|
641
|
+
/\/@vitest\/\w+\/dist\//,
|
642
|
+
"/vitest/dist/",
|
643
|
+
"/vitest/src/",
|
644
|
+
"/vite-node/dist/",
|
645
|
+
"/vite-node/src/",
|
646
|
+
"/node_modules/chai/",
|
647
|
+
"/node_modules/tinypool/",
|
648
|
+
"/node_modules/tinyspy/",
|
649
|
+
"/deps/chunk-",
|
650
|
+
"/deps/@vitest",
|
651
|
+
"/deps/loupe",
|
652
|
+
"/deps/chai",
|
653
|
+
/node:\w+/,
|
654
|
+
/__vitest_test__/,
|
655
|
+
/__vitest_browser__/,
|
656
|
+
/\/deps\/vitest_/
|
644
657
|
];
|
645
658
|
function extractLocation(urlLike) {
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
659
|
+
if (!urlLike.includes(":")) {
|
660
|
+
return [urlLike];
|
661
|
+
}
|
662
|
+
const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
|
663
|
+
const parts = regExp.exec(urlLike.replace(/^\(|\)$/g, ""));
|
664
|
+
if (!parts) {
|
665
|
+
return [urlLike];
|
666
|
+
}
|
667
|
+
let url = parts[1];
|
668
|
+
if (url.startsWith("async ")) {
|
669
|
+
url = url.slice(6);
|
670
|
+
}
|
671
|
+
if (url.startsWith("http:") || url.startsWith("https:")) {
|
672
|
+
const urlObj = new URL(url);
|
673
|
+
urlObj.searchParams.delete("import");
|
674
|
+
urlObj.searchParams.delete("browserv");
|
675
|
+
url = urlObj.pathname + urlObj.hash + urlObj.search;
|
676
|
+
}
|
677
|
+
if (url.startsWith("/@fs/")) {
|
678
|
+
const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url);
|
679
|
+
url = url.slice(isWindows ? 5 : 4);
|
680
|
+
}
|
681
|
+
return [
|
682
|
+
url,
|
683
|
+
parts[2] || undefined,
|
684
|
+
parts[3] || undefined
|
685
|
+
];
|
669
686
|
}
|
670
687
|
function parseSingleFFOrSafariStack(raw) {
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
file: url,
|
695
|
-
method: functionName || "",
|
696
|
-
line: Number.parseInt(lineNumber),
|
697
|
-
column: Number.parseInt(columnNumber)
|
698
|
-
};
|
688
|
+
let line = raw.trim();
|
689
|
+
if (SAFARI_NATIVE_CODE_REGEXP.test(line)) {
|
690
|
+
return null;
|
691
|
+
}
|
692
|
+
if (line.includes(" > eval")) {
|
693
|
+
line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1");
|
694
|
+
}
|
695
|
+
if (!line.includes("@") && !line.includes(":")) {
|
696
|
+
return null;
|
697
|
+
}
|
698
|
+
const functionNameRegex = /((.*".+"[^@]*)?[^@]*)(@)/;
|
699
|
+
const matches = line.match(functionNameRegex);
|
700
|
+
const functionName = matches && matches[1] ? matches[1] : undefined;
|
701
|
+
const [url, lineNumber, columnNumber] = extractLocation(line.replace(functionNameRegex, ""));
|
702
|
+
if (!url || !lineNumber || !columnNumber) {
|
703
|
+
return null;
|
704
|
+
}
|
705
|
+
return {
|
706
|
+
file: url,
|
707
|
+
method: functionName || "",
|
708
|
+
line: Number.parseInt(lineNumber),
|
709
|
+
column: Number.parseInt(columnNumber)
|
710
|
+
};
|
699
711
|
}
|
700
712
|
function parseSingleV8Stack(raw) {
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
column: Number.parseInt(columnNumber)
|
734
|
-
};
|
713
|
+
let line = raw.trim();
|
714
|
+
if (!CHROME_IE_STACK_REGEXP.test(line)) {
|
715
|
+
return null;
|
716
|
+
}
|
717
|
+
if (line.includes("(eval ")) {
|
718
|
+
line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, "");
|
719
|
+
}
|
720
|
+
let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, "");
|
721
|
+
const location = sanitizedLine.match(/ (\(.+\)$)/);
|
722
|
+
sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine;
|
723
|
+
const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine);
|
724
|
+
let method = location && sanitizedLine || "";
|
725
|
+
let file = url && ["eval", "<anonymous>"].includes(url) ? undefined : url;
|
726
|
+
if (!file || !lineNumber || !columnNumber) {
|
727
|
+
return null;
|
728
|
+
}
|
729
|
+
if (method.startsWith("async ")) {
|
730
|
+
method = method.slice(6);
|
731
|
+
}
|
732
|
+
if (file.startsWith("file://")) {
|
733
|
+
file = file.slice(7);
|
734
|
+
}
|
735
|
+
file = file.startsWith("node:") || file.startsWith("internal:") ? file : resolve$2(file);
|
736
|
+
if (method) {
|
737
|
+
method = method.replace(/__vite_ssr_import_\d+__\./g, "");
|
738
|
+
}
|
739
|
+
return {
|
740
|
+
method,
|
741
|
+
file,
|
742
|
+
line: Number.parseInt(lineNumber),
|
743
|
+
column: Number.parseInt(columnNumber)
|
744
|
+
};
|
735
745
|
}
|
736
746
|
function parseStacktrace(stack, options = {}) {
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
747
|
+
const { ignoreStackEntries = stackIgnorePatterns } = options;
|
748
|
+
const stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack);
|
749
|
+
return stacks.map((stack) => {
|
750
|
+
var _options$getSourceMap;
|
751
|
+
if (options.getUrlId) {
|
752
|
+
stack.file = options.getUrlId(stack.file);
|
753
|
+
}
|
754
|
+
const map = (_options$getSourceMap = options.getSourceMap) === null || _options$getSourceMap === void 0 ? void 0 : _options$getSourceMap.call(options, stack.file);
|
755
|
+
if (!map || typeof map !== "object" || !map.version) {
|
756
|
+
return shouldFilter(ignoreStackEntries, stack.file) ? null : stack;
|
757
|
+
}
|
758
|
+
const traceMap = new TraceMap(map);
|
759
|
+
const { line, column, source, name } = originalPositionFor(traceMap, stack);
|
760
|
+
let file = stack.file;
|
761
|
+
if (source) {
|
762
|
+
const fileUrl = stack.file.startsWith("file://") ? stack.file : `file://${stack.file}`;
|
763
|
+
const sourceRootUrl = map.sourceRoot ? new URL(map.sourceRoot, fileUrl) : fileUrl;
|
764
|
+
file = new URL(source, sourceRootUrl).pathname;
|
765
|
+
}
|
766
|
+
if (shouldFilter(ignoreStackEntries, file)) {
|
767
|
+
return null;
|
768
|
+
}
|
769
|
+
if (line != null && column != null) {
|
770
|
+
return {
|
771
|
+
line,
|
772
|
+
column,
|
773
|
+
file,
|
774
|
+
method: name || stack.method
|
775
|
+
};
|
776
|
+
}
|
777
|
+
return stack;
|
778
|
+
}).filter((s) => s != null);
|
769
779
|
}
|
770
780
|
function shouldFilter(ignoreStackEntries, file) {
|
771
|
-
|
781
|
+
return ignoreStackEntries.some((p) => file.match(p));
|
772
782
|
}
|
773
783
|
function parseFFOrSafariStackTrace(stack) {
|
774
|
-
|
784
|
+
return stack.split("\n").map((line) => parseSingleFFOrSafariStack(line)).filter(notNullish);
|
775
785
|
}
|
776
786
|
function parseV8Stacktrace(stack) {
|
777
|
-
|
787
|
+
return stack.split("\n").map((line) => parseSingleV8Stack(line)).filter(notNullish);
|
778
788
|
}
|
779
789
|
function parseErrorStacktrace(e, options = {}) {
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
790
|
+
if (!e || isPrimitive(e)) {
|
791
|
+
return [];
|
792
|
+
}
|
793
|
+
if (e.stacks) {
|
794
|
+
return e.stacks;
|
795
|
+
}
|
796
|
+
const stackStr = e.stack || e.stackStr || "";
|
797
|
+
let stackFrames = parseStacktrace(stackStr, options);
|
798
|
+
if (!stackFrames.length) {
|
799
|
+
const e_ = e;
|
800
|
+
if (e_.fileName != null && e_.lineNumber != null && e_.columnNumber != null) {
|
801
|
+
stackFrames = parseStacktrace(`${e_.fileName}:${e_.lineNumber}:${e_.columnNumber}`, options);
|
802
|
+
}
|
803
|
+
if (e_.sourceURL != null && e_.line != null && e_._column != null) {
|
804
|
+
stackFrames = parseStacktrace(`${e_.sourceURL}:${e_.line}:${e_.column}`, options);
|
805
|
+
}
|
806
|
+
}
|
807
|
+
if (options.frameFilter) {
|
808
|
+
stackFrames = stackFrames.filter((f) => options.frameFilter(e, f) !== false);
|
809
|
+
}
|
810
|
+
e.stacks = stackFrames;
|
811
|
+
return stackFrames;
|
795
812
|
}
|
796
813
|
|
797
814
|
let getPromiseValue = () => 'Promise{…}';
|
@@ -828,14 +845,7 @@ catch (noNodeInspect) {
|
|
828
845
|
nodeInspect = false;
|
829
846
|
}
|
830
847
|
|
831
|
-
const {
|
832
|
-
AsymmetricMatcher: AsymmetricMatcher$1,
|
833
|
-
DOMCollection: DOMCollection$1,
|
834
|
-
DOMElement: DOMElement$1,
|
835
|
-
Immutable: Immutable$1,
|
836
|
-
ReactElement: ReactElement$1,
|
837
|
-
ReactTestComponent: ReactTestComponent$1
|
838
|
-
} = plugins;
|
848
|
+
const { AsymmetricMatcher: AsymmetricMatcher$1, DOMCollection: DOMCollection$1, DOMElement: DOMElement$1, Immutable: Immutable$1, ReactElement: ReactElement$1, ReactTestComponent: ReactTestComponent$1 } = plugins;
|
839
849
|
|
840
850
|
function getDefaultExportFromCjs (x) {
|
841
851
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
@@ -1374,190 +1384,180 @@ p();
|
|
1374
1384
|
|
1375
1385
|
const lineSplitRE = /\r?\n/;
|
1376
1386
|
function positionToOffset(source, lineNumber, columnNumber) {
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
+
const lines = source.split(lineSplitRE);
|
1388
|
+
const nl = /\r\n/.test(source) ? 2 : 1;
|
1389
|
+
let start = 0;
|
1390
|
+
if (lineNumber > lines.length) {
|
1391
|
+
return source.length;
|
1392
|
+
}
|
1393
|
+
for (let i = 0; i < lineNumber - 1; i++) {
|
1394
|
+
start += lines[i].length + nl;
|
1395
|
+
}
|
1396
|
+
return start + columnNumber;
|
1387
1397
|
}
|
1388
1398
|
function offsetToLineNumber(source, offset) {
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
}
|
1405
|
-
return line + 1;
|
1399
|
+
if (offset > source.length) {
|
1400
|
+
throw new Error(`offset is longer than source length! offset ${offset} > length ${source.length}`);
|
1401
|
+
}
|
1402
|
+
const lines = source.split(lineSplitRE);
|
1403
|
+
const nl = /\r\n/.test(source) ? 2 : 1;
|
1404
|
+
let counted = 0;
|
1405
|
+
let line = 0;
|
1406
|
+
for (; line < lines.length; line++) {
|
1407
|
+
const lineLength = lines[line].length + nl;
|
1408
|
+
if (counted + lineLength >= offset) {
|
1409
|
+
break;
|
1410
|
+
}
|
1411
|
+
counted += lineLength;
|
1412
|
+
}
|
1413
|
+
return line + 1;
|
1406
1414
|
}
|
1407
1415
|
|
1408
1416
|
async function saveInlineSnapshots(environment, snapshots) {
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
})
|
1425
|
-
);
|
1417
|
+
const MagicString = (await import('magic-string')).default;
|
1418
|
+
const files = new Set(snapshots.map((i) => i.file));
|
1419
|
+
await Promise.all(Array.from(files).map(async (file) => {
|
1420
|
+
const snaps = snapshots.filter((i) => i.file === file);
|
1421
|
+
const code = await environment.readSnapshotFile(file);
|
1422
|
+
const s = new MagicString(code);
|
1423
|
+
for (const snap of snaps) {
|
1424
|
+
const index = positionToOffset(code, snap.line, snap.column);
|
1425
|
+
replaceInlineSnap(code, s, index, snap.snapshot);
|
1426
|
+
}
|
1427
|
+
const transformed = s.toString();
|
1428
|
+
if (transformed !== code) {
|
1429
|
+
await environment.saveSnapshotFile(file, transformed);
|
1430
|
+
}
|
1431
|
+
}));
|
1426
1432
|
}
|
1427
1433
|
const startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*\{/;
|
1428
1434
|
function replaceObjectSnap(code, s, index, newSnap) {
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1435
|
+
let _code = code.slice(index);
|
1436
|
+
const startMatch = startObjectRegex.exec(_code);
|
1437
|
+
if (!startMatch) {
|
1438
|
+
return false;
|
1439
|
+
}
|
1440
|
+
_code = _code.slice(startMatch.index);
|
1441
|
+
let callEnd = getCallLastIndex(_code);
|
1442
|
+
if (callEnd === null) {
|
1443
|
+
return false;
|
1444
|
+
}
|
1445
|
+
callEnd += index + startMatch.index;
|
1446
|
+
const shapeStart = index + startMatch.index + startMatch[0].length;
|
1447
|
+
const shapeEnd = getObjectShapeEndIndex(code, shapeStart);
|
1448
|
+
const snap = `, ${prepareSnapString(newSnap, code, index)}`;
|
1449
|
+
if (shapeEnd === callEnd) {
|
1450
|
+
s.appendLeft(callEnd, snap);
|
1451
|
+
} else {
|
1452
|
+
s.overwrite(shapeEnd, callEnd, snap);
|
1453
|
+
}
|
1454
|
+
return true;
|
1449
1455
|
}
|
1450
1456
|
function getObjectShapeEndIndex(code, index) {
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1457
|
+
let startBraces = 1;
|
1458
|
+
let endBraces = 0;
|
1459
|
+
while (startBraces !== endBraces && index < code.length) {
|
1460
|
+
const s = code[index++];
|
1461
|
+
if (s === "{") {
|
1462
|
+
startBraces++;
|
1463
|
+
} else if (s === "}") {
|
1464
|
+
endBraces++;
|
1465
|
+
}
|
1466
|
+
}
|
1467
|
+
return index;
|
1462
1468
|
}
|
1463
1469
|
function prepareSnapString(snap, source, index) {
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}
|
1476
|
-
${indent}${quote}`;
|
1470
|
+
const lineNumber = offsetToLineNumber(source, index);
|
1471
|
+
const line = source.split(lineSplitRE)[lineNumber - 1];
|
1472
|
+
const indent = line.match(/^\s*/)[0] || "";
|
1473
|
+
const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `;
|
1474
|
+
const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
|
1475
|
+
const isOneline = lines.length <= 1;
|
1476
|
+
const quote = "`";
|
1477
|
+
if (isOneline) {
|
1478
|
+
return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\\${")}${quote}`;
|
1479
|
+
}
|
1480
|
+
return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\\${")}\n${indent}${quote}`;
|
1477
1481
|
}
|
1478
1482
|
const toMatchInlineName = "toMatchInlineSnapshot";
|
1479
1483
|
const toThrowErrorMatchingInlineName = "toThrowErrorMatchingInlineSnapshot";
|
1480
1484
|
function getCodeStartingAtIndex(code, index) {
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1485
|
+
const indexInline = index - toMatchInlineName.length;
|
1486
|
+
if (code.slice(indexInline, index) === toMatchInlineName) {
|
1487
|
+
return {
|
1488
|
+
code: code.slice(indexInline),
|
1489
|
+
index: indexInline
|
1490
|
+
};
|
1491
|
+
}
|
1492
|
+
const indexThrowInline = index - toThrowErrorMatchingInlineName.length;
|
1493
|
+
if (code.slice(index - indexThrowInline, index) === toThrowErrorMatchingInlineName) {
|
1494
|
+
return {
|
1495
|
+
code: code.slice(index - indexThrowInline),
|
1496
|
+
index: index - indexThrowInline
|
1497
|
+
};
|
1498
|
+
}
|
1499
|
+
return {
|
1500
|
+
code: code.slice(index),
|
1501
|
+
index
|
1502
|
+
};
|
1499
1503
|
}
|
1500
1504
|
const startRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*[\w$]*(['"`)])/;
|
1501
1505
|
function replaceInlineSnap(code, s, currentIndex, newSnap) {
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
s.overwrite(startIndex - 1, endIndex, snapString);
|
1524
|
-
return true;
|
1506
|
+
const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex);
|
1507
|
+
const startMatch = startRegex.exec(codeStartingAtIndex);
|
1508
|
+
const firstKeywordMatch = /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/.exec(codeStartingAtIndex);
|
1509
|
+
if (!startMatch || startMatch.index !== (firstKeywordMatch === null || firstKeywordMatch === void 0 ? void 0 : firstKeywordMatch.index)) {
|
1510
|
+
return replaceObjectSnap(code, s, index, newSnap);
|
1511
|
+
}
|
1512
|
+
const quote = startMatch[1];
|
1513
|
+
const startIndex = index + startMatch.index + startMatch[0].length;
|
1514
|
+
const snapString = prepareSnapString(newSnap, code, index);
|
1515
|
+
if (quote === ")") {
|
1516
|
+
s.appendRight(startIndex - 1, snapString);
|
1517
|
+
return true;
|
1518
|
+
}
|
1519
|
+
const quoteEndRE = new RegExp(`(?:^|[^\\\\])${quote}`);
|
1520
|
+
const endMatch = quoteEndRE.exec(code.slice(startIndex));
|
1521
|
+
if (!endMatch) {
|
1522
|
+
return false;
|
1523
|
+
}
|
1524
|
+
const endIndex = startIndex + endMatch.index + endMatch[0].length;
|
1525
|
+
s.overwrite(startIndex - 1, endIndex, snapString);
|
1526
|
+
return true;
|
1525
1527
|
}
|
1526
1528
|
const INDENTATION_REGEX = /^([^\S\n]*)\S/m;
|
1527
1529
|
function stripSnapshotIndentation(inlineSnapshot) {
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1530
|
+
const match = inlineSnapshot.match(INDENTATION_REGEX);
|
1531
|
+
if (!match || !match[1]) {
|
1532
|
+
return inlineSnapshot;
|
1533
|
+
}
|
1534
|
+
const indentation = match[1];
|
1535
|
+
const lines = inlineSnapshot.split(/\n/g);
|
1536
|
+
if (lines.length <= 2) {
|
1537
|
+
return inlineSnapshot;
|
1538
|
+
}
|
1539
|
+
if (lines[0].trim() !== "" || lines[lines.length - 1].trim() !== "") {
|
1540
|
+
return inlineSnapshot;
|
1541
|
+
}
|
1542
|
+
for (let i = 1; i < lines.length - 1; i++) {
|
1543
|
+
if (lines[i] !== "") {
|
1544
|
+
if (lines[i].indexOf(indentation) !== 0) {
|
1545
|
+
return inlineSnapshot;
|
1546
|
+
}
|
1547
|
+
lines[i] = lines[i].substring(indentation.length);
|
1548
|
+
}
|
1549
|
+
}
|
1550
|
+
lines[lines.length - 1] = "";
|
1551
|
+
inlineSnapshot = lines.join("\n");
|
1552
|
+
return inlineSnapshot;
|
1551
1553
|
}
|
1552
1554
|
|
1553
1555
|
async function saveRawSnapshots(environment, snapshots) {
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
})
|
1560
|
-
);
|
1556
|
+
await Promise.all(snapshots.map(async (snap) => {
|
1557
|
+
if (!snap.readonly) {
|
1558
|
+
await environment.saveSnapshotFile(snap.file, snap.snapshot);
|
1559
|
+
}
|
1560
|
+
}));
|
1561
1561
|
}
|
1562
1562
|
|
1563
1563
|
var naturalCompare$1 = {exports: {}};
|
@@ -1628,699 +1628,600 @@ var naturalCompareExports = requireNaturalCompare();
|
|
1628
1628
|
var naturalCompare = /*@__PURE__*/getDefaultExportFromCjs(naturalCompareExports);
|
1629
1629
|
|
1630
1630
|
const serialize$1 = (val, config, indentation, depth, refs, printer) => {
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
indentationNext,
|
1640
|
-
depth,
|
1641
|
-
refs
|
1642
|
-
)}${config.min ? ", " : ","}${config.spacingOuter}${indentationNext}"results": ${printer(
|
1643
|
-
val.mock.results,
|
1644
|
-
config,
|
1645
|
-
indentationNext,
|
1646
|
-
depth,
|
1647
|
-
refs
|
1648
|
-
)}${config.min ? "" : ","}${config.spacingOuter}${indentation}}`;
|
1649
|
-
}
|
1650
|
-
return `[MockFunction${nameString}]${callsString}`;
|
1631
|
+
const name = val.getMockName();
|
1632
|
+
const nameString = name === "vi.fn()" ? "" : ` ${name}`;
|
1633
|
+
let callsString = "";
|
1634
|
+
if (val.mock.calls.length !== 0) {
|
1635
|
+
const indentationNext = indentation + config.indent;
|
1636
|
+
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}}`;
|
1637
|
+
}
|
1638
|
+
return `[MockFunction${nameString}]${callsString}`;
|
1651
1639
|
};
|
1652
1640
|
const test = (val) => val && !!val._isMockFunction;
|
1653
|
-
const plugin = {
|
1641
|
+
const plugin = {
|
1642
|
+
serialize: serialize$1,
|
1643
|
+
test
|
1644
|
+
};
|
1654
1645
|
|
1655
|
-
const {
|
1656
|
-
DOMCollection,
|
1657
|
-
DOMElement,
|
1658
|
-
Immutable,
|
1659
|
-
ReactElement,
|
1660
|
-
ReactTestComponent,
|
1661
|
-
AsymmetricMatcher
|
1662
|
-
} = plugins;
|
1646
|
+
const { DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent, AsymmetricMatcher } = plugins;
|
1663
1647
|
let PLUGINS = [
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1648
|
+
ReactTestComponent,
|
1649
|
+
ReactElement,
|
1650
|
+
DOMElement,
|
1651
|
+
DOMCollection,
|
1652
|
+
Immutable,
|
1653
|
+
AsymmetricMatcher,
|
1654
|
+
plugin
|
1671
1655
|
];
|
1672
1656
|
function addSerializer(plugin) {
|
1673
|
-
|
1657
|
+
PLUGINS = [plugin].concat(PLUGINS);
|
1674
1658
|
}
|
1675
1659
|
function getSerializers() {
|
1676
|
-
|
1660
|
+
return PLUGINS;
|
1677
1661
|
}
|
1678
1662
|
|
1679
1663
|
function testNameToKey(testName, count) {
|
1680
|
-
|
1664
|
+
return `${testName} ${count}`;
|
1681
1665
|
}
|
1682
1666
|
function keyToTestName(key) {
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1667
|
+
if (!/ \d+$/.test(key)) {
|
1668
|
+
throw new Error("Snapshot keys must end with a number.");
|
1669
|
+
}
|
1670
|
+
return key.replace(/ \d+$/, "");
|
1687
1671
|
}
|
1688
1672
|
function getSnapshotData(content, options) {
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1673
|
+
const update = options.updateSnapshot;
|
1674
|
+
const data = Object.create(null);
|
1675
|
+
let snapshotContents = "";
|
1676
|
+
let dirty = false;
|
1677
|
+
if (content != null) {
|
1678
|
+
try {
|
1679
|
+
snapshotContents = content;
|
1680
|
+
const populate = new Function("exports", snapshotContents);
|
1681
|
+
populate(data);
|
1682
|
+
} catch {}
|
1683
|
+
}
|
1684
|
+
const isInvalid = snapshotContents;
|
1685
|
+
if ((update === "all" || update === "new") && isInvalid) {
|
1686
|
+
dirty = true;
|
1687
|
+
}
|
1688
|
+
return {
|
1689
|
+
data,
|
1690
|
+
dirty
|
1691
|
+
};
|
1706
1692
|
}
|
1707
1693
|
function addExtraLineBreaks(string) {
|
1708
|
-
|
1709
|
-
${string}
|
1710
|
-
` : string;
|
1694
|
+
return string.includes("\n") ? `\n${string}\n` : string;
|
1711
1695
|
}
|
1712
1696
|
function removeExtraLineBreaks(string) {
|
1713
|
-
|
1697
|
+
return string.length > 2 && string.startsWith("\n") && string.endsWith("\n") ? string.slice(1, -1) : string;
|
1714
1698
|
}
|
1715
1699
|
const escapeRegex = true;
|
1716
1700
|
const printFunctionName = false;
|
1717
1701
|
function serialize(val, indent = 2, formatOverrides = {}) {
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
})
|
1726
|
-
);
|
1702
|
+
return normalizeNewlines(format(val, {
|
1703
|
+
escapeRegex,
|
1704
|
+
indent,
|
1705
|
+
plugins: getSerializers(),
|
1706
|
+
printFunctionName,
|
1707
|
+
...formatOverrides
|
1708
|
+
}));
|
1727
1709
|
}
|
1728
1710
|
function escapeBacktickString(str) {
|
1729
|
-
|
1711
|
+
return str.replace(/`|\\|\$\{/g, "\\$&");
|
1730
1712
|
}
|
1731
1713
|
function printBacktickString(str) {
|
1732
|
-
|
1714
|
+
return `\`${escapeBacktickString(str)}\``;
|
1733
1715
|
}
|
1734
1716
|
function normalizeNewlines(string) {
|
1735
|
-
|
1717
|
+
return string.replace(/\r\n|\r/g, "\n");
|
1736
1718
|
}
|
1737
1719
|
async function saveSnapshotFile(environment, snapshotData, snapshotPath) {
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
`;
|
1747
|
-
const oldContent = await environment.readSnapshotFile(snapshotPath);
|
1748
|
-
const skipWriting = oldContent != null && oldContent === content;
|
1749
|
-
if (skipWriting) {
|
1750
|
-
return;
|
1751
|
-
}
|
1752
|
-
await environment.saveSnapshotFile(snapshotPath, content);
|
1753
|
-
}
|
1754
|
-
function prepareExpected(expected) {
|
1755
|
-
function findStartIndent() {
|
1756
|
-
var _a, _b;
|
1757
|
-
const matchObject = /^( +)\}\s+$/m.exec(expected || "");
|
1758
|
-
const objectIndent = (_a = matchObject == null ? void 0 : matchObject[1]) == null ? void 0 : _a.length;
|
1759
|
-
if (objectIndent) {
|
1760
|
-
return objectIndent;
|
1761
|
-
}
|
1762
|
-
const matchText = /^\n( +)"/.exec(expected || "");
|
1763
|
-
return ((_b = matchText == null ? void 0 : matchText[1]) == null ? void 0 : _b.length) || 0;
|
1764
|
-
}
|
1765
|
-
const startIndent = findStartIndent();
|
1766
|
-
let expectedTrimmed = expected == null ? void 0 : expected.trim();
|
1767
|
-
if (startIndent) {
|
1768
|
-
expectedTrimmed = expectedTrimmed == null ? void 0 : expectedTrimmed.replace(new RegExp(`^${" ".repeat(startIndent)}`, "gm"), "").replace(/ +\}$/, "}");
|
1769
|
-
}
|
1770
|
-
return expectedTrimmed;
|
1720
|
+
const snapshots = Object.keys(snapshotData).sort(naturalCompare).map((key) => `exports[${printBacktickString(key)}] = ${printBacktickString(normalizeNewlines(snapshotData[key]))};`);
|
1721
|
+
const content = `${environment.getHeader()}\n\n${snapshots.join("\n\n")}\n`;
|
1722
|
+
const oldContent = await environment.readSnapshotFile(snapshotPath);
|
1723
|
+
const skipWriting = oldContent != null && oldContent === content;
|
1724
|
+
if (skipWriting) {
|
1725
|
+
return;
|
1726
|
+
}
|
1727
|
+
await environment.saveSnapshotFile(snapshotPath, content);
|
1771
1728
|
}
|
1772
1729
|
function deepMergeArray(target = [], source = []) {
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1730
|
+
const mergedOutput = Array.from(target);
|
1731
|
+
source.forEach((sourceElement, index) => {
|
1732
|
+
const targetElement = mergedOutput[index];
|
1733
|
+
if (Array.isArray(target[index])) {
|
1734
|
+
mergedOutput[index] = deepMergeArray(target[index], sourceElement);
|
1735
|
+
} else if (isObject(targetElement)) {
|
1736
|
+
mergedOutput[index] = deepMergeSnapshot(target[index], sourceElement);
|
1737
|
+
} else {
|
1738
|
+
mergedOutput[index] = sourceElement;
|
1739
|
+
}
|
1740
|
+
});
|
1741
|
+
return mergedOutput;
|
1785
1742
|
}
|
1743
|
+
/**
|
1744
|
+
* Deep merge, but considers asymmetric matchers. Unlike base util's deep merge,
|
1745
|
+
* will merge any object-like instance.
|
1746
|
+
* Compatible with Jest's snapshot matcher. Should not be used outside of snapshot.
|
1747
|
+
*
|
1748
|
+
* @example
|
1749
|
+
* ```ts
|
1750
|
+
* toMatchSnapshot({
|
1751
|
+
* name: expect.stringContaining('text')
|
1752
|
+
* })
|
1753
|
+
* ```
|
1754
|
+
*/
|
1786
1755
|
function deepMergeSnapshot(target, source) {
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1756
|
+
if (isObject(target) && isObject(source)) {
|
1757
|
+
const mergedOutput = { ...target };
|
1758
|
+
Object.keys(source).forEach((key) => {
|
1759
|
+
if (isObject(source[key]) && !source[key].$$typeof) {
|
1760
|
+
if (!(key in target)) {
|
1761
|
+
Object.assign(mergedOutput, { [key]: source[key] });
|
1762
|
+
} else {
|
1763
|
+
mergedOutput[key] = deepMergeSnapshot(target[key], source[key]);
|
1764
|
+
}
|
1765
|
+
} else if (Array.isArray(source[key])) {
|
1766
|
+
mergedOutput[key] = deepMergeArray(target[key], source[key]);
|
1767
|
+
} else {
|
1768
|
+
Object.assign(mergedOutput, { [key]: source[key] });
|
1769
|
+
}
|
1770
|
+
});
|
1771
|
+
return mergedOutput;
|
1772
|
+
} else if (Array.isArray(target) && Array.isArray(source)) {
|
1773
|
+
return deepMergeArray(target, source);
|
1774
|
+
}
|
1775
|
+
return target;
|
1807
1776
|
}
|
1808
1777
|
class DefaultMap extends Map {
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1778
|
+
constructor(defaultFn, entries) {
|
1779
|
+
super(entries);
|
1780
|
+
this.defaultFn = defaultFn;
|
1781
|
+
}
|
1782
|
+
get(key) {
|
1783
|
+
if (!this.has(key)) {
|
1784
|
+
this.set(key, this.defaultFn(key));
|
1785
|
+
}
|
1786
|
+
return super.get(key);
|
1787
|
+
}
|
1819
1788
|
}
|
1820
1789
|
class CounterMap extends DefaultMap {
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
for (const x of this.values()) {
|
1845
|
-
total += x;
|
1846
|
-
}
|
1847
|
-
return total;
|
1848
|
-
}
|
1790
|
+
constructor() {
|
1791
|
+
super(() => 0);
|
1792
|
+
}
|
1793
|
+
_total;
|
1794
|
+
valueOf() {
|
1795
|
+
return this._total = this.total();
|
1796
|
+
}
|
1797
|
+
increment(key) {
|
1798
|
+
if (typeof this._total !== "undefined") {
|
1799
|
+
this._total++;
|
1800
|
+
}
|
1801
|
+
this.set(key, this.get(key) + 1);
|
1802
|
+
}
|
1803
|
+
total() {
|
1804
|
+
if (typeof this._total !== "undefined") {
|
1805
|
+
return this._total;
|
1806
|
+
}
|
1807
|
+
let total = 0;
|
1808
|
+
for (const x of this.values()) {
|
1809
|
+
total += x;
|
1810
|
+
}
|
1811
|
+
return total;
|
1812
|
+
}
|
1849
1813
|
}
|
1850
1814
|
|
1851
1815
|
function isSameStackPosition(x, y) {
|
1852
|
-
|
1816
|
+
return x.file === y.file && x.column === y.column && x.line === y.line;
|
1853
1817
|
}
|
1854
1818
|
class SnapshotState {
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
2147
|
-
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
2153
|
-
key,
|
2154
|
-
pass: true
|
2155
|
-
};
|
2156
|
-
}
|
2157
|
-
}
|
2158
|
-
}
|
2159
|
-
async pack() {
|
2160
|
-
const snapshot = {
|
2161
|
-
filepath: this.testFilePath,
|
2162
|
-
added: 0,
|
2163
|
-
fileDeleted: false,
|
2164
|
-
matched: 0,
|
2165
|
-
unchecked: 0,
|
2166
|
-
uncheckedKeys: [],
|
2167
|
-
unmatched: 0,
|
2168
|
-
updated: 0
|
2169
|
-
};
|
2170
|
-
const uncheckedCount = this.getUncheckedCount();
|
2171
|
-
const uncheckedKeys = this.getUncheckedKeys();
|
2172
|
-
if (uncheckedCount) {
|
2173
|
-
this.removeUncheckedKeys();
|
2174
|
-
}
|
2175
|
-
const status = await this.save();
|
2176
|
-
snapshot.fileDeleted = status.deleted;
|
2177
|
-
snapshot.added = this.added.total();
|
2178
|
-
snapshot.matched = this.matched.total();
|
2179
|
-
snapshot.unmatched = this.unmatched.total();
|
2180
|
-
snapshot.updated = this.updated.total();
|
2181
|
-
snapshot.unchecked = !status.deleted ? uncheckedCount : 0;
|
2182
|
-
snapshot.uncheckedKeys = Array.from(uncheckedKeys);
|
2183
|
-
return snapshot;
|
2184
|
-
}
|
1819
|
+
_counters = new CounterMap();
|
1820
|
+
_dirty;
|
1821
|
+
_updateSnapshot;
|
1822
|
+
_snapshotData;
|
1823
|
+
_initialData;
|
1824
|
+
_inlineSnapshots;
|
1825
|
+
_inlineSnapshotStacks;
|
1826
|
+
_testIdToKeys = new DefaultMap(() => []);
|
1827
|
+
_rawSnapshots;
|
1828
|
+
_uncheckedKeys;
|
1829
|
+
_snapshotFormat;
|
1830
|
+
_environment;
|
1831
|
+
_fileExists;
|
1832
|
+
expand;
|
1833
|
+
_added = new CounterMap();
|
1834
|
+
_matched = new CounterMap();
|
1835
|
+
_unmatched = new CounterMap();
|
1836
|
+
_updated = new CounterMap();
|
1837
|
+
get added() {
|
1838
|
+
return this._added;
|
1839
|
+
}
|
1840
|
+
set added(value) {
|
1841
|
+
this._added._total = value;
|
1842
|
+
}
|
1843
|
+
get matched() {
|
1844
|
+
return this._matched;
|
1845
|
+
}
|
1846
|
+
set matched(value) {
|
1847
|
+
this._matched._total = value;
|
1848
|
+
}
|
1849
|
+
get unmatched() {
|
1850
|
+
return this._unmatched;
|
1851
|
+
}
|
1852
|
+
set unmatched(value) {
|
1853
|
+
this._unmatched._total = value;
|
1854
|
+
}
|
1855
|
+
get updated() {
|
1856
|
+
return this._updated;
|
1857
|
+
}
|
1858
|
+
set updated(value) {
|
1859
|
+
this._updated._total = value;
|
1860
|
+
}
|
1861
|
+
constructor(testFilePath, snapshotPath, snapshotContent, options) {
|
1862
|
+
this.testFilePath = testFilePath;
|
1863
|
+
this.snapshotPath = snapshotPath;
|
1864
|
+
const { data, dirty } = getSnapshotData(snapshotContent, options);
|
1865
|
+
this._fileExists = snapshotContent != null;
|
1866
|
+
this._initialData = { ...data };
|
1867
|
+
this._snapshotData = { ...data };
|
1868
|
+
this._dirty = dirty;
|
1869
|
+
this._inlineSnapshots = [];
|
1870
|
+
this._inlineSnapshotStacks = [];
|
1871
|
+
this._rawSnapshots = [];
|
1872
|
+
this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
|
1873
|
+
this.expand = options.expand || false;
|
1874
|
+
this._updateSnapshot = options.updateSnapshot;
|
1875
|
+
this._snapshotFormat = {
|
1876
|
+
printBasicPrototype: false,
|
1877
|
+
escapeString: false,
|
1878
|
+
...options.snapshotFormat
|
1879
|
+
};
|
1880
|
+
this._environment = options.snapshotEnvironment;
|
1881
|
+
}
|
1882
|
+
static async create(testFilePath, options) {
|
1883
|
+
const snapshotPath = await options.snapshotEnvironment.resolvePath(testFilePath);
|
1884
|
+
const content = await options.snapshotEnvironment.readSnapshotFile(snapshotPath);
|
1885
|
+
return new SnapshotState(testFilePath, snapshotPath, content, options);
|
1886
|
+
}
|
1887
|
+
get environment() {
|
1888
|
+
return this._environment;
|
1889
|
+
}
|
1890
|
+
markSnapshotsAsCheckedForTest(testName) {
|
1891
|
+
this._uncheckedKeys.forEach((uncheckedKey) => {
|
1892
|
+
if (/ \d+$| > /.test(uncheckedKey.slice(testName.length))) {
|
1893
|
+
this._uncheckedKeys.delete(uncheckedKey);
|
1894
|
+
}
|
1895
|
+
});
|
1896
|
+
}
|
1897
|
+
clearTest(testId) {
|
1898
|
+
this._inlineSnapshots = this._inlineSnapshots.filter((s) => s.testId !== testId);
|
1899
|
+
this._inlineSnapshotStacks = this._inlineSnapshotStacks.filter((s) => s.testId !== testId);
|
1900
|
+
for (const key of this._testIdToKeys.get(testId)) {
|
1901
|
+
const name = keyToTestName(key);
|
1902
|
+
const count = this._counters.get(name);
|
1903
|
+
if (count > 0) {
|
1904
|
+
if (key in this._snapshotData || key in this._initialData) {
|
1905
|
+
this._snapshotData[key] = this._initialData[key];
|
1906
|
+
}
|
1907
|
+
this._counters.set(name, count - 1);
|
1908
|
+
}
|
1909
|
+
}
|
1910
|
+
this._testIdToKeys.delete(testId);
|
1911
|
+
this.added.delete(testId);
|
1912
|
+
this.updated.delete(testId);
|
1913
|
+
this.matched.delete(testId);
|
1914
|
+
this.unmatched.delete(testId);
|
1915
|
+
}
|
1916
|
+
_inferInlineSnapshotStack(stacks) {
|
1917
|
+
const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/));
|
1918
|
+
if (promiseIndex !== -1) {
|
1919
|
+
return stacks[promiseIndex + 3];
|
1920
|
+
}
|
1921
|
+
const stackIndex = stacks.findIndex((i) => i.method.includes("__INLINE_SNAPSHOT__"));
|
1922
|
+
return stackIndex !== -1 ? stacks[stackIndex + 2] : null;
|
1923
|
+
}
|
1924
|
+
_addSnapshot(key, receivedSerialized, options) {
|
1925
|
+
this._dirty = true;
|
1926
|
+
if (options.stack) {
|
1927
|
+
this._inlineSnapshots.push({
|
1928
|
+
snapshot: receivedSerialized,
|
1929
|
+
testId: options.testId,
|
1930
|
+
...options.stack
|
1931
|
+
});
|
1932
|
+
} else if (options.rawSnapshot) {
|
1933
|
+
this._rawSnapshots.push({
|
1934
|
+
...options.rawSnapshot,
|
1935
|
+
snapshot: receivedSerialized
|
1936
|
+
});
|
1937
|
+
} else {
|
1938
|
+
this._snapshotData[key] = receivedSerialized;
|
1939
|
+
}
|
1940
|
+
}
|
1941
|
+
async save() {
|
1942
|
+
const hasExternalSnapshots = Object.keys(this._snapshotData).length;
|
1943
|
+
const hasInlineSnapshots = this._inlineSnapshots.length;
|
1944
|
+
const hasRawSnapshots = this._rawSnapshots.length;
|
1945
|
+
const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots && !hasRawSnapshots;
|
1946
|
+
const status = {
|
1947
|
+
deleted: false,
|
1948
|
+
saved: false
|
1949
|
+
};
|
1950
|
+
if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) {
|
1951
|
+
if (hasExternalSnapshots) {
|
1952
|
+
await saveSnapshotFile(this._environment, this._snapshotData, this.snapshotPath);
|
1953
|
+
this._fileExists = true;
|
1954
|
+
}
|
1955
|
+
if (hasInlineSnapshots) {
|
1956
|
+
await saveInlineSnapshots(this._environment, this._inlineSnapshots);
|
1957
|
+
}
|
1958
|
+
if (hasRawSnapshots) {
|
1959
|
+
await saveRawSnapshots(this._environment, this._rawSnapshots);
|
1960
|
+
}
|
1961
|
+
status.saved = true;
|
1962
|
+
} else if (!hasExternalSnapshots && this._fileExists) {
|
1963
|
+
if (this._updateSnapshot === "all") {
|
1964
|
+
await this._environment.removeSnapshotFile(this.snapshotPath);
|
1965
|
+
this._fileExists = false;
|
1966
|
+
}
|
1967
|
+
status.deleted = true;
|
1968
|
+
}
|
1969
|
+
return status;
|
1970
|
+
}
|
1971
|
+
getUncheckedCount() {
|
1972
|
+
return this._uncheckedKeys.size || 0;
|
1973
|
+
}
|
1974
|
+
getUncheckedKeys() {
|
1975
|
+
return Array.from(this._uncheckedKeys);
|
1976
|
+
}
|
1977
|
+
removeUncheckedKeys() {
|
1978
|
+
if (this._updateSnapshot === "all" && this._uncheckedKeys.size) {
|
1979
|
+
this._dirty = true;
|
1980
|
+
this._uncheckedKeys.forEach((key) => delete this._snapshotData[key]);
|
1981
|
+
this._uncheckedKeys.clear();
|
1982
|
+
}
|
1983
|
+
}
|
1984
|
+
match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot }) {
|
1985
|
+
this._counters.increment(testName);
|
1986
|
+
const count = this._counters.get(testName);
|
1987
|
+
if (!key) {
|
1988
|
+
key = testNameToKey(testName, count);
|
1989
|
+
}
|
1990
|
+
this._testIdToKeys.get(testId).push(key);
|
1991
|
+
if (!(isInline && this._snapshotData[key] !== undefined)) {
|
1992
|
+
this._uncheckedKeys.delete(key);
|
1993
|
+
}
|
1994
|
+
let receivedSerialized = rawSnapshot && typeof received === "string" ? received : serialize(received, undefined, this._snapshotFormat);
|
1995
|
+
if (!rawSnapshot) {
|
1996
|
+
receivedSerialized = addExtraLineBreaks(receivedSerialized);
|
1997
|
+
}
|
1998
|
+
if (rawSnapshot) {
|
1999
|
+
if (rawSnapshot.content && rawSnapshot.content.match(/\r\n/) && !receivedSerialized.match(/\r\n/)) {
|
2000
|
+
rawSnapshot.content = normalizeNewlines(rawSnapshot.content);
|
2001
|
+
}
|
2002
|
+
}
|
2003
|
+
const expected = isInline ? inlineSnapshot : rawSnapshot ? rawSnapshot.content : this._snapshotData[key];
|
2004
|
+
const expectedTrimmed = rawSnapshot ? expected : expected === null || expected === void 0 ? void 0 : expected.trim();
|
2005
|
+
const pass = expectedTrimmed === (rawSnapshot ? receivedSerialized : receivedSerialized.trim());
|
2006
|
+
const hasSnapshot = expected !== undefined;
|
2007
|
+
const snapshotIsPersisted = isInline || this._fileExists || rawSnapshot && rawSnapshot.content != null;
|
2008
|
+
if (pass && !isInline && !rawSnapshot) {
|
2009
|
+
this._snapshotData[key] = receivedSerialized;
|
2010
|
+
}
|
2011
|
+
let stack;
|
2012
|
+
if (isInline) {
|
2013
|
+
var _this$environment$pro, _this$environment;
|
2014
|
+
const stacks = parseErrorStacktrace(error || new Error("snapshot"), { ignoreStackEntries: [] });
|
2015
|
+
const _stack = this._inferInlineSnapshotStack(stacks);
|
2016
|
+
if (!_stack) {
|
2017
|
+
throw new Error(`@vitest/snapshot: Couldn't infer stack frame for inline snapshot.\n${JSON.stringify(stacks)}`);
|
2018
|
+
}
|
2019
|
+
stack = ((_this$environment$pro = (_this$environment = this.environment).processStackTrace) === null || _this$environment$pro === void 0 ? void 0 : _this$environment$pro.call(_this$environment, _stack)) || _stack;
|
2020
|
+
stack.column--;
|
2021
|
+
const snapshotsWithSameStack = this._inlineSnapshotStacks.filter((s) => isSameStackPosition(s, stack));
|
2022
|
+
if (snapshotsWithSameStack.length > 0) {
|
2023
|
+
this._inlineSnapshots = this._inlineSnapshots.filter((s) => !isSameStackPosition(s, stack));
|
2024
|
+
const differentSnapshot = snapshotsWithSameStack.find((s) => s.snapshot !== receivedSerialized);
|
2025
|
+
if (differentSnapshot) {
|
2026
|
+
throw Object.assign(new Error("toMatchInlineSnapshot with different snapshots cannot be called at the same location"), {
|
2027
|
+
actual: receivedSerialized,
|
2028
|
+
expected: differentSnapshot.snapshot
|
2029
|
+
});
|
2030
|
+
}
|
2031
|
+
}
|
2032
|
+
this._inlineSnapshotStacks.push({
|
2033
|
+
...stack,
|
2034
|
+
testId,
|
2035
|
+
snapshot: receivedSerialized
|
2036
|
+
});
|
2037
|
+
}
|
2038
|
+
if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
|
2039
|
+
if (this._updateSnapshot === "all") {
|
2040
|
+
if (!pass) {
|
2041
|
+
if (hasSnapshot) {
|
2042
|
+
this.updated.increment(testId);
|
2043
|
+
} else {
|
2044
|
+
this.added.increment(testId);
|
2045
|
+
}
|
2046
|
+
this._addSnapshot(key, receivedSerialized, {
|
2047
|
+
stack,
|
2048
|
+
testId,
|
2049
|
+
rawSnapshot
|
2050
|
+
});
|
2051
|
+
} else {
|
2052
|
+
this.matched.increment(testId);
|
2053
|
+
}
|
2054
|
+
} else {
|
2055
|
+
this._addSnapshot(key, receivedSerialized, {
|
2056
|
+
stack,
|
2057
|
+
testId,
|
2058
|
+
rawSnapshot
|
2059
|
+
});
|
2060
|
+
this.added.increment(testId);
|
2061
|
+
}
|
2062
|
+
return {
|
2063
|
+
actual: "",
|
2064
|
+
count,
|
2065
|
+
expected: "",
|
2066
|
+
key,
|
2067
|
+
pass: true
|
2068
|
+
};
|
2069
|
+
} else {
|
2070
|
+
if (!pass) {
|
2071
|
+
this.unmatched.increment(testId);
|
2072
|
+
return {
|
2073
|
+
actual: rawSnapshot ? receivedSerialized : removeExtraLineBreaks(receivedSerialized),
|
2074
|
+
count,
|
2075
|
+
expected: expectedTrimmed !== undefined ? rawSnapshot ? expectedTrimmed : removeExtraLineBreaks(expectedTrimmed) : undefined,
|
2076
|
+
key,
|
2077
|
+
pass: false
|
2078
|
+
};
|
2079
|
+
} else {
|
2080
|
+
this.matched.increment(testId);
|
2081
|
+
return {
|
2082
|
+
actual: "",
|
2083
|
+
count,
|
2084
|
+
expected: "",
|
2085
|
+
key,
|
2086
|
+
pass: true
|
2087
|
+
};
|
2088
|
+
}
|
2089
|
+
}
|
2090
|
+
}
|
2091
|
+
async pack() {
|
2092
|
+
const snapshot = {
|
2093
|
+
filepath: this.testFilePath,
|
2094
|
+
added: 0,
|
2095
|
+
fileDeleted: false,
|
2096
|
+
matched: 0,
|
2097
|
+
unchecked: 0,
|
2098
|
+
uncheckedKeys: [],
|
2099
|
+
unmatched: 0,
|
2100
|
+
updated: 0
|
2101
|
+
};
|
2102
|
+
const uncheckedCount = this.getUncheckedCount();
|
2103
|
+
const uncheckedKeys = this.getUncheckedKeys();
|
2104
|
+
if (uncheckedCount) {
|
2105
|
+
this.removeUncheckedKeys();
|
2106
|
+
}
|
2107
|
+
const status = await this.save();
|
2108
|
+
snapshot.fileDeleted = status.deleted;
|
2109
|
+
snapshot.added = this.added.total();
|
2110
|
+
snapshot.matched = this.matched.total();
|
2111
|
+
snapshot.unmatched = this.unmatched.total();
|
2112
|
+
snapshot.updated = this.updated.total();
|
2113
|
+
snapshot.unchecked = !status.deleted ? uncheckedCount : 0;
|
2114
|
+
snapshot.uncheckedKeys = Array.from(uncheckedKeys);
|
2115
|
+
return snapshot;
|
2116
|
+
}
|
2185
2117
|
}
|
2186
2118
|
|
2187
2119
|
function createMismatchError(message, expand, actual, expected) {
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2120
|
+
const error = new Error(message);
|
2121
|
+
Object.defineProperty(error, "actual", {
|
2122
|
+
value: actual,
|
2123
|
+
enumerable: true,
|
2124
|
+
configurable: true,
|
2125
|
+
writable: true
|
2126
|
+
});
|
2127
|
+
Object.defineProperty(error, "expected", {
|
2128
|
+
value: expected,
|
2129
|
+
enumerable: true,
|
2130
|
+
configurable: true,
|
2131
|
+
writable: true
|
2132
|
+
});
|
2133
|
+
Object.defineProperty(error, "diffOptions", { value: { expand } });
|
2134
|
+
return error;
|
2203
2135
|
}
|
2204
2136
|
class SnapshotClient {
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2230
|
-
|
2231
|
-
|
2232
|
-
|
2233
|
-
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2272
|
-
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2283
|
-
|
2284
|
-
|
2285
|
-
|
2286
|
-
|
2287
|
-
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2291
|
-
|
2292
|
-
|
2293
|
-
if (!pass) {
|
2294
|
-
throw createMismatchError(
|
2295
|
-
`Snapshot \`${key || "unknown"}\` mismatched`,
|
2296
|
-
snapshotState.expand,
|
2297
|
-
rawSnapshot ? actual : actual == null ? void 0 : actual.trim(),
|
2298
|
-
rawSnapshot ? expected : expected == null ? void 0 : expected.trim()
|
2299
|
-
);
|
2300
|
-
}
|
2301
|
-
}
|
2302
|
-
async assertRaw(options) {
|
2303
|
-
if (!options.rawSnapshot) {
|
2304
|
-
throw new Error("Raw snapshot is required");
|
2305
|
-
}
|
2306
|
-
const { filepath, rawSnapshot } = options;
|
2307
|
-
if (rawSnapshot.content == null) {
|
2308
|
-
if (!filepath) {
|
2309
|
-
throw new Error("Snapshot cannot be used outside of test");
|
2310
|
-
}
|
2311
|
-
const snapshotState = this.getSnapshotState(filepath);
|
2312
|
-
options.filepath || (options.filepath = filepath);
|
2313
|
-
rawSnapshot.file = await snapshotState.environment.resolveRawPath(
|
2314
|
-
filepath,
|
2315
|
-
rawSnapshot.file
|
2316
|
-
);
|
2317
|
-
rawSnapshot.content = await snapshotState.environment.readSnapshotFile(rawSnapshot.file) ?? void 0;
|
2318
|
-
}
|
2319
|
-
return this.assert(options);
|
2320
|
-
}
|
2321
|
-
clear() {
|
2322
|
-
this.snapshotStateMap.clear();
|
2323
|
-
}
|
2137
|
+
snapshotStateMap = new Map();
|
2138
|
+
constructor(options = {}) {
|
2139
|
+
this.options = options;
|
2140
|
+
}
|
2141
|
+
async setup(filepath, options) {
|
2142
|
+
if (this.snapshotStateMap.has(filepath)) {
|
2143
|
+
return;
|
2144
|
+
}
|
2145
|
+
this.snapshotStateMap.set(filepath, await SnapshotState.create(filepath, options));
|
2146
|
+
}
|
2147
|
+
async finish(filepath) {
|
2148
|
+
const state = this.getSnapshotState(filepath);
|
2149
|
+
const result = await state.pack();
|
2150
|
+
this.snapshotStateMap.delete(filepath);
|
2151
|
+
return result;
|
2152
|
+
}
|
2153
|
+
skipTest(filepath, testName) {
|
2154
|
+
const state = this.getSnapshotState(filepath);
|
2155
|
+
state.markSnapshotsAsCheckedForTest(testName);
|
2156
|
+
}
|
2157
|
+
clearTest(filepath, testId) {
|
2158
|
+
const state = this.getSnapshotState(filepath);
|
2159
|
+
state.clearTest(testId);
|
2160
|
+
}
|
2161
|
+
getSnapshotState(filepath) {
|
2162
|
+
const state = this.snapshotStateMap.get(filepath);
|
2163
|
+
if (!state) {
|
2164
|
+
throw new Error(`The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`);
|
2165
|
+
}
|
2166
|
+
return state;
|
2167
|
+
}
|
2168
|
+
assert(options) {
|
2169
|
+
const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot } = options;
|
2170
|
+
let { received } = options;
|
2171
|
+
if (!filepath) {
|
2172
|
+
throw new Error("Snapshot cannot be used outside of test");
|
2173
|
+
}
|
2174
|
+
const snapshotState = this.getSnapshotState(filepath);
|
2175
|
+
if (typeof properties === "object") {
|
2176
|
+
if (typeof received !== "object" || !received) {
|
2177
|
+
throw new Error("Received value must be an object when the matcher has properties");
|
2178
|
+
}
|
2179
|
+
try {
|
2180
|
+
var _this$options$isEqual, _this$options;
|
2181
|
+
const pass = ((_this$options$isEqual = (_this$options = this.options).isEqual) === null || _this$options$isEqual === void 0 ? void 0 : _this$options$isEqual.call(_this$options, received, properties)) ?? false;
|
2182
|
+
if (!pass) {
|
2183
|
+
throw createMismatchError("Snapshot properties mismatched", snapshotState.expand, received, properties);
|
2184
|
+
} else {
|
2185
|
+
received = deepMergeSnapshot(received, properties);
|
2186
|
+
}
|
2187
|
+
} catch (err) {
|
2188
|
+
err.message = errorMessage || "Snapshot mismatched";
|
2189
|
+
throw err;
|
2190
|
+
}
|
2191
|
+
}
|
2192
|
+
const testName = [name, ...message ? [message] : []].join(" > ");
|
2193
|
+
const { actual, expected, key, pass } = snapshotState.match({
|
2194
|
+
testId,
|
2195
|
+
testName,
|
2196
|
+
received,
|
2197
|
+
isInline,
|
2198
|
+
error,
|
2199
|
+
inlineSnapshot,
|
2200
|
+
rawSnapshot
|
2201
|
+
});
|
2202
|
+
if (!pass) {
|
2203
|
+
throw createMismatchError(`Snapshot \`${key || "unknown"}\` mismatched`, snapshotState.expand, rawSnapshot ? actual : actual === null || actual === void 0 ? void 0 : actual.trim(), rawSnapshot ? expected : expected === null || expected === void 0 ? void 0 : expected.trim());
|
2204
|
+
}
|
2205
|
+
}
|
2206
|
+
async assertRaw(options) {
|
2207
|
+
if (!options.rawSnapshot) {
|
2208
|
+
throw new Error("Raw snapshot is required");
|
2209
|
+
}
|
2210
|
+
const { filepath, rawSnapshot } = options;
|
2211
|
+
if (rawSnapshot.content == null) {
|
2212
|
+
if (!filepath) {
|
2213
|
+
throw new Error("Snapshot cannot be used outside of test");
|
2214
|
+
}
|
2215
|
+
const snapshotState = this.getSnapshotState(filepath);
|
2216
|
+
options.filepath || (options.filepath = filepath);
|
2217
|
+
rawSnapshot.file = await snapshotState.environment.resolveRawPath(filepath, rawSnapshot.file);
|
2218
|
+
rawSnapshot.content = await snapshotState.environment.readSnapshotFile(rawSnapshot.file) ?? undefined;
|
2219
|
+
}
|
2220
|
+
return this.assert(options);
|
2221
|
+
}
|
2222
|
+
clear() {
|
2223
|
+
this.snapshotStateMap.clear();
|
2224
|
+
}
|
2324
2225
|
}
|
2325
2226
|
|
2326
2227
|
export { SnapshotClient, SnapshotState, addSerializer, getSerializers, stripSnapshotIndentation };
|