@vitest/snapshot 3.0.9 → 3.1.0-beta.2
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 +906 -996
- package/dist/manager.js +63 -66
- package/package.json +3 -3
package/dist/index.js
CHANGED
@@ -577,221 +577,229 @@ 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
|
-
e.stacks = stackFrames;
|
794
|
-
return stackFrames;
|
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 (options.frameFilter) {
|
799
|
+
stackFrames = stackFrames.filter((f) => options.frameFilter(e, f) !== false);
|
800
|
+
}
|
801
|
+
e.stacks = stackFrames;
|
802
|
+
return stackFrames;
|
795
803
|
}
|
796
804
|
|
797
805
|
let getPromiseValue = () => 'Promise{…}';
|
@@ -828,14 +836,7 @@ catch (noNodeInspect) {
|
|
828
836
|
nodeInspect = false;
|
829
837
|
}
|
830
838
|
|
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;
|
839
|
+
const { AsymmetricMatcher: AsymmetricMatcher$1, DOMCollection: DOMCollection$1, DOMElement: DOMElement$1, Immutable: Immutable$1, ReactElement: ReactElement$1, ReactTestComponent: ReactTestComponent$1 } = plugins;
|
839
840
|
|
840
841
|
function getDefaultExportFromCjs (x) {
|
841
842
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
@@ -1374,190 +1375,180 @@ p();
|
|
1374
1375
|
|
1375
1376
|
const lineSplitRE = /\r?\n/;
|
1376
1377
|
function positionToOffset(source, lineNumber, columnNumber) {
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1378
|
+
const lines = source.split(lineSplitRE);
|
1379
|
+
const nl = /\r\n/.test(source) ? 2 : 1;
|
1380
|
+
let start = 0;
|
1381
|
+
if (lineNumber > lines.length) {
|
1382
|
+
return source.length;
|
1383
|
+
}
|
1384
|
+
for (let i = 0; i < lineNumber - 1; i++) {
|
1385
|
+
start += lines[i].length + nl;
|
1386
|
+
}
|
1387
|
+
return start + columnNumber;
|
1387
1388
|
}
|
1388
1389
|
function offsetToLineNumber(source, offset) {
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
}
|
1405
|
-
return line + 1;
|
1390
|
+
if (offset > source.length) {
|
1391
|
+
throw new Error(`offset is longer than source length! offset ${offset} > length ${source.length}`);
|
1392
|
+
}
|
1393
|
+
const lines = source.split(lineSplitRE);
|
1394
|
+
const nl = /\r\n/.test(source) ? 2 : 1;
|
1395
|
+
let counted = 0;
|
1396
|
+
let line = 0;
|
1397
|
+
for (; line < lines.length; line++) {
|
1398
|
+
const lineLength = lines[line].length + nl;
|
1399
|
+
if (counted + lineLength >= offset) {
|
1400
|
+
break;
|
1401
|
+
}
|
1402
|
+
counted += lineLength;
|
1403
|
+
}
|
1404
|
+
return line + 1;
|
1406
1405
|
}
|
1407
1406
|
|
1408
1407
|
async function saveInlineSnapshots(environment, snapshots) {
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
})
|
1425
|
-
);
|
1408
|
+
const MagicString = (await import('magic-string')).default;
|
1409
|
+
const files = new Set(snapshots.map((i) => i.file));
|
1410
|
+
await Promise.all(Array.from(files).map(async (file) => {
|
1411
|
+
const snaps = snapshots.filter((i) => i.file === file);
|
1412
|
+
const code = await environment.readSnapshotFile(file);
|
1413
|
+
const s = new MagicString(code);
|
1414
|
+
for (const snap of snaps) {
|
1415
|
+
const index = positionToOffset(code, snap.line, snap.column);
|
1416
|
+
replaceInlineSnap(code, s, index, snap.snapshot);
|
1417
|
+
}
|
1418
|
+
const transformed = s.toString();
|
1419
|
+
if (transformed !== code) {
|
1420
|
+
await environment.saveSnapshotFile(file, transformed);
|
1421
|
+
}
|
1422
|
+
}));
|
1426
1423
|
}
|
1427
1424
|
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
1425
|
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
|
-
|
1426
|
+
let _code = code.slice(index);
|
1427
|
+
const startMatch = startObjectRegex.exec(_code);
|
1428
|
+
if (!startMatch) {
|
1429
|
+
return false;
|
1430
|
+
}
|
1431
|
+
_code = _code.slice(startMatch.index);
|
1432
|
+
let callEnd = getCallLastIndex(_code);
|
1433
|
+
if (callEnd === null) {
|
1434
|
+
return false;
|
1435
|
+
}
|
1436
|
+
callEnd += index + startMatch.index;
|
1437
|
+
const shapeStart = index + startMatch.index + startMatch[0].length;
|
1438
|
+
const shapeEnd = getObjectShapeEndIndex(code, shapeStart);
|
1439
|
+
const snap = `, ${prepareSnapString(newSnap, code, index)}`;
|
1440
|
+
if (shapeEnd === callEnd) {
|
1441
|
+
s.appendLeft(callEnd, snap);
|
1442
|
+
} else {
|
1443
|
+
s.overwrite(shapeEnd, callEnd, snap);
|
1444
|
+
}
|
1445
|
+
return true;
|
1449
1446
|
}
|
1450
1447
|
function getObjectShapeEndIndex(code, index) {
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1448
|
+
let startBraces = 1;
|
1449
|
+
let endBraces = 0;
|
1450
|
+
while (startBraces !== endBraces && index < code.length) {
|
1451
|
+
const s = code[index++];
|
1452
|
+
if (s === "{") {
|
1453
|
+
startBraces++;
|
1454
|
+
} else if (s === "}") {
|
1455
|
+
endBraces++;
|
1456
|
+
}
|
1457
|
+
}
|
1458
|
+
return index;
|
1462
1459
|
}
|
1463
1460
|
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}`;
|
1461
|
+
const lineNumber = offsetToLineNumber(source, index);
|
1462
|
+
const line = source.split(lineSplitRE)[lineNumber - 1];
|
1463
|
+
const indent = line.match(/^\s*/)[0] || "";
|
1464
|
+
const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `;
|
1465
|
+
const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
|
1466
|
+
const isOneline = lines.length <= 1;
|
1467
|
+
const quote = "`";
|
1468
|
+
if (isOneline) {
|
1469
|
+
return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\\${")}${quote}`;
|
1470
|
+
}
|
1471
|
+
return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\\${")}\n${indent}${quote}`;
|
1477
1472
|
}
|
1478
1473
|
const toMatchInlineName = "toMatchInlineSnapshot";
|
1479
1474
|
const toThrowErrorMatchingInlineName = "toThrowErrorMatchingInlineSnapshot";
|
1480
1475
|
function getCodeStartingAtIndex(code, index) {
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1476
|
+
const indexInline = index - toMatchInlineName.length;
|
1477
|
+
if (code.slice(indexInline, index) === toMatchInlineName) {
|
1478
|
+
return {
|
1479
|
+
code: code.slice(indexInline),
|
1480
|
+
index: indexInline
|
1481
|
+
};
|
1482
|
+
}
|
1483
|
+
const indexThrowInline = index - toThrowErrorMatchingInlineName.length;
|
1484
|
+
if (code.slice(index - indexThrowInline, index) === toThrowErrorMatchingInlineName) {
|
1485
|
+
return {
|
1486
|
+
code: code.slice(index - indexThrowInline),
|
1487
|
+
index: index - indexThrowInline
|
1488
|
+
};
|
1489
|
+
}
|
1490
|
+
return {
|
1491
|
+
code: code.slice(index),
|
1492
|
+
index
|
1493
|
+
};
|
1499
1494
|
}
|
1500
1495
|
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
1496
|
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;
|
1497
|
+
const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex);
|
1498
|
+
const startMatch = startRegex.exec(codeStartingAtIndex);
|
1499
|
+
const firstKeywordMatch = /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/.exec(codeStartingAtIndex);
|
1500
|
+
if (!startMatch || startMatch.index !== (firstKeywordMatch === null || firstKeywordMatch === void 0 ? void 0 : firstKeywordMatch.index)) {
|
1501
|
+
return replaceObjectSnap(code, s, index, newSnap);
|
1502
|
+
}
|
1503
|
+
const quote = startMatch[1];
|
1504
|
+
const startIndex = index + startMatch.index + startMatch[0].length;
|
1505
|
+
const snapString = prepareSnapString(newSnap, code, index);
|
1506
|
+
if (quote === ")") {
|
1507
|
+
s.appendRight(startIndex - 1, snapString);
|
1508
|
+
return true;
|
1509
|
+
}
|
1510
|
+
const quoteEndRE = new RegExp(`(?:^|[^\\\\])${quote}`);
|
1511
|
+
const endMatch = quoteEndRE.exec(code.slice(startIndex));
|
1512
|
+
if (!endMatch) {
|
1513
|
+
return false;
|
1514
|
+
}
|
1515
|
+
const endIndex = startIndex + endMatch.index + endMatch[0].length;
|
1516
|
+
s.overwrite(startIndex - 1, endIndex, snapString);
|
1517
|
+
return true;
|
1525
1518
|
}
|
1526
1519
|
const INDENTATION_REGEX = /^([^\S\n]*)\S/m;
|
1527
1520
|
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
|
-
|
1521
|
+
const match = inlineSnapshot.match(INDENTATION_REGEX);
|
1522
|
+
if (!match || !match[1]) {
|
1523
|
+
return inlineSnapshot;
|
1524
|
+
}
|
1525
|
+
const indentation = match[1];
|
1526
|
+
const lines = inlineSnapshot.split(/\n/g);
|
1527
|
+
if (lines.length <= 2) {
|
1528
|
+
return inlineSnapshot;
|
1529
|
+
}
|
1530
|
+
if (lines[0].trim() !== "" || lines[lines.length - 1].trim() !== "") {
|
1531
|
+
return inlineSnapshot;
|
1532
|
+
}
|
1533
|
+
for (let i = 1; i < lines.length - 1; i++) {
|
1534
|
+
if (lines[i] !== "") {
|
1535
|
+
if (lines[i].indexOf(indentation) !== 0) {
|
1536
|
+
return inlineSnapshot;
|
1537
|
+
}
|
1538
|
+
lines[i] = lines[i].substring(indentation.length);
|
1539
|
+
}
|
1540
|
+
}
|
1541
|
+
lines[lines.length - 1] = "";
|
1542
|
+
inlineSnapshot = lines.join("\n");
|
1543
|
+
return inlineSnapshot;
|
1551
1544
|
}
|
1552
1545
|
|
1553
1546
|
async function saveRawSnapshots(environment, snapshots) {
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
})
|
1560
|
-
);
|
1547
|
+
await Promise.all(snapshots.map(async (snap) => {
|
1548
|
+
if (!snap.readonly) {
|
1549
|
+
await environment.saveSnapshotFile(snap.file, snap.snapshot);
|
1550
|
+
}
|
1551
|
+
}));
|
1561
1552
|
}
|
1562
1553
|
|
1563
1554
|
var naturalCompare$1 = {exports: {}};
|
@@ -1628,699 +1619,618 @@ var naturalCompareExports = requireNaturalCompare();
|
|
1628
1619
|
var naturalCompare = /*@__PURE__*/getDefaultExportFromCjs(naturalCompareExports);
|
1629
1620
|
|
1630
1621
|
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}`;
|
1622
|
+
const name = val.getMockName();
|
1623
|
+
const nameString = name === "vi.fn()" ? "" : ` ${name}`;
|
1624
|
+
let callsString = "";
|
1625
|
+
if (val.mock.calls.length !== 0) {
|
1626
|
+
const indentationNext = indentation + config.indent;
|
1627
|
+
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}}`;
|
1628
|
+
}
|
1629
|
+
return `[MockFunction${nameString}]${callsString}`;
|
1651
1630
|
};
|
1652
1631
|
const test = (val) => val && !!val._isMockFunction;
|
1653
|
-
const plugin = {
|
1632
|
+
const plugin = {
|
1633
|
+
serialize: serialize$1,
|
1634
|
+
test
|
1635
|
+
};
|
1654
1636
|
|
1655
|
-
const {
|
1656
|
-
DOMCollection,
|
1657
|
-
DOMElement,
|
1658
|
-
Immutable,
|
1659
|
-
ReactElement,
|
1660
|
-
ReactTestComponent,
|
1661
|
-
AsymmetricMatcher
|
1662
|
-
} = plugins;
|
1637
|
+
const { DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent, AsymmetricMatcher } = plugins;
|
1663
1638
|
let PLUGINS = [
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1639
|
+
ReactTestComponent,
|
1640
|
+
ReactElement,
|
1641
|
+
DOMElement,
|
1642
|
+
DOMCollection,
|
1643
|
+
Immutable,
|
1644
|
+
AsymmetricMatcher,
|
1645
|
+
plugin
|
1671
1646
|
];
|
1672
1647
|
function addSerializer(plugin) {
|
1673
|
-
|
1648
|
+
PLUGINS = [plugin].concat(PLUGINS);
|
1674
1649
|
}
|
1675
1650
|
function getSerializers() {
|
1676
|
-
|
1651
|
+
return PLUGINS;
|
1677
1652
|
}
|
1678
1653
|
|
1679
1654
|
function testNameToKey(testName, count) {
|
1680
|
-
|
1655
|
+
return `${testName} ${count}`;
|
1681
1656
|
}
|
1682
1657
|
function keyToTestName(key) {
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1658
|
+
if (!/ \d+$/.test(key)) {
|
1659
|
+
throw new Error("Snapshot keys must end with a number.");
|
1660
|
+
}
|
1661
|
+
return key.replace(/ \d+$/, "");
|
1687
1662
|
}
|
1688
1663
|
function getSnapshotData(content, options) {
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1664
|
+
const update = options.updateSnapshot;
|
1665
|
+
const data = Object.create(null);
|
1666
|
+
let snapshotContents = "";
|
1667
|
+
let dirty = false;
|
1668
|
+
if (content != null) {
|
1669
|
+
try {
|
1670
|
+
snapshotContents = content;
|
1671
|
+
const populate = new Function("exports", snapshotContents);
|
1672
|
+
populate(data);
|
1673
|
+
} catch {}
|
1674
|
+
}
|
1675
|
+
const isInvalid = snapshotContents;
|
1676
|
+
if ((update === "all" || update === "new") && isInvalid) {
|
1677
|
+
dirty = true;
|
1678
|
+
}
|
1679
|
+
return {
|
1680
|
+
data,
|
1681
|
+
dirty
|
1682
|
+
};
|
1706
1683
|
}
|
1707
1684
|
function addExtraLineBreaks(string) {
|
1708
|
-
|
1709
|
-
${string}
|
1710
|
-
` : string;
|
1685
|
+
return string.includes("\n") ? `\n${string}\n` : string;
|
1711
1686
|
}
|
1712
1687
|
function removeExtraLineBreaks(string) {
|
1713
|
-
|
1688
|
+
return string.length > 2 && string.startsWith("\n") && string.endsWith("\n") ? string.slice(1, -1) : string;
|
1714
1689
|
}
|
1715
1690
|
const escapeRegex = true;
|
1716
1691
|
const printFunctionName = false;
|
1717
1692
|
function serialize(val, indent = 2, formatOverrides = {}) {
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
})
|
1726
|
-
);
|
1693
|
+
return normalizeNewlines(format(val, {
|
1694
|
+
escapeRegex,
|
1695
|
+
indent,
|
1696
|
+
plugins: getSerializers(),
|
1697
|
+
printFunctionName,
|
1698
|
+
...formatOverrides
|
1699
|
+
}));
|
1727
1700
|
}
|
1728
1701
|
function escapeBacktickString(str) {
|
1729
|
-
|
1702
|
+
return str.replace(/`|\\|\$\{/g, "\\$&");
|
1730
1703
|
}
|
1731
1704
|
function printBacktickString(str) {
|
1732
|
-
|
1705
|
+
return `\`${escapeBacktickString(str)}\``;
|
1733
1706
|
}
|
1734
1707
|
function normalizeNewlines(string) {
|
1735
|
-
|
1708
|
+
return string.replace(/\r\n|\r/g, "\n");
|
1736
1709
|
}
|
1737
1710
|
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);
|
1711
|
+
const snapshots = Object.keys(snapshotData).sort(naturalCompare).map((key) => `exports[${printBacktickString(key)}] = ${printBacktickString(normalizeNewlines(snapshotData[key]))};`);
|
1712
|
+
const content = `${environment.getHeader()}\n\n${snapshots.join("\n\n")}\n`;
|
1713
|
+
const oldContent = await environment.readSnapshotFile(snapshotPath);
|
1714
|
+
const skipWriting = oldContent != null && oldContent === content;
|
1715
|
+
if (skipWriting) {
|
1716
|
+
return;
|
1717
|
+
}
|
1718
|
+
await environment.saveSnapshotFile(snapshotPath, content);
|
1753
1719
|
}
|
1754
1720
|
function prepareExpected(expected) {
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1721
|
+
function findStartIndent() {
|
1722
|
+
var _matchObject$, _matchText$;
|
1723
|
+
const matchObject = /^( +)\}\s+$/m.exec(expected || "");
|
1724
|
+
const objectIndent = matchObject === null || matchObject === void 0 || (_matchObject$ = matchObject[1]) === null || _matchObject$ === void 0 ? void 0 : _matchObject$.length;
|
1725
|
+
if (objectIndent) {
|
1726
|
+
return objectIndent;
|
1727
|
+
}
|
1728
|
+
const matchText = /^\n( +)"/.exec(expected || "");
|
1729
|
+
return (matchText === null || matchText === void 0 || (_matchText$ = matchText[1]) === null || _matchText$ === void 0 ? void 0 : _matchText$.length) || 0;
|
1730
|
+
}
|
1731
|
+
const startIndent = findStartIndent();
|
1732
|
+
let expectedTrimmed = expected === null || expected === void 0 ? void 0 : expected.trim();
|
1733
|
+
if (startIndent) {
|
1734
|
+
expectedTrimmed = expectedTrimmed === null || expectedTrimmed === void 0 ? void 0 : expectedTrimmed.replace(new RegExp(`^${" ".repeat(startIndent)}`, "gm"), "").replace(/ +\}$/, "}");
|
1735
|
+
}
|
1736
|
+
return expectedTrimmed;
|
1771
1737
|
}
|
1772
1738
|
function deepMergeArray(target = [], source = []) {
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1739
|
+
const mergedOutput = Array.from(target);
|
1740
|
+
source.forEach((sourceElement, index) => {
|
1741
|
+
const targetElement = mergedOutput[index];
|
1742
|
+
if (Array.isArray(target[index])) {
|
1743
|
+
mergedOutput[index] = deepMergeArray(target[index], sourceElement);
|
1744
|
+
} else if (isObject(targetElement)) {
|
1745
|
+
mergedOutput[index] = deepMergeSnapshot(target[index], sourceElement);
|
1746
|
+
} else {
|
1747
|
+
mergedOutput[index] = sourceElement;
|
1748
|
+
}
|
1749
|
+
});
|
1750
|
+
return mergedOutput;
|
1785
1751
|
}
|
1752
|
+
/**
|
1753
|
+
* Deep merge, but considers asymmetric matchers. Unlike base util's deep merge,
|
1754
|
+
* will merge any object-like instance.
|
1755
|
+
* Compatible with Jest's snapshot matcher. Should not be used outside of snapshot.
|
1756
|
+
*
|
1757
|
+
* @example
|
1758
|
+
* ```ts
|
1759
|
+
* toMatchSnapshot({
|
1760
|
+
* name: expect.stringContaining('text')
|
1761
|
+
* })
|
1762
|
+
* ```
|
1763
|
+
*/
|
1786
1764
|
function deepMergeSnapshot(target, source) {
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1765
|
+
if (isObject(target) && isObject(source)) {
|
1766
|
+
const mergedOutput = { ...target };
|
1767
|
+
Object.keys(source).forEach((key) => {
|
1768
|
+
if (isObject(source[key]) && !source[key].$$typeof) {
|
1769
|
+
if (!(key in target)) {
|
1770
|
+
Object.assign(mergedOutput, { [key]: source[key] });
|
1771
|
+
} else {
|
1772
|
+
mergedOutput[key] = deepMergeSnapshot(target[key], source[key]);
|
1773
|
+
}
|
1774
|
+
} else if (Array.isArray(source[key])) {
|
1775
|
+
mergedOutput[key] = deepMergeArray(target[key], source[key]);
|
1776
|
+
} else {
|
1777
|
+
Object.assign(mergedOutput, { [key]: source[key] });
|
1778
|
+
}
|
1779
|
+
});
|
1780
|
+
return mergedOutput;
|
1781
|
+
} else if (Array.isArray(target) && Array.isArray(source)) {
|
1782
|
+
return deepMergeArray(target, source);
|
1783
|
+
}
|
1784
|
+
return target;
|
1807
1785
|
}
|
1808
1786
|
class DefaultMap extends Map {
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1787
|
+
constructor(defaultFn, entries) {
|
1788
|
+
super(entries);
|
1789
|
+
this.defaultFn = defaultFn;
|
1790
|
+
}
|
1791
|
+
get(key) {
|
1792
|
+
if (!this.has(key)) {
|
1793
|
+
this.set(key, this.defaultFn(key));
|
1794
|
+
}
|
1795
|
+
return super.get(key);
|
1796
|
+
}
|
1819
1797
|
}
|
1820
1798
|
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
|
-
}
|
1799
|
+
constructor() {
|
1800
|
+
super(() => 0);
|
1801
|
+
}
|
1802
|
+
_total;
|
1803
|
+
valueOf() {
|
1804
|
+
return this._total = this.total();
|
1805
|
+
}
|
1806
|
+
increment(key) {
|
1807
|
+
if (typeof this._total !== "undefined") {
|
1808
|
+
this._total++;
|
1809
|
+
}
|
1810
|
+
this.set(key, this.get(key) + 1);
|
1811
|
+
}
|
1812
|
+
total() {
|
1813
|
+
if (typeof this._total !== "undefined") {
|
1814
|
+
return this._total;
|
1815
|
+
}
|
1816
|
+
let total = 0;
|
1817
|
+
for (const x of this.values()) {
|
1818
|
+
total += x;
|
1819
|
+
}
|
1820
|
+
return total;
|
1821
|
+
}
|
1849
1822
|
}
|
1850
1823
|
|
1851
1824
|
function isSameStackPosition(x, y) {
|
1852
|
-
|
1825
|
+
return x.file === y.file && x.column === y.column && x.line === y.line;
|
1853
1826
|
}
|
1854
1827
|
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
|
-
}
|
1828
|
+
_counters = new CounterMap();
|
1829
|
+
_dirty;
|
1830
|
+
_updateSnapshot;
|
1831
|
+
_snapshotData;
|
1832
|
+
_initialData;
|
1833
|
+
_inlineSnapshots;
|
1834
|
+
_inlineSnapshotStacks;
|
1835
|
+
_testIdToKeys = new DefaultMap(() => []);
|
1836
|
+
_rawSnapshots;
|
1837
|
+
_uncheckedKeys;
|
1838
|
+
_snapshotFormat;
|
1839
|
+
_environment;
|
1840
|
+
_fileExists;
|
1841
|
+
expand;
|
1842
|
+
_added = new CounterMap();
|
1843
|
+
_matched = new CounterMap();
|
1844
|
+
_unmatched = new CounterMap();
|
1845
|
+
_updated = new CounterMap();
|
1846
|
+
get added() {
|
1847
|
+
return this._added;
|
1848
|
+
}
|
1849
|
+
set added(value) {
|
1850
|
+
this._added._total = value;
|
1851
|
+
}
|
1852
|
+
get matched() {
|
1853
|
+
return this._matched;
|
1854
|
+
}
|
1855
|
+
set matched(value) {
|
1856
|
+
this._matched._total = value;
|
1857
|
+
}
|
1858
|
+
get unmatched() {
|
1859
|
+
return this._unmatched;
|
1860
|
+
}
|
1861
|
+
set unmatched(value) {
|
1862
|
+
this._unmatched._total = value;
|
1863
|
+
}
|
1864
|
+
get updated() {
|
1865
|
+
return this._updated;
|
1866
|
+
}
|
1867
|
+
set updated(value) {
|
1868
|
+
this._updated._total = value;
|
1869
|
+
}
|
1870
|
+
constructor(testFilePath, snapshotPath, snapshotContent, options) {
|
1871
|
+
this.testFilePath = testFilePath;
|
1872
|
+
this.snapshotPath = snapshotPath;
|
1873
|
+
const { data, dirty } = getSnapshotData(snapshotContent, options);
|
1874
|
+
this._fileExists = snapshotContent != null;
|
1875
|
+
this._initialData = { ...data };
|
1876
|
+
this._snapshotData = { ...data };
|
1877
|
+
this._dirty = dirty;
|
1878
|
+
this._inlineSnapshots = [];
|
1879
|
+
this._inlineSnapshotStacks = [];
|
1880
|
+
this._rawSnapshots = [];
|
1881
|
+
this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
|
1882
|
+
this.expand = options.expand || false;
|
1883
|
+
this._updateSnapshot = options.updateSnapshot;
|
1884
|
+
this._snapshotFormat = {
|
1885
|
+
printBasicPrototype: false,
|
1886
|
+
escapeString: false,
|
1887
|
+
...options.snapshotFormat
|
1888
|
+
};
|
1889
|
+
this._environment = options.snapshotEnvironment;
|
1890
|
+
}
|
1891
|
+
static async create(testFilePath, options) {
|
1892
|
+
const snapshotPath = await options.snapshotEnvironment.resolvePath(testFilePath);
|
1893
|
+
const content = await options.snapshotEnvironment.readSnapshotFile(snapshotPath);
|
1894
|
+
return new SnapshotState(testFilePath, snapshotPath, content, options);
|
1895
|
+
}
|
1896
|
+
get environment() {
|
1897
|
+
return this._environment;
|
1898
|
+
}
|
1899
|
+
markSnapshotsAsCheckedForTest(testName) {
|
1900
|
+
this._uncheckedKeys.forEach((uncheckedKey) => {
|
1901
|
+
if (/ \d+$| > /.test(uncheckedKey.slice(testName.length))) {
|
1902
|
+
this._uncheckedKeys.delete(uncheckedKey);
|
1903
|
+
}
|
1904
|
+
});
|
1905
|
+
}
|
1906
|
+
clearTest(testId) {
|
1907
|
+
this._inlineSnapshots = this._inlineSnapshots.filter((s) => s.testId !== testId);
|
1908
|
+
this._inlineSnapshotStacks = this._inlineSnapshotStacks.filter((s) => s.testId !== testId);
|
1909
|
+
for (const key of this._testIdToKeys.get(testId)) {
|
1910
|
+
const name = keyToTestName(key);
|
1911
|
+
const count = this._counters.get(name);
|
1912
|
+
if (count > 0) {
|
1913
|
+
if (key in this._snapshotData || key in this._initialData) {
|
1914
|
+
this._snapshotData[key] = this._initialData[key];
|
1915
|
+
}
|
1916
|
+
this._counters.set(name, count - 1);
|
1917
|
+
}
|
1918
|
+
}
|
1919
|
+
this._testIdToKeys.delete(testId);
|
1920
|
+
this.added.delete(testId);
|
1921
|
+
this.updated.delete(testId);
|
1922
|
+
this.matched.delete(testId);
|
1923
|
+
this.unmatched.delete(testId);
|
1924
|
+
}
|
1925
|
+
_inferInlineSnapshotStack(stacks) {
|
1926
|
+
const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/));
|
1927
|
+
if (promiseIndex !== -1) {
|
1928
|
+
return stacks[promiseIndex + 3];
|
1929
|
+
}
|
1930
|
+
const stackIndex = stacks.findIndex((i) => i.method.includes("__INLINE_SNAPSHOT__"));
|
1931
|
+
return stackIndex !== -1 ? stacks[stackIndex + 2] : null;
|
1932
|
+
}
|
1933
|
+
_addSnapshot(key, receivedSerialized, options) {
|
1934
|
+
this._dirty = true;
|
1935
|
+
if (options.stack) {
|
1936
|
+
this._inlineSnapshots.push({
|
1937
|
+
snapshot: receivedSerialized,
|
1938
|
+
testId: options.testId,
|
1939
|
+
...options.stack
|
1940
|
+
});
|
1941
|
+
} else if (options.rawSnapshot) {
|
1942
|
+
this._rawSnapshots.push({
|
1943
|
+
...options.rawSnapshot,
|
1944
|
+
snapshot: receivedSerialized
|
1945
|
+
});
|
1946
|
+
} else {
|
1947
|
+
this._snapshotData[key] = receivedSerialized;
|
1948
|
+
}
|
1949
|
+
}
|
1950
|
+
async save() {
|
1951
|
+
const hasExternalSnapshots = Object.keys(this._snapshotData).length;
|
1952
|
+
const hasInlineSnapshots = this._inlineSnapshots.length;
|
1953
|
+
const hasRawSnapshots = this._rawSnapshots.length;
|
1954
|
+
const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots && !hasRawSnapshots;
|
1955
|
+
const status = {
|
1956
|
+
deleted: false,
|
1957
|
+
saved: false
|
1958
|
+
};
|
1959
|
+
if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) {
|
1960
|
+
if (hasExternalSnapshots) {
|
1961
|
+
await saveSnapshotFile(this._environment, this._snapshotData, this.snapshotPath);
|
1962
|
+
this._fileExists = true;
|
1963
|
+
}
|
1964
|
+
if (hasInlineSnapshots) {
|
1965
|
+
await saveInlineSnapshots(this._environment, this._inlineSnapshots);
|
1966
|
+
}
|
1967
|
+
if (hasRawSnapshots) {
|
1968
|
+
await saveRawSnapshots(this._environment, this._rawSnapshots);
|
1969
|
+
}
|
1970
|
+
status.saved = true;
|
1971
|
+
} else if (!hasExternalSnapshots && this._fileExists) {
|
1972
|
+
if (this._updateSnapshot === "all") {
|
1973
|
+
await this._environment.removeSnapshotFile(this.snapshotPath);
|
1974
|
+
this._fileExists = false;
|
1975
|
+
}
|
1976
|
+
status.deleted = true;
|
1977
|
+
}
|
1978
|
+
return status;
|
1979
|
+
}
|
1980
|
+
getUncheckedCount() {
|
1981
|
+
return this._uncheckedKeys.size || 0;
|
1982
|
+
}
|
1983
|
+
getUncheckedKeys() {
|
1984
|
+
return Array.from(this._uncheckedKeys);
|
1985
|
+
}
|
1986
|
+
removeUncheckedKeys() {
|
1987
|
+
if (this._updateSnapshot === "all" && this._uncheckedKeys.size) {
|
1988
|
+
this._dirty = true;
|
1989
|
+
this._uncheckedKeys.forEach((key) => delete this._snapshotData[key]);
|
1990
|
+
this._uncheckedKeys.clear();
|
1991
|
+
}
|
1992
|
+
}
|
1993
|
+
match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot }) {
|
1994
|
+
this._counters.increment(testName);
|
1995
|
+
const count = this._counters.get(testName);
|
1996
|
+
if (!key) {
|
1997
|
+
key = testNameToKey(testName, count);
|
1998
|
+
}
|
1999
|
+
this._testIdToKeys.get(testId).push(key);
|
2000
|
+
if (!(isInline && this._snapshotData[key] !== undefined)) {
|
2001
|
+
this._uncheckedKeys.delete(key);
|
2002
|
+
}
|
2003
|
+
let receivedSerialized = rawSnapshot && typeof received === "string" ? received : serialize(received, undefined, this._snapshotFormat);
|
2004
|
+
if (!rawSnapshot) {
|
2005
|
+
receivedSerialized = addExtraLineBreaks(receivedSerialized);
|
2006
|
+
}
|
2007
|
+
if (rawSnapshot) {
|
2008
|
+
if (rawSnapshot.content && rawSnapshot.content.match(/\r\n/) && !receivedSerialized.match(/\r\n/)) {
|
2009
|
+
rawSnapshot.content = normalizeNewlines(rawSnapshot.content);
|
2010
|
+
}
|
2011
|
+
}
|
2012
|
+
const expected = isInline ? inlineSnapshot : rawSnapshot ? rawSnapshot.content : this._snapshotData[key];
|
2013
|
+
const expectedTrimmed = rawSnapshot ? expected : prepareExpected(expected);
|
2014
|
+
const pass = expectedTrimmed === (rawSnapshot ? receivedSerialized : prepareExpected(receivedSerialized));
|
2015
|
+
const hasSnapshot = expected !== undefined;
|
2016
|
+
const snapshotIsPersisted = isInline || this._fileExists || rawSnapshot && rawSnapshot.content != null;
|
2017
|
+
if (pass && !isInline && !rawSnapshot) {
|
2018
|
+
this._snapshotData[key] = receivedSerialized;
|
2019
|
+
}
|
2020
|
+
let stack;
|
2021
|
+
if (isInline) {
|
2022
|
+
var _this$environment$pro, _this$environment;
|
2023
|
+
const stacks = parseErrorStacktrace(error || new Error("snapshot"), { ignoreStackEntries: [] });
|
2024
|
+
const _stack = this._inferInlineSnapshotStack(stacks);
|
2025
|
+
if (!_stack) {
|
2026
|
+
throw new Error(`@vitest/snapshot: Couldn't infer stack frame for inline snapshot.\n${JSON.stringify(stacks)}`);
|
2027
|
+
}
|
2028
|
+
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;
|
2029
|
+
stack.column--;
|
2030
|
+
const snapshotsWithSameStack = this._inlineSnapshotStacks.filter((s) => isSameStackPosition(s, stack));
|
2031
|
+
if (snapshotsWithSameStack.length > 0) {
|
2032
|
+
this._inlineSnapshots = this._inlineSnapshots.filter((s) => !isSameStackPosition(s, stack));
|
2033
|
+
const differentSnapshot = snapshotsWithSameStack.find((s) => s.snapshot !== receivedSerialized);
|
2034
|
+
if (differentSnapshot) {
|
2035
|
+
throw Object.assign(new Error("toMatchInlineSnapshot with different snapshots cannot be called at the same location"), {
|
2036
|
+
actual: receivedSerialized,
|
2037
|
+
expected: differentSnapshot.snapshot
|
2038
|
+
});
|
2039
|
+
}
|
2040
|
+
}
|
2041
|
+
this._inlineSnapshotStacks.push({
|
2042
|
+
...stack,
|
2043
|
+
testId,
|
2044
|
+
snapshot: receivedSerialized
|
2045
|
+
});
|
2046
|
+
}
|
2047
|
+
if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
|
2048
|
+
if (this._updateSnapshot === "all") {
|
2049
|
+
if (!pass) {
|
2050
|
+
if (hasSnapshot) {
|
2051
|
+
this.updated.increment(testId);
|
2052
|
+
} else {
|
2053
|
+
this.added.increment(testId);
|
2054
|
+
}
|
2055
|
+
this._addSnapshot(key, receivedSerialized, {
|
2056
|
+
stack,
|
2057
|
+
testId,
|
2058
|
+
rawSnapshot
|
2059
|
+
});
|
2060
|
+
} else {
|
2061
|
+
this.matched.increment(testId);
|
2062
|
+
}
|
2063
|
+
} else {
|
2064
|
+
this._addSnapshot(key, receivedSerialized, {
|
2065
|
+
stack,
|
2066
|
+
testId,
|
2067
|
+
rawSnapshot
|
2068
|
+
});
|
2069
|
+
this.added.increment(testId);
|
2070
|
+
}
|
2071
|
+
return {
|
2072
|
+
actual: "",
|
2073
|
+
count,
|
2074
|
+
expected: "",
|
2075
|
+
key,
|
2076
|
+
pass: true
|
2077
|
+
};
|
2078
|
+
} else {
|
2079
|
+
if (!pass) {
|
2080
|
+
this.unmatched.increment(testId);
|
2081
|
+
return {
|
2082
|
+
actual: rawSnapshot ? receivedSerialized : removeExtraLineBreaks(receivedSerialized),
|
2083
|
+
count,
|
2084
|
+
expected: expectedTrimmed !== undefined ? rawSnapshot ? expectedTrimmed : removeExtraLineBreaks(expectedTrimmed) : undefined,
|
2085
|
+
key,
|
2086
|
+
pass: false
|
2087
|
+
};
|
2088
|
+
} else {
|
2089
|
+
this.matched.increment(testId);
|
2090
|
+
return {
|
2091
|
+
actual: "",
|
2092
|
+
count,
|
2093
|
+
expected: "",
|
2094
|
+
key,
|
2095
|
+
pass: true
|
2096
|
+
};
|
2097
|
+
}
|
2098
|
+
}
|
2099
|
+
}
|
2100
|
+
async pack() {
|
2101
|
+
const snapshot = {
|
2102
|
+
filepath: this.testFilePath,
|
2103
|
+
added: 0,
|
2104
|
+
fileDeleted: false,
|
2105
|
+
matched: 0,
|
2106
|
+
unchecked: 0,
|
2107
|
+
uncheckedKeys: [],
|
2108
|
+
unmatched: 0,
|
2109
|
+
updated: 0
|
2110
|
+
};
|
2111
|
+
const uncheckedCount = this.getUncheckedCount();
|
2112
|
+
const uncheckedKeys = this.getUncheckedKeys();
|
2113
|
+
if (uncheckedCount) {
|
2114
|
+
this.removeUncheckedKeys();
|
2115
|
+
}
|
2116
|
+
const status = await this.save();
|
2117
|
+
snapshot.fileDeleted = status.deleted;
|
2118
|
+
snapshot.added = this.added.total();
|
2119
|
+
snapshot.matched = this.matched.total();
|
2120
|
+
snapshot.unmatched = this.unmatched.total();
|
2121
|
+
snapshot.updated = this.updated.total();
|
2122
|
+
snapshot.unchecked = !status.deleted ? uncheckedCount : 0;
|
2123
|
+
snapshot.uncheckedKeys = Array.from(uncheckedKeys);
|
2124
|
+
return snapshot;
|
2125
|
+
}
|
2185
2126
|
}
|
2186
2127
|
|
2187
2128
|
function createMismatchError(message, expand, actual, expected) {
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2129
|
+
const error = new Error(message);
|
2130
|
+
Object.defineProperty(error, "actual", {
|
2131
|
+
value: actual,
|
2132
|
+
enumerable: true,
|
2133
|
+
configurable: true,
|
2134
|
+
writable: true
|
2135
|
+
});
|
2136
|
+
Object.defineProperty(error, "expected", {
|
2137
|
+
value: expected,
|
2138
|
+
enumerable: true,
|
2139
|
+
configurable: true,
|
2140
|
+
writable: true
|
2141
|
+
});
|
2142
|
+
Object.defineProperty(error, "diffOptions", { value: { expand } });
|
2143
|
+
return error;
|
2203
2144
|
}
|
2204
2145
|
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
|
-
}
|
2146
|
+
snapshotStateMap = new Map();
|
2147
|
+
constructor(options = {}) {
|
2148
|
+
this.options = options;
|
2149
|
+
}
|
2150
|
+
async setup(filepath, options) {
|
2151
|
+
if (this.snapshotStateMap.has(filepath)) {
|
2152
|
+
return;
|
2153
|
+
}
|
2154
|
+
this.snapshotStateMap.set(filepath, await SnapshotState.create(filepath, options));
|
2155
|
+
}
|
2156
|
+
async finish(filepath) {
|
2157
|
+
const state = this.getSnapshotState(filepath);
|
2158
|
+
const result = await state.pack();
|
2159
|
+
this.snapshotStateMap.delete(filepath);
|
2160
|
+
return result;
|
2161
|
+
}
|
2162
|
+
skipTest(filepath, testName) {
|
2163
|
+
const state = this.getSnapshotState(filepath);
|
2164
|
+
state.markSnapshotsAsCheckedForTest(testName);
|
2165
|
+
}
|
2166
|
+
clearTest(filepath, testId) {
|
2167
|
+
const state = this.getSnapshotState(filepath);
|
2168
|
+
state.clearTest(testId);
|
2169
|
+
}
|
2170
|
+
getSnapshotState(filepath) {
|
2171
|
+
const state = this.snapshotStateMap.get(filepath);
|
2172
|
+
if (!state) {
|
2173
|
+
throw new Error(`The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`);
|
2174
|
+
}
|
2175
|
+
return state;
|
2176
|
+
}
|
2177
|
+
assert(options) {
|
2178
|
+
const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot } = options;
|
2179
|
+
let { received } = options;
|
2180
|
+
if (!filepath) {
|
2181
|
+
throw new Error("Snapshot cannot be used outside of test");
|
2182
|
+
}
|
2183
|
+
const snapshotState = this.getSnapshotState(filepath);
|
2184
|
+
if (typeof properties === "object") {
|
2185
|
+
if (typeof received !== "object" || !received) {
|
2186
|
+
throw new Error("Received value must be an object when the matcher has properties");
|
2187
|
+
}
|
2188
|
+
try {
|
2189
|
+
var _this$options$isEqual, _this$options;
|
2190
|
+
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;
|
2191
|
+
if (!pass) {
|
2192
|
+
throw createMismatchError("Snapshot properties mismatched", snapshotState.expand, received, properties);
|
2193
|
+
} else {
|
2194
|
+
received = deepMergeSnapshot(received, properties);
|
2195
|
+
}
|
2196
|
+
} catch (err) {
|
2197
|
+
err.message = errorMessage || "Snapshot mismatched";
|
2198
|
+
throw err;
|
2199
|
+
}
|
2200
|
+
}
|
2201
|
+
const testName = [name, ...message ? [message] : []].join(" > ");
|
2202
|
+
const { actual, expected, key, pass } = snapshotState.match({
|
2203
|
+
testId,
|
2204
|
+
testName,
|
2205
|
+
received,
|
2206
|
+
isInline,
|
2207
|
+
error,
|
2208
|
+
inlineSnapshot,
|
2209
|
+
rawSnapshot
|
2210
|
+
});
|
2211
|
+
if (!pass) {
|
2212
|
+
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());
|
2213
|
+
}
|
2214
|
+
}
|
2215
|
+
async assertRaw(options) {
|
2216
|
+
if (!options.rawSnapshot) {
|
2217
|
+
throw new Error("Raw snapshot is required");
|
2218
|
+
}
|
2219
|
+
const { filepath, rawSnapshot } = options;
|
2220
|
+
if (rawSnapshot.content == null) {
|
2221
|
+
if (!filepath) {
|
2222
|
+
throw new Error("Snapshot cannot be used outside of test");
|
2223
|
+
}
|
2224
|
+
const snapshotState = this.getSnapshotState(filepath);
|
2225
|
+
options.filepath || (options.filepath = filepath);
|
2226
|
+
rawSnapshot.file = await snapshotState.environment.resolveRawPath(filepath, rawSnapshot.file);
|
2227
|
+
rawSnapshot.content = await snapshotState.environment.readSnapshotFile(rawSnapshot.file) ?? undefined;
|
2228
|
+
}
|
2229
|
+
return this.assert(options);
|
2230
|
+
}
|
2231
|
+
clear() {
|
2232
|
+
this.snapshotStateMap.clear();
|
2233
|
+
}
|
2324
2234
|
}
|
2325
2235
|
|
2326
2236
|
export { SnapshotClient, SnapshotState, addSerializer, getSerializers, stripSnapshotIndentation };
|