@powerlines/plugin-open-feature 0.1.196 → 0.1.198
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/_virtual/_rolldown/runtime.cjs +0 -14
- package/dist/components/features-builtin.cjs +3 -10
- package/dist/components/features-builtin.mjs +2 -4
- package/dist/components/features-builtin.mjs.map +1 -1
- package/dist/helpers/automd-generator.cjs +0 -8
- package/dist/helpers/automd-generator.mjs +1 -3
- package/dist/helpers/automd-generator.mjs.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +2 -2
- package/package.json +8 -63
- package/dist/_virtual/_rolldown/runtime.mjs +0 -18
- package/dist/components/features-builtin.test.cjs +0 -16
- package/dist/components/features-builtin.test.d.cts +0 -1
- package/dist/components/features-builtin.test.d.mts +0 -1
- package/dist/components/features-builtin.test.mjs +0 -18
- package/dist/components/features-builtin.test.mjs.map +0 -1
- package/dist/helpers/automd-generator.test.cjs +0 -16
- package/dist/helpers/automd-generator.test.d.cts +0 -1
- package/dist/helpers/automd-generator.test.d.mts +0 -1
- package/dist/helpers/automd-generator.test.mjs +0 -18
- package/dist/helpers/automd-generator.test.mjs.map +0 -1
- package/dist/index.test.cjs +0 -30
- package/dist/index.test.d.cts +0 -1
- package/dist/index.test.d.mts +0 -1
- package/dist/index.test.mjs +0 -32
- package/dist/index.test.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.cjs +0 -78
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs +0 -78
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_expect@4.1.7/node_modules/@vitest/expect/dist/index.cjs +0 -1487
- package/dist/node_modules/.pnpm/@vitest_expect@4.1.7/node_modules/@vitest/expect/dist/index.mjs +0 -1473
- package/dist/node_modules/.pnpm/@vitest_expect@4.1.7/node_modules/@vitest/expect/dist/index.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.7/node_modules/@vitest/pretty-format/dist/index.cjs +0 -889
- package/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.7/node_modules/@vitest/pretty-format/dist/index.mjs +0 -888
- package/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.7/node_modules/@vitest/pretty-format/dist/index.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.7/node_modules/@vitest/runner/dist/chunk-artifact.cjs +0 -1614
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.7/node_modules/@vitest/runner/dist/chunk-artifact.mjs +0 -1594
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.7/node_modules/@vitest/runner/dist/chunk-artifact.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.7/node_modules/@vitest/runner/dist/index.cjs +0 -1
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.7/node_modules/@vitest/runner/dist/index.mjs +0 -3
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.7/node_modules/@vitest/runner/dist/utils.cjs +0 -1
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.7/node_modules/@vitest/runner/dist/utils.mjs +0 -3
- package/dist/node_modules/.pnpm/@vitest_snapshot@4.1.7/node_modules/@vitest/snapshot/dist/index.cjs +0 -923
- package/dist/node_modules/.pnpm/@vitest_snapshot@4.1.7/node_modules/@vitest/snapshot/dist/index.mjs +0 -922
- package/dist/node_modules/.pnpm/@vitest_snapshot@4.1.7/node_modules/@vitest/snapshot/dist/index.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_spy@4.1.7/node_modules/@vitest/spy/dist/index.cjs +0 -391
- package/dist/node_modules/.pnpm/@vitest_spy@4.1.7/node_modules/@vitest/spy/dist/index.mjs +0 -386
- package/dist/node_modules/.pnpm/@vitest_spy@4.1.7/node_modules/@vitest/spy/dist/index.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.cjs +0 -82
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs +0 -82
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/diff.cjs +0 -1358
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/diff.mjs +0 -1357
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/diff.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/display.cjs +0 -561
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/display.mjs +0 -559
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/display.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/error.cjs +0 -37
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/error.mjs +0 -38
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/error.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/helpers.cjs +0 -197
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/helpers.mjs +0 -181
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/helpers.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/offset.cjs +0 -29
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/offset.mjs +0 -27
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/offset.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/serialize.cjs +0 -77
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/serialize.mjs +0 -77
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/serialize.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/source-map.cjs +0 -374
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/source-map.mjs +0 -374
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/source-map.mjs.map +0 -1
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/timers.cjs +0 -38
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/timers.mjs +0 -37
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/timers.mjs.map +0 -1
- package/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.cjs +0 -2978
- package/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.mjs +0 -2973
- package/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.mjs.map +0 -1
- package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.cjs +0 -939
- package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.mjs +0 -940
- package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.mjs.map +0 -1
- package/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.cjs +0 -87
- package/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.mjs +0 -87
- package/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.mjs.map +0 -1
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.cjs +0 -6
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs +0 -6
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.mjs.map +0 -1
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/rpc.MzXet3jl.cjs +0 -54
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs +0 -52
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/rpc.MzXet3jl.mjs.map +0 -1
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/test.DNmyFkvJ.cjs +0 -2696
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs +0 -2697
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/test.DNmyFkvJ.mjs.map +0 -1
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.cjs +0 -47
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs +0 -45
- package/dist/node_modules/.pnpm/vitest@4.1.7_@opentelemetry_api@1.9.1_@types_node@25.9.1_@vitest_coverage-v8@4.1.7_vite_34dd47607c0af5e5ae7f1b2f95fc48c3/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.mjs.map +0 -1
package/dist/node_modules/.pnpm/@vitest_snapshot@4.1.7/node_modules/@vitest/snapshot/dist/index.cjs
DELETED
|
@@ -1,923 +0,0 @@
|
|
|
1
|
-
const require_index = require('../../../../../@vitest_pretty-format@4.1.7/node_modules/@vitest/pretty-format/dist/index.cjs');
|
|
2
|
-
const require_helpers = require('../../../../../@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/helpers.cjs');
|
|
3
|
-
const require_source_map = require('../../../../../@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/source-map.cjs');
|
|
4
|
-
const require_offset = require('../../../../../@vitest_utils@4.1.7/node_modules/@vitest/utils/dist/offset.cjs');
|
|
5
|
-
|
|
6
|
-
//#region ../../../node_modules/.pnpm/@vitest+snapshot@4.1.7/node_modules/@vitest/snapshot/dist/index.js
|
|
7
|
-
function getDefaultExportFromCjs(x) {
|
|
8
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
9
|
-
}
|
|
10
|
-
var naturalCompare$1 = { exports: {} };
|
|
11
|
-
var hasRequiredNaturalCompare;
|
|
12
|
-
function requireNaturalCompare() {
|
|
13
|
-
if (hasRequiredNaturalCompare) return naturalCompare$1.exports;
|
|
14
|
-
hasRequiredNaturalCompare = 1;
|
|
15
|
-
/*
|
|
16
|
-
* @version 1.4.0
|
|
17
|
-
* @date 2015-10-26
|
|
18
|
-
* @stability 3 - Stable
|
|
19
|
-
* @author Lauri Rooden (https://github.com/litejs/natural-compare-lite)
|
|
20
|
-
* @license MIT License
|
|
21
|
-
*/
|
|
22
|
-
var naturalCompare = function(a, b) {
|
|
23
|
-
var i, codeA, codeB = 1, posA = 0, posB = 0, alphabet = String.alphabet;
|
|
24
|
-
function getCode(str, pos, code) {
|
|
25
|
-
if (code) {
|
|
26
|
-
for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i;
|
|
27
|
-
return +str.slice(pos - 1, i);
|
|
28
|
-
}
|
|
29
|
-
code = alphabet && alphabet.indexOf(str.charAt(pos));
|
|
30
|
-
return code > -1 ? code + 76 : (code = str.charCodeAt(pos) || 0, code < 45 || code > 127) ? code : code < 46 ? 65 : code < 48 ? code - 1 : code < 58 ? code + 18 : code < 65 ? code - 11 : code < 91 ? code + 11 : code < 97 ? code - 37 : code < 123 ? code + 5 : code - 63;
|
|
31
|
-
}
|
|
32
|
-
if ((a += "") != (b += "")) for (; codeB;) {
|
|
33
|
-
codeA = getCode(a, posA++);
|
|
34
|
-
codeB = getCode(b, posB++);
|
|
35
|
-
if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) {
|
|
36
|
-
codeA = getCode(a, posA, posA);
|
|
37
|
-
codeB = getCode(b, posB, posA = i);
|
|
38
|
-
posB = i;
|
|
39
|
-
}
|
|
40
|
-
if (codeA != codeB) return codeA < codeB ? -1 : 1;
|
|
41
|
-
}
|
|
42
|
-
return 0;
|
|
43
|
-
};
|
|
44
|
-
try {
|
|
45
|
-
naturalCompare$1.exports = naturalCompare;
|
|
46
|
-
} catch (e) {
|
|
47
|
-
String.naturalCompare = naturalCompare;
|
|
48
|
-
}
|
|
49
|
-
return naturalCompare$1.exports;
|
|
50
|
-
}
|
|
51
|
-
var naturalCompare = /*@__PURE__*/ getDefaultExportFromCjs(requireNaturalCompare());
|
|
52
|
-
const serialize$1 = (val, config, indentation, depth, refs, printer) => {
|
|
53
|
-
const name = val.getMockName();
|
|
54
|
-
const nameString = name === "vi.fn()" ? "" : ` ${name}`;
|
|
55
|
-
let callsString = "";
|
|
56
|
-
if (val.mock.calls.length !== 0) {
|
|
57
|
-
const indentationNext = indentation + config.indent;
|
|
58
|
-
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}}`;
|
|
59
|
-
}
|
|
60
|
-
return `[MockFunction${nameString}]${callsString}`;
|
|
61
|
-
};
|
|
62
|
-
const test = (val) => val && !!val._isMockFunction;
|
|
63
|
-
const plugin = {
|
|
64
|
-
serialize: serialize$1,
|
|
65
|
-
test
|
|
66
|
-
};
|
|
67
|
-
const { DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent, AsymmetricMatcher } = require_index.plugins;
|
|
68
|
-
let PLUGINS = [
|
|
69
|
-
ReactTestComponent,
|
|
70
|
-
ReactElement,
|
|
71
|
-
DOMElement,
|
|
72
|
-
DOMCollection,
|
|
73
|
-
Immutable,
|
|
74
|
-
AsymmetricMatcher,
|
|
75
|
-
plugin
|
|
76
|
-
];
|
|
77
|
-
function addSerializer(plugin) {
|
|
78
|
-
PLUGINS = [plugin].concat(PLUGINS);
|
|
79
|
-
}
|
|
80
|
-
function getSerializers() {
|
|
81
|
-
return PLUGINS;
|
|
82
|
-
}
|
|
83
|
-
function testNameToKey(testName, count) {
|
|
84
|
-
return `${testName} ${count}`;
|
|
85
|
-
}
|
|
86
|
-
function keyToTestName(key) {
|
|
87
|
-
if (!/ \d+$/.test(key)) throw new Error("Snapshot keys must end with a number.");
|
|
88
|
-
return key.replace(/ \d+$/, "");
|
|
89
|
-
}
|
|
90
|
-
function getSnapshotData(content, options) {
|
|
91
|
-
const update = options.updateSnapshot;
|
|
92
|
-
const data = Object.create(null);
|
|
93
|
-
let snapshotContents = "";
|
|
94
|
-
let dirty = false;
|
|
95
|
-
if (content != null) try {
|
|
96
|
-
snapshotContents = content;
|
|
97
|
-
new Function("exports", snapshotContents)(data);
|
|
98
|
-
} catch {}
|
|
99
|
-
if ((update === "all" || update === "new") && snapshotContents) dirty = true;
|
|
100
|
-
return {
|
|
101
|
-
data,
|
|
102
|
-
dirty
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
function addExtraLineBreaks(string) {
|
|
106
|
-
return string.includes("\n") ? `\n${string}\n` : string;
|
|
107
|
-
}
|
|
108
|
-
function removeExtraLineBreaks(string) {
|
|
109
|
-
return string.length > 2 && string[0] === "\n" && string.endsWith("\n") ? string.slice(1, -1) : string;
|
|
110
|
-
}
|
|
111
|
-
const escapeRegex = true;
|
|
112
|
-
const printFunctionName = false;
|
|
113
|
-
function serialize(val, indent = 2, formatOverrides = {}) {
|
|
114
|
-
return normalizeNewlines(require_index.format(val, {
|
|
115
|
-
escapeRegex,
|
|
116
|
-
indent,
|
|
117
|
-
plugins: getSerializers(),
|
|
118
|
-
printFunctionName,
|
|
119
|
-
...formatOverrides
|
|
120
|
-
}));
|
|
121
|
-
}
|
|
122
|
-
function escapeBacktickString(str) {
|
|
123
|
-
return str.replace(/`|\\|\$\{/g, "\\$&");
|
|
124
|
-
}
|
|
125
|
-
function printBacktickString(str) {
|
|
126
|
-
return `\`${escapeBacktickString(str)}\``;
|
|
127
|
-
}
|
|
128
|
-
function normalizeNewlines(string) {
|
|
129
|
-
return string.replace(/\r\n|\r/g, "\n");
|
|
130
|
-
}
|
|
131
|
-
async function saveSnapshotFile(environment, snapshotData, snapshotPath) {
|
|
132
|
-
const snapshots = Object.keys(snapshotData).sort(naturalCompare).map((key) => `exports[${printBacktickString(key)}] = ${printBacktickString(normalizeNewlines(snapshotData[key]))};`);
|
|
133
|
-
const content = `${environment.getHeader()}\n\n${snapshots.join("\n\n")}\n`;
|
|
134
|
-
const oldContent = await environment.readSnapshotFile(snapshotPath);
|
|
135
|
-
if (oldContent != null && oldContent === content) return;
|
|
136
|
-
await environment.saveSnapshotFile(snapshotPath, content);
|
|
137
|
-
}
|
|
138
|
-
function deepMergeArray(target = [], source = []) {
|
|
139
|
-
const mergedOutput = Array.from(target);
|
|
140
|
-
source.forEach((sourceElement, index) => {
|
|
141
|
-
const targetElement = mergedOutput[index];
|
|
142
|
-
if (Array.isArray(target[index])) mergedOutput[index] = deepMergeArray(target[index], sourceElement);
|
|
143
|
-
else if (require_helpers.isObject(targetElement)) mergedOutput[index] = deepMergeSnapshot(target[index], sourceElement);
|
|
144
|
-
else mergedOutput[index] = sourceElement;
|
|
145
|
-
});
|
|
146
|
-
return mergedOutput;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Deep merge, but considers asymmetric matchers. Unlike base util's deep merge,
|
|
150
|
-
* will merge any object-like instance.
|
|
151
|
-
* Compatible with Jest's snapshot matcher. Should not be used outside of snapshot.
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
* ```ts
|
|
155
|
-
* toMatchSnapshot({
|
|
156
|
-
* name: expect.stringContaining('text')
|
|
157
|
-
* })
|
|
158
|
-
* ```
|
|
159
|
-
*/
|
|
160
|
-
function deepMergeSnapshot(target, source) {
|
|
161
|
-
if (require_helpers.isObject(target) && require_helpers.isObject(source)) {
|
|
162
|
-
const mergedOutput = { ...target };
|
|
163
|
-
Object.keys(source).forEach((key) => {
|
|
164
|
-
if (require_helpers.isObject(source[key]) && !source[key].$$typeof) if (!(key in target)) Object.assign(mergedOutput, { [key]: source[key] });
|
|
165
|
-
else mergedOutput[key] = deepMergeSnapshot(target[key], source[key]);
|
|
166
|
-
else if (Array.isArray(source[key])) mergedOutput[key] = deepMergeArray(target[key], source[key]);
|
|
167
|
-
else Object.assign(mergedOutput, { [key]: source[key] });
|
|
168
|
-
});
|
|
169
|
-
return mergedOutput;
|
|
170
|
-
} else if (Array.isArray(target) && Array.isArray(source)) return deepMergeArray(target, source);
|
|
171
|
-
return target;
|
|
172
|
-
}
|
|
173
|
-
var DefaultMap = class extends Map {
|
|
174
|
-
constructor(defaultFn, entries) {
|
|
175
|
-
super(entries);
|
|
176
|
-
this.defaultFn = defaultFn;
|
|
177
|
-
}
|
|
178
|
-
get(key) {
|
|
179
|
-
if (!this.has(key)) this.set(key, this.defaultFn(key));
|
|
180
|
-
return super.get(key);
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
var CounterMap = class extends DefaultMap {
|
|
184
|
-
constructor() {
|
|
185
|
-
super(() => 0);
|
|
186
|
-
}
|
|
187
|
-
_total;
|
|
188
|
-
valueOf() {
|
|
189
|
-
return this._total = this.total();
|
|
190
|
-
}
|
|
191
|
-
increment(key) {
|
|
192
|
-
if (typeof this._total !== "undefined") this._total++;
|
|
193
|
-
this.set(key, this.get(key) + 1);
|
|
194
|
-
}
|
|
195
|
-
total() {
|
|
196
|
-
if (typeof this._total !== "undefined") return this._total;
|
|
197
|
-
let total = 0;
|
|
198
|
-
for (const x of this.values()) total += x;
|
|
199
|
-
return total;
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
203
|
-
function memo(fn) {
|
|
204
|
-
const cache = /* @__PURE__ */ new Map();
|
|
205
|
-
return (arg) => {
|
|
206
|
-
if (!cache.has(arg)) cache.set(arg, fn(arg));
|
|
207
|
-
return cache.get(arg);
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
async function saveInlineSnapshots(environment, snapshots) {
|
|
211
|
-
const MagicString = (await Promise.resolve().then(() => require("../../../../../magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.cjs"))).default;
|
|
212
|
-
const files = new Set(snapshots.map((i) => i.file));
|
|
213
|
-
await Promise.all(Array.from(files).map(async (file) => {
|
|
214
|
-
const snaps = snapshots.filter((i) => i.file === file);
|
|
215
|
-
const code = await environment.readSnapshotFile(file);
|
|
216
|
-
if (code == null) throw new Error(`cannot read ${file} when saving inline snapshot`);
|
|
217
|
-
const s = new MagicString(code);
|
|
218
|
-
for (const snap of snaps) replaceInlineSnap(code, s, require_offset.positionToOffset(code, snap.line, snap.column), snap.snapshot, snap.assertionName);
|
|
219
|
-
const transformed = s.toString();
|
|
220
|
-
if (transformed !== code) await environment.saveSnapshotFile(file, transformed);
|
|
221
|
-
}));
|
|
222
|
-
}
|
|
223
|
-
const defaultStartObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*\{/;
|
|
224
|
-
function escapeRegExp(s) {
|
|
225
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
226
|
-
}
|
|
227
|
-
const buildStartObjectRegex = /* @__PURE__ */ memo((assertionName) => {
|
|
228
|
-
const replaced = defaultStartObjectRegex.source.replace("toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot", escapeRegExp(assertionName));
|
|
229
|
-
return new RegExp(replaced);
|
|
230
|
-
});
|
|
231
|
-
function replaceObjectSnap(code, s, index, newSnap, assertionName) {
|
|
232
|
-
let _code = code.slice(index);
|
|
233
|
-
const startMatch = (assertionName ? buildStartObjectRegex(assertionName) : defaultStartObjectRegex).exec(_code);
|
|
234
|
-
if (!startMatch) return false;
|
|
235
|
-
_code = _code.slice(startMatch.index);
|
|
236
|
-
let callEnd = require_helpers.getCallLastIndex(_code);
|
|
237
|
-
if (callEnd === null) return false;
|
|
238
|
-
callEnd += index + startMatch.index;
|
|
239
|
-
const shapeEnd = getObjectShapeEndIndex(code, index + startMatch.index + startMatch[0].length);
|
|
240
|
-
const snap = `, ${prepareSnapString(newSnap, code, index)}`;
|
|
241
|
-
if (shapeEnd === callEnd) s.appendLeft(callEnd, snap);
|
|
242
|
-
else s.overwrite(shapeEnd, callEnd, snap);
|
|
243
|
-
return true;
|
|
244
|
-
}
|
|
245
|
-
function getObjectShapeEndIndex(code, index) {
|
|
246
|
-
let startBraces = 1;
|
|
247
|
-
let endBraces = 0;
|
|
248
|
-
while (startBraces !== endBraces && index < code.length) {
|
|
249
|
-
const s = code[index++];
|
|
250
|
-
if (s === "{") startBraces++;
|
|
251
|
-
else if (s === "}") endBraces++;
|
|
252
|
-
}
|
|
253
|
-
return index;
|
|
254
|
-
}
|
|
255
|
-
function prepareSnapString(snap, source, index) {
|
|
256
|
-
const lineNumber = require_offset.offsetToLineNumber(source, index);
|
|
257
|
-
const indent = source.split(require_offset.lineSplitRE)[lineNumber - 1].match(/^\s*/)[0] || "";
|
|
258
|
-
const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `;
|
|
259
|
-
const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
|
|
260
|
-
const isOneline = lines.length <= 1;
|
|
261
|
-
const quote = "`";
|
|
262
|
-
if (isOneline) return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}${quote}`;
|
|
263
|
-
return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}\n${indent}${quote}`;
|
|
264
|
-
}
|
|
265
|
-
const defaultMethodNames = ["toMatchInlineSnapshot", "toThrowErrorMatchingInlineSnapshot"];
|
|
266
|
-
function getCodeStartingAtIndex(code, index, methodNames) {
|
|
267
|
-
for (const name of methodNames) {
|
|
268
|
-
const adjusted = index - name.length;
|
|
269
|
-
if (adjusted >= 0 && code.slice(adjusted, index) === name) return {
|
|
270
|
-
code: code.slice(adjusted),
|
|
271
|
-
index: adjusted
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
code: code.slice(index),
|
|
276
|
-
index
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
const defaultStartRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*[\w$]*(['"`)])/;
|
|
280
|
-
const buildStartRegex = /* @__PURE__ */ memo((assertionName) => {
|
|
281
|
-
const replaced = defaultStartRegex.source.replace("toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot", escapeRegExp(assertionName));
|
|
282
|
-
return new RegExp(replaced);
|
|
283
|
-
});
|
|
284
|
-
function replaceInlineSnap(code, s, currentIndex, newSnap, assertionName) {
|
|
285
|
-
const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex, assertionName ? [assertionName] : defaultMethodNames);
|
|
286
|
-
const startMatch = (assertionName ? buildStartRegex(assertionName) : defaultStartRegex).exec(codeStartingAtIndex);
|
|
287
|
-
const firstKeywordMatch = (assertionName ? new RegExp(escapeRegExp(assertionName)) : /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/).exec(codeStartingAtIndex);
|
|
288
|
-
if (!startMatch || startMatch.index !== firstKeywordMatch?.index) return replaceObjectSnap(code, s, index, newSnap, assertionName);
|
|
289
|
-
const quote = startMatch[1];
|
|
290
|
-
const startIndex = index + startMatch.index + startMatch[0].length;
|
|
291
|
-
const snapString = prepareSnapString(newSnap, code, index);
|
|
292
|
-
if (quote === ")") {
|
|
293
|
-
s.appendRight(startIndex - 1, snapString);
|
|
294
|
-
return true;
|
|
295
|
-
}
|
|
296
|
-
const endMatch = new RegExp(`(?:^|[^\\\\])${quote}`).exec(code.slice(startIndex));
|
|
297
|
-
if (!endMatch) return false;
|
|
298
|
-
const endIndex = startIndex + endMatch.index + endMatch[0].length;
|
|
299
|
-
s.overwrite(startIndex - 1, endIndex, snapString);
|
|
300
|
-
return true;
|
|
301
|
-
}
|
|
302
|
-
const INDENTATION_REGEX = /^([^\S\n]*)\S/m;
|
|
303
|
-
function stripSnapshotIndentation(inlineSnapshot) {
|
|
304
|
-
const match = inlineSnapshot.match(INDENTATION_REGEX);
|
|
305
|
-
if (!match || !match[1]) return inlineSnapshot;
|
|
306
|
-
const indentation = match[1];
|
|
307
|
-
const lines = inlineSnapshot.split(/\n/g);
|
|
308
|
-
if (lines.length <= 2) return inlineSnapshot;
|
|
309
|
-
if (lines[0].trim() !== "" || lines.at(-1)?.trim() !== "") return inlineSnapshot;
|
|
310
|
-
for (let i = 1; i < lines.length - 1; i++) if (lines[i] !== "") {
|
|
311
|
-
if (lines[i].indexOf(indentation) !== 0) return inlineSnapshot;
|
|
312
|
-
lines[i] = lines[i].substring(indentation.length);
|
|
313
|
-
}
|
|
314
|
-
lines[lines.length - 1] = "";
|
|
315
|
-
inlineSnapshot = lines.join("\n");
|
|
316
|
-
return inlineSnapshot;
|
|
317
|
-
}
|
|
318
|
-
async function saveRawSnapshots(environment, snapshots) {
|
|
319
|
-
await Promise.all(snapshots.map(async (snap) => {
|
|
320
|
-
if (!snap.readonly) await environment.saveSnapshotFile(snap.file, snap.snapshot);
|
|
321
|
-
}));
|
|
322
|
-
}
|
|
323
|
-
function isSameStackPosition(x, y) {
|
|
324
|
-
return x.file === y.file && x.column === y.column && x.line === y.line;
|
|
325
|
-
}
|
|
326
|
-
var SnapshotState = class SnapshotState {
|
|
327
|
-
_counters = new CounterMap();
|
|
328
|
-
_dirty;
|
|
329
|
-
_updateSnapshot;
|
|
330
|
-
_snapshotData;
|
|
331
|
-
_initialData;
|
|
332
|
-
_inlineSnapshots;
|
|
333
|
-
_inlineSnapshotStacks;
|
|
334
|
-
_testIdToKeys = new DefaultMap(() => []);
|
|
335
|
-
_rawSnapshots;
|
|
336
|
-
_uncheckedKeys;
|
|
337
|
-
_snapshotFormat;
|
|
338
|
-
_environment;
|
|
339
|
-
_fileExists;
|
|
340
|
-
expand;
|
|
341
|
-
_added = new CounterMap();
|
|
342
|
-
_matched = new CounterMap();
|
|
343
|
-
_unmatched = new CounterMap();
|
|
344
|
-
_updated = new CounterMap();
|
|
345
|
-
get added() {
|
|
346
|
-
return this._added;
|
|
347
|
-
}
|
|
348
|
-
set added(value) {
|
|
349
|
-
this._added._total = value;
|
|
350
|
-
}
|
|
351
|
-
get matched() {
|
|
352
|
-
return this._matched;
|
|
353
|
-
}
|
|
354
|
-
set matched(value) {
|
|
355
|
-
this._matched._total = value;
|
|
356
|
-
}
|
|
357
|
-
get unmatched() {
|
|
358
|
-
return this._unmatched;
|
|
359
|
-
}
|
|
360
|
-
set unmatched(value) {
|
|
361
|
-
this._unmatched._total = value;
|
|
362
|
-
}
|
|
363
|
-
get updated() {
|
|
364
|
-
return this._updated;
|
|
365
|
-
}
|
|
366
|
-
set updated(value) {
|
|
367
|
-
this._updated._total = value;
|
|
368
|
-
}
|
|
369
|
-
constructor(testFilePath, snapshotPath, snapshotContent, options) {
|
|
370
|
-
this.testFilePath = testFilePath;
|
|
371
|
-
this.snapshotPath = snapshotPath;
|
|
372
|
-
const { data, dirty } = getSnapshotData(snapshotContent, options);
|
|
373
|
-
this._fileExists = snapshotContent != null;
|
|
374
|
-
this._initialData = { ...data };
|
|
375
|
-
this._snapshotData = { ...data };
|
|
376
|
-
this._dirty = dirty;
|
|
377
|
-
this._inlineSnapshots = [];
|
|
378
|
-
this._inlineSnapshotStacks = [];
|
|
379
|
-
this._rawSnapshots = [];
|
|
380
|
-
this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
|
|
381
|
-
this.expand = options.expand || false;
|
|
382
|
-
this._updateSnapshot = options.updateSnapshot;
|
|
383
|
-
this._snapshotFormat = {
|
|
384
|
-
printBasicPrototype: false,
|
|
385
|
-
escapeString: false,
|
|
386
|
-
maxOutputLength: 2 ** 27,
|
|
387
|
-
...options.snapshotFormat
|
|
388
|
-
};
|
|
389
|
-
this._environment = options.snapshotEnvironment;
|
|
390
|
-
}
|
|
391
|
-
static async create(testFilePath, options) {
|
|
392
|
-
const snapshotPath = await options.snapshotEnvironment.resolvePath(testFilePath);
|
|
393
|
-
return new SnapshotState(testFilePath, snapshotPath, await options.snapshotEnvironment.readSnapshotFile(snapshotPath), options);
|
|
394
|
-
}
|
|
395
|
-
get snapshotUpdateState() {
|
|
396
|
-
return this._updateSnapshot;
|
|
397
|
-
}
|
|
398
|
-
get environment() {
|
|
399
|
-
return this._environment;
|
|
400
|
-
}
|
|
401
|
-
markSnapshotsAsCheckedForTest(testName) {
|
|
402
|
-
this._uncheckedKeys.forEach((uncheckedKey) => {
|
|
403
|
-
if (/ \d+$| > /.test(uncheckedKey.slice(testName.length))) this._uncheckedKeys.delete(uncheckedKey);
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
clearTest(testId) {
|
|
407
|
-
this._inlineSnapshots = this._inlineSnapshots.filter((s) => s.testId !== testId);
|
|
408
|
-
this._inlineSnapshotStacks = this._inlineSnapshotStacks.filter((s) => s.testId !== testId);
|
|
409
|
-
for (const key of this._testIdToKeys.get(testId)) {
|
|
410
|
-
const name = keyToTestName(key);
|
|
411
|
-
const count = this._counters.get(name);
|
|
412
|
-
if (count > 0) {
|
|
413
|
-
if (key in this._snapshotData || key in this._initialData) this._snapshotData[key] = this._initialData[key];
|
|
414
|
-
this._counters.set(name, count - 1);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
this._testIdToKeys.delete(testId);
|
|
418
|
-
this.added.delete(testId);
|
|
419
|
-
this.updated.delete(testId);
|
|
420
|
-
this.matched.delete(testId);
|
|
421
|
-
this.unmatched.delete(testId);
|
|
422
|
-
}
|
|
423
|
-
_inferInlineSnapshotStack(stacks) {
|
|
424
|
-
const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/));
|
|
425
|
-
if (promiseIndex !== -1) return stacks[promiseIndex + 3];
|
|
426
|
-
const pollChainIndex = stacks.findIndex((i) => i.method.match(/__VITEST_POLL_CHAIN__/));
|
|
427
|
-
if (pollChainIndex !== -1) return stacks[pollChainIndex + 1];
|
|
428
|
-
for (let i = 0; i < stacks.length; i++) {
|
|
429
|
-
const match = stacks[i].method.match(/__INLINE_SNAPSHOT_OFFSET_(\d+)__/);
|
|
430
|
-
if (match) return stacks[i + Number(match[1])] ?? null;
|
|
431
|
-
}
|
|
432
|
-
const customMatcherIndex = stacks.findIndex((i) => i.method.includes("__VITEST_EXTEND_ASSERTION__"));
|
|
433
|
-
if (customMatcherIndex !== -1) return stacks[customMatcherIndex + 3] ?? null;
|
|
434
|
-
const stackIndex = stacks.findIndex((i) => i.method.includes("__INLINE_SNAPSHOT__"));
|
|
435
|
-
return stackIndex !== -1 ? stacks[stackIndex + 2] : null;
|
|
436
|
-
}
|
|
437
|
-
_addSnapshot(key, receivedSerialized, options) {
|
|
438
|
-
this._dirty = true;
|
|
439
|
-
if (options.stack) this._inlineSnapshots.push({
|
|
440
|
-
...options.stack,
|
|
441
|
-
snapshot: receivedSerialized,
|
|
442
|
-
testId: options.testId,
|
|
443
|
-
assertionName: options.assertionName
|
|
444
|
-
});
|
|
445
|
-
else if (options.rawSnapshot) this._rawSnapshots.push({
|
|
446
|
-
...options.rawSnapshot,
|
|
447
|
-
snapshot: receivedSerialized
|
|
448
|
-
});
|
|
449
|
-
else this._snapshotData[key] = receivedSerialized;
|
|
450
|
-
}
|
|
451
|
-
_resolveKey(testId, testName, key) {
|
|
452
|
-
this._counters.increment(testName);
|
|
453
|
-
const count = this._counters.get(testName);
|
|
454
|
-
if (!key) key = testNameToKey(testName, count);
|
|
455
|
-
this._testIdToKeys.get(testId).push(key);
|
|
456
|
-
return {
|
|
457
|
-
key,
|
|
458
|
-
count
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
_resolveInlineStack(options) {
|
|
462
|
-
const { testId, snapshot, assertionName, error } = options;
|
|
463
|
-
const stacks = require_source_map.parseErrorStacktrace(error, { ignoreStackEntries: [] });
|
|
464
|
-
const _stack = this._inferInlineSnapshotStack(stacks);
|
|
465
|
-
if (!_stack) {
|
|
466
|
-
const message = stacks.map((s) => ` ${s.file}:${s.line}:${s.column}${s.method ? ` (${s.method})` : ""}`).join("\n");
|
|
467
|
-
throw new Error(`@vitest/snapshot: Couldn't infer stack frame for inline snapshot.\n${message}`);
|
|
468
|
-
}
|
|
469
|
-
const stack = this.environment.processStackTrace?.(_stack) || _stack;
|
|
470
|
-
stack.column--;
|
|
471
|
-
const snapshotsWithSameStack = this._inlineSnapshotStacks.filter((s) => isSameStackPosition(s, stack));
|
|
472
|
-
if (snapshotsWithSameStack.length > 0) {
|
|
473
|
-
this._inlineSnapshots = this._inlineSnapshots.filter((s) => !isSameStackPosition(s, stack));
|
|
474
|
-
const differentSnapshot = snapshotsWithSameStack.find((s) => s.snapshot !== snapshot);
|
|
475
|
-
if (differentSnapshot) throw Object.assign(/* @__PURE__ */ new Error(`${assertionName} with different snapshots cannot be called at the same location`), {
|
|
476
|
-
actual: snapshot,
|
|
477
|
-
expected: differentSnapshot.snapshot
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
this._inlineSnapshotStacks.push({
|
|
481
|
-
...stack,
|
|
482
|
-
testId,
|
|
483
|
-
snapshot
|
|
484
|
-
});
|
|
485
|
-
return stack;
|
|
486
|
-
}
|
|
487
|
-
_reconcile(opts) {
|
|
488
|
-
if (opts.hasSnapshot && this._updateSnapshot === "all" || (!opts.hasSnapshot || !opts.snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
|
|
489
|
-
if (this._updateSnapshot === "all") if (!opts.pass) {
|
|
490
|
-
if (opts.hasSnapshot) this.updated.increment(opts.testId);
|
|
491
|
-
else this.added.increment(opts.testId);
|
|
492
|
-
this._addSnapshot(opts.key, opts.addValue, {
|
|
493
|
-
stack: opts.stack,
|
|
494
|
-
testId: opts.testId,
|
|
495
|
-
rawSnapshot: opts.rawSnapshot,
|
|
496
|
-
assertionName: opts.assertionName
|
|
497
|
-
});
|
|
498
|
-
} else this.matched.increment(opts.testId);
|
|
499
|
-
else {
|
|
500
|
-
this._addSnapshot(opts.key, opts.addValue, {
|
|
501
|
-
stack: opts.stack,
|
|
502
|
-
testId: opts.testId,
|
|
503
|
-
rawSnapshot: opts.rawSnapshot,
|
|
504
|
-
assertionName: opts.assertionName
|
|
505
|
-
});
|
|
506
|
-
this.added.increment(opts.testId);
|
|
507
|
-
}
|
|
508
|
-
return {
|
|
509
|
-
actual: "",
|
|
510
|
-
count: opts.count,
|
|
511
|
-
expected: "",
|
|
512
|
-
key: opts.key,
|
|
513
|
-
pass: true
|
|
514
|
-
};
|
|
515
|
-
} else if (!opts.pass) {
|
|
516
|
-
this.unmatched.increment(opts.testId);
|
|
517
|
-
return {
|
|
518
|
-
actual: opts.actualDisplay,
|
|
519
|
-
count: opts.count,
|
|
520
|
-
expected: opts.expectedDisplay,
|
|
521
|
-
key: opts.key,
|
|
522
|
-
pass: false
|
|
523
|
-
};
|
|
524
|
-
} else {
|
|
525
|
-
this.matched.increment(opts.testId);
|
|
526
|
-
return {
|
|
527
|
-
actual: "",
|
|
528
|
-
count: opts.count,
|
|
529
|
-
expected: "",
|
|
530
|
-
key: opts.key,
|
|
531
|
-
pass: true
|
|
532
|
-
};
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
async save() {
|
|
536
|
-
const hasExternalSnapshots = Object.keys(this._snapshotData).length;
|
|
537
|
-
const hasInlineSnapshots = this._inlineSnapshots.length;
|
|
538
|
-
const hasRawSnapshots = this._rawSnapshots.length;
|
|
539
|
-
const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots && !hasRawSnapshots;
|
|
540
|
-
const status = {
|
|
541
|
-
deleted: false,
|
|
542
|
-
saved: false
|
|
543
|
-
};
|
|
544
|
-
if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) {
|
|
545
|
-
if (hasExternalSnapshots) {
|
|
546
|
-
await saveSnapshotFile(this._environment, this._snapshotData, this.snapshotPath);
|
|
547
|
-
this._fileExists = true;
|
|
548
|
-
}
|
|
549
|
-
if (hasInlineSnapshots) await saveInlineSnapshots(this._environment, this._inlineSnapshots);
|
|
550
|
-
if (hasRawSnapshots) await saveRawSnapshots(this._environment, this._rawSnapshots);
|
|
551
|
-
status.saved = true;
|
|
552
|
-
} else if (!hasExternalSnapshots && this._fileExists) {
|
|
553
|
-
if (this._updateSnapshot === "all") {
|
|
554
|
-
await this._environment.removeSnapshotFile(this.snapshotPath);
|
|
555
|
-
this._fileExists = false;
|
|
556
|
-
}
|
|
557
|
-
status.deleted = true;
|
|
558
|
-
}
|
|
559
|
-
return status;
|
|
560
|
-
}
|
|
561
|
-
getUncheckedCount() {
|
|
562
|
-
return this._uncheckedKeys.size || 0;
|
|
563
|
-
}
|
|
564
|
-
getUncheckedKeys() {
|
|
565
|
-
return Array.from(this._uncheckedKeys);
|
|
566
|
-
}
|
|
567
|
-
removeUncheckedKeys() {
|
|
568
|
-
if (this._updateSnapshot === "all" && this._uncheckedKeys.size) {
|
|
569
|
-
this._dirty = true;
|
|
570
|
-
this._uncheckedKeys.forEach((key) => delete this._snapshotData[key]);
|
|
571
|
-
this._uncheckedKeys.clear();
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
probeExpectedSnapshot(options) {
|
|
575
|
-
const count = this._counters.get(options.testName) + 1;
|
|
576
|
-
const key = testNameToKey(options.testName, count);
|
|
577
|
-
return {
|
|
578
|
-
key,
|
|
579
|
-
count,
|
|
580
|
-
data: options?.isInline ? options.inlineSnapshot : this._snapshotData[key],
|
|
581
|
-
markAsChecked: () => {
|
|
582
|
-
this._counters.increment(options.testName);
|
|
583
|
-
this._testIdToKeys.get(options.testId).push(key);
|
|
584
|
-
this._uncheckedKeys.delete(key);
|
|
585
|
-
}
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot, assertionName }) {
|
|
589
|
-
const resolved = this._resolveKey(testId, testName, key);
|
|
590
|
-
key = resolved.key;
|
|
591
|
-
const count = resolved.count;
|
|
592
|
-
if (!(isInline && this._snapshotData[key] !== void 0)) this._uncheckedKeys.delete(key);
|
|
593
|
-
let receivedSerialized = rawSnapshot && typeof received === "string" ? received : serialize(received, void 0, this._snapshotFormat);
|
|
594
|
-
if (!rawSnapshot) receivedSerialized = addExtraLineBreaks(receivedSerialized);
|
|
595
|
-
if (rawSnapshot) {
|
|
596
|
-
if (rawSnapshot.content && rawSnapshot.content.match(/\r\n/) && !receivedSerialized.match(/\r\n/)) rawSnapshot.content = normalizeNewlines(rawSnapshot.content);
|
|
597
|
-
}
|
|
598
|
-
const expected = isInline ? inlineSnapshot : rawSnapshot ? rawSnapshot.content : this._snapshotData[key];
|
|
599
|
-
const expectedTrimmed = rawSnapshot ? expected : expected?.trim();
|
|
600
|
-
const pass = expectedTrimmed === (rawSnapshot ? receivedSerialized : receivedSerialized.trim());
|
|
601
|
-
const hasSnapshot = expected !== void 0;
|
|
602
|
-
const snapshotIsPersisted = isInline || this._fileExists || rawSnapshot && rawSnapshot.content != null;
|
|
603
|
-
if (pass && !isInline && !rawSnapshot) this._snapshotData[key] = receivedSerialized;
|
|
604
|
-
const stack = isInline ? this._resolveInlineStack({
|
|
605
|
-
testId,
|
|
606
|
-
snapshot: receivedSerialized,
|
|
607
|
-
assertionName: assertionName || "toMatchInlineSnapshot",
|
|
608
|
-
error: error || /* @__PURE__ */ new Error("snapshot")
|
|
609
|
-
}) : void 0;
|
|
610
|
-
return this._reconcile({
|
|
611
|
-
testId,
|
|
612
|
-
key,
|
|
613
|
-
count,
|
|
614
|
-
pass,
|
|
615
|
-
hasSnapshot,
|
|
616
|
-
snapshotIsPersisted: !!snapshotIsPersisted,
|
|
617
|
-
addValue: receivedSerialized,
|
|
618
|
-
actualDisplay: rawSnapshot ? receivedSerialized : removeExtraLineBreaks(receivedSerialized),
|
|
619
|
-
expectedDisplay: expectedTrimmed !== void 0 ? rawSnapshot ? expectedTrimmed : removeExtraLineBreaks(expectedTrimmed) : void 0,
|
|
620
|
-
stack,
|
|
621
|
-
rawSnapshot,
|
|
622
|
-
assertionName
|
|
623
|
-
});
|
|
624
|
-
}
|
|
625
|
-
processDomainSnapshot({ testId, received, expectedSnapshot, matchResult, isInline, error, assertionName }) {
|
|
626
|
-
const stack = isInline ? this._resolveInlineStack({
|
|
627
|
-
testId,
|
|
628
|
-
snapshot: received,
|
|
629
|
-
assertionName,
|
|
630
|
-
error: error || /* @__PURE__ */ new Error("STACK_TRACE_ERROR")
|
|
631
|
-
}) : void 0;
|
|
632
|
-
const actualResolved = matchResult?.resolved ?? received;
|
|
633
|
-
const expectedResolved = matchResult?.expected ?? expectedSnapshot.data;
|
|
634
|
-
return this._reconcile({
|
|
635
|
-
testId,
|
|
636
|
-
key: expectedSnapshot.key,
|
|
637
|
-
count: expectedSnapshot.count,
|
|
638
|
-
pass: matchResult?.pass ?? false,
|
|
639
|
-
hasSnapshot: !!expectedSnapshot.data,
|
|
640
|
-
snapshotIsPersisted: isInline ? true : this._fileExists,
|
|
641
|
-
addValue: actualResolved,
|
|
642
|
-
actualDisplay: removeExtraLineBreaks(actualResolved),
|
|
643
|
-
expectedDisplay: expectedResolved !== void 0 ? removeExtraLineBreaks(expectedResolved) : void 0,
|
|
644
|
-
stack,
|
|
645
|
-
assertionName
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
async pack() {
|
|
649
|
-
const snapshot = {
|
|
650
|
-
filepath: this.testFilePath,
|
|
651
|
-
added: 0,
|
|
652
|
-
fileDeleted: false,
|
|
653
|
-
matched: 0,
|
|
654
|
-
unchecked: 0,
|
|
655
|
-
uncheckedKeys: [],
|
|
656
|
-
unmatched: 0,
|
|
657
|
-
updated: 0
|
|
658
|
-
};
|
|
659
|
-
const uncheckedCount = this.getUncheckedCount();
|
|
660
|
-
const uncheckedKeys = this.getUncheckedKeys();
|
|
661
|
-
if (uncheckedCount) this.removeUncheckedKeys();
|
|
662
|
-
const status = await this.save();
|
|
663
|
-
snapshot.fileDeleted = status.deleted;
|
|
664
|
-
snapshot.added = this.added.total();
|
|
665
|
-
snapshot.matched = this.matched.total();
|
|
666
|
-
snapshot.unmatched = this.unmatched.total();
|
|
667
|
-
snapshot.updated = this.updated.total();
|
|
668
|
-
snapshot.unchecked = !status.deleted ? uncheckedCount : 0;
|
|
669
|
-
snapshot.uncheckedKeys = Array.from(uncheckedKeys);
|
|
670
|
-
return snapshot;
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
function createMismatchError(message, expand, actual, expected) {
|
|
674
|
-
const error = new Error(message);
|
|
675
|
-
Object.defineProperty(error, "actual", {
|
|
676
|
-
value: actual,
|
|
677
|
-
enumerable: true,
|
|
678
|
-
configurable: true,
|
|
679
|
-
writable: true
|
|
680
|
-
});
|
|
681
|
-
Object.defineProperty(error, "expected", {
|
|
682
|
-
value: expected,
|
|
683
|
-
enumerable: true,
|
|
684
|
-
configurable: true,
|
|
685
|
-
writable: true
|
|
686
|
-
});
|
|
687
|
-
Object.defineProperty(error, "diffOptions", { value: { expand } });
|
|
688
|
-
return error;
|
|
689
|
-
}
|
|
690
|
-
var SnapshotClient = class {
|
|
691
|
-
snapshotStateMap = /* @__PURE__ */ new Map();
|
|
692
|
-
constructor(options = {}) {
|
|
693
|
-
this.options = options;
|
|
694
|
-
}
|
|
695
|
-
async setup(filepath, options) {
|
|
696
|
-
if (this.snapshotStateMap.has(filepath)) return;
|
|
697
|
-
this.snapshotStateMap.set(filepath, await SnapshotState.create(filepath, options));
|
|
698
|
-
}
|
|
699
|
-
async finish(filepath) {
|
|
700
|
-
const result = await this.getSnapshotState(filepath).pack();
|
|
701
|
-
this.snapshotStateMap.delete(filepath);
|
|
702
|
-
return result;
|
|
703
|
-
}
|
|
704
|
-
skipTest(filepath, testName) {
|
|
705
|
-
this.getSnapshotState(filepath).markSnapshotsAsCheckedForTest(testName);
|
|
706
|
-
}
|
|
707
|
-
clearTest(filepath, testId) {
|
|
708
|
-
this.getSnapshotState(filepath).clearTest(testId);
|
|
709
|
-
}
|
|
710
|
-
getSnapshotState(filepath) {
|
|
711
|
-
const state = this.snapshotStateMap.get(filepath);
|
|
712
|
-
if (!state) throw new Error(`The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`);
|
|
713
|
-
return state;
|
|
714
|
-
}
|
|
715
|
-
match(options) {
|
|
716
|
-
const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot, assertionName } = options;
|
|
717
|
-
let { received } = options;
|
|
718
|
-
if (!filepath) throw new Error("Snapshot cannot be used outside of test");
|
|
719
|
-
const snapshotState = this.getSnapshotState(filepath);
|
|
720
|
-
const testName = [name, ...message ? [message] : []].join(" > ");
|
|
721
|
-
const expectedSnapshot = snapshotState.probeExpectedSnapshot({
|
|
722
|
-
testName,
|
|
723
|
-
testId,
|
|
724
|
-
isInline,
|
|
725
|
-
inlineSnapshot
|
|
726
|
-
});
|
|
727
|
-
if (typeof properties === "object") {
|
|
728
|
-
if (typeof received !== "object" || !received) {
|
|
729
|
-
expectedSnapshot.markAsChecked();
|
|
730
|
-
throw new Error("Received value must be an object when the matcher has properties");
|
|
731
|
-
}
|
|
732
|
-
let propertiesPass;
|
|
733
|
-
try {
|
|
734
|
-
propertiesPass = this.options.isEqual?.(received, properties) ?? false;
|
|
735
|
-
} catch (err) {
|
|
736
|
-
expectedSnapshot.markAsChecked();
|
|
737
|
-
throw err;
|
|
738
|
-
}
|
|
739
|
-
if (!propertiesPass) {
|
|
740
|
-
expectedSnapshot.markAsChecked();
|
|
741
|
-
return {
|
|
742
|
-
pass: false,
|
|
743
|
-
message: () => errorMessage || "Snapshot properties mismatched",
|
|
744
|
-
actual: received,
|
|
745
|
-
expected: properties
|
|
746
|
-
};
|
|
747
|
-
}
|
|
748
|
-
received = deepMergeSnapshot(received, properties);
|
|
749
|
-
}
|
|
750
|
-
const { actual, expected, key, pass } = snapshotState.match({
|
|
751
|
-
testId,
|
|
752
|
-
testName,
|
|
753
|
-
received,
|
|
754
|
-
isInline,
|
|
755
|
-
error,
|
|
756
|
-
inlineSnapshot,
|
|
757
|
-
rawSnapshot,
|
|
758
|
-
assertionName
|
|
759
|
-
});
|
|
760
|
-
return {
|
|
761
|
-
pass,
|
|
762
|
-
message: () => `Snapshot \`${key || "unknown"}\` mismatched`,
|
|
763
|
-
actual: rawSnapshot ? actual : actual?.trim(),
|
|
764
|
-
expected: rawSnapshot ? expected : expected?.trim()
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
assert(options) {
|
|
768
|
-
const result = this.match(options);
|
|
769
|
-
if (!result.pass) {
|
|
770
|
-
const snapshotState = this.getSnapshotState(options.filepath);
|
|
771
|
-
throw createMismatchError(result.message(), snapshotState.expand, result.actual, result.expected);
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
matchDomain(options) {
|
|
775
|
-
const { received, filepath, name, testId = name, message, adapter, isInline = false, inlineSnapshot, error } = options;
|
|
776
|
-
if (!filepath) throw new Error("Snapshot cannot be used outside of test");
|
|
777
|
-
const captured = adapter.capture(received);
|
|
778
|
-
const rendered = adapter.render(captured);
|
|
779
|
-
const snapshotState = this.getSnapshotState(filepath);
|
|
780
|
-
const testName = [name, ...message ? [message] : []].join(" > ");
|
|
781
|
-
const expectedSnapshot = snapshotState.probeExpectedSnapshot({
|
|
782
|
-
testName,
|
|
783
|
-
testId,
|
|
784
|
-
isInline,
|
|
785
|
-
inlineSnapshot
|
|
786
|
-
});
|
|
787
|
-
expectedSnapshot.markAsChecked();
|
|
788
|
-
const matchResult = expectedSnapshot.data ? adapter.match(captured, adapter.parseExpected(expectedSnapshot.data)) : void 0;
|
|
789
|
-
const { actual, expected, key, pass } = snapshotState.processDomainSnapshot({
|
|
790
|
-
testId,
|
|
791
|
-
received: rendered,
|
|
792
|
-
expectedSnapshot,
|
|
793
|
-
matchResult,
|
|
794
|
-
isInline,
|
|
795
|
-
error,
|
|
796
|
-
assertionName: options.assertionName
|
|
797
|
-
});
|
|
798
|
-
return {
|
|
799
|
-
pass,
|
|
800
|
-
message: () => `Snapshot \`${key}\` mismatched`,
|
|
801
|
-
actual: actual?.trim(),
|
|
802
|
-
expected: expected?.trim()
|
|
803
|
-
};
|
|
804
|
-
}
|
|
805
|
-
async pollMatchDomain(options) {
|
|
806
|
-
const { poll, filepath, name, testId = name, message, adapter, isInline = false, inlineSnapshot, error, timeout = 1e3, interval = 50 } = options;
|
|
807
|
-
if (!filepath) throw new Error("Snapshot cannot be used outside of test");
|
|
808
|
-
const snapshotState = this.getSnapshotState(filepath);
|
|
809
|
-
const testName = [name, ...message ? [message] : []].join(" > ");
|
|
810
|
-
const expectedSnapshot = snapshotState.probeExpectedSnapshot({
|
|
811
|
-
testName,
|
|
812
|
-
testId,
|
|
813
|
-
isInline,
|
|
814
|
-
inlineSnapshot
|
|
815
|
-
});
|
|
816
|
-
const reference = expectedSnapshot.data && snapshotState.snapshotUpdateState !== "all" ? adapter.parseExpected(expectedSnapshot.data) : void 0;
|
|
817
|
-
const stableResult = await getStableSnapshot({
|
|
818
|
-
adapter,
|
|
819
|
-
poll,
|
|
820
|
-
interval,
|
|
821
|
-
timedOut: timeout > 0 ? new Promise((r) => setTimeout(r, timeout)) : void 0,
|
|
822
|
-
match: reference ? (captured) => adapter.match(captured, reference).pass : void 0
|
|
823
|
-
});
|
|
824
|
-
expectedSnapshot.markAsChecked();
|
|
825
|
-
if (!stableResult?.rendered) {
|
|
826
|
-
if (stableResult?.lastPollError) throw stableResult.lastPollError;
|
|
827
|
-
return {
|
|
828
|
-
pass: false,
|
|
829
|
-
message: () => `poll() did not produce a stable snapshot within the timeout`
|
|
830
|
-
};
|
|
831
|
-
}
|
|
832
|
-
const matchResult = expectedSnapshot.data ? adapter.match(stableResult.captured, adapter.parseExpected(expectedSnapshot.data)) : void 0;
|
|
833
|
-
const { actual, expected, key, pass } = snapshotState.processDomainSnapshot({
|
|
834
|
-
testId,
|
|
835
|
-
received: stableResult.rendered,
|
|
836
|
-
expectedSnapshot,
|
|
837
|
-
matchResult,
|
|
838
|
-
isInline,
|
|
839
|
-
error,
|
|
840
|
-
assertionName: options.assertionName
|
|
841
|
-
});
|
|
842
|
-
return {
|
|
843
|
-
pass,
|
|
844
|
-
message: () => `Snapshot \`${key}\` mismatched`,
|
|
845
|
-
actual: actual?.trim(),
|
|
846
|
-
expected: expected?.trim()
|
|
847
|
-
};
|
|
848
|
-
}
|
|
849
|
-
async assertRaw(options) {
|
|
850
|
-
if (!options.rawSnapshot) throw new Error("Raw snapshot is required");
|
|
851
|
-
const { filepath, rawSnapshot } = options;
|
|
852
|
-
if (rawSnapshot.content == null) {
|
|
853
|
-
if (!filepath) throw new Error("Snapshot cannot be used outside of test");
|
|
854
|
-
const snapshotState = this.getSnapshotState(filepath);
|
|
855
|
-
options.filepath ||= filepath;
|
|
856
|
-
rawSnapshot.file = await snapshotState.environment.resolveRawPath(filepath, rawSnapshot.file);
|
|
857
|
-
rawSnapshot.content = await snapshotState.environment.readSnapshotFile(rawSnapshot.file) ?? void 0;
|
|
858
|
-
}
|
|
859
|
-
return this.assert(options);
|
|
860
|
-
}
|
|
861
|
-
clear() {
|
|
862
|
-
this.snapshotStateMap.clear();
|
|
863
|
-
}
|
|
864
|
-
};
|
|
865
|
-
/**
|
|
866
|
-
* Polls repeatedly until the value reaches a stable state.
|
|
867
|
-
*
|
|
868
|
-
* Compares consecutive rendered outputs from the current session —
|
|
869
|
-
* when two consecutive polls produce the same rendered string,
|
|
870
|
-
* the value is considered stable.
|
|
871
|
-
*
|
|
872
|
-
* Every `await` (poll call, interval delay) races against `timedOut`
|
|
873
|
-
* so that hanging polls and delays are interrupted.
|
|
874
|
-
*/
|
|
875
|
-
async function getStableSnapshot({ adapter, poll, interval, timedOut, match }) {
|
|
876
|
-
let lastRendered;
|
|
877
|
-
let lastPollError;
|
|
878
|
-
let lastStable;
|
|
879
|
-
while (true) {
|
|
880
|
-
try {
|
|
881
|
-
const pollResult = await raceWith(Promise.resolve(poll()), timedOut);
|
|
882
|
-
if (!pollResult.ok) break;
|
|
883
|
-
const captured = adapter.capture(pollResult.value);
|
|
884
|
-
const rendered = adapter.render(captured);
|
|
885
|
-
if (lastRendered !== void 0 && rendered === lastRendered) {
|
|
886
|
-
lastStable = {
|
|
887
|
-
captured,
|
|
888
|
-
rendered
|
|
889
|
-
};
|
|
890
|
-
if (!match || match(captured)) break;
|
|
891
|
-
} else {
|
|
892
|
-
lastRendered = rendered;
|
|
893
|
-
lastStable = void 0;
|
|
894
|
-
}
|
|
895
|
-
} catch (pollError) {
|
|
896
|
-
lastRendered = void 0;
|
|
897
|
-
lastStable = void 0;
|
|
898
|
-
lastPollError = pollError;
|
|
899
|
-
}
|
|
900
|
-
if (!(await raceWith(new Promise((r) => setTimeout(r, interval)), timedOut)).ok) break;
|
|
901
|
-
}
|
|
902
|
-
return {
|
|
903
|
-
...lastStable,
|
|
904
|
-
lastPollError
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
/** Type-safe `Promise.race` — tells you which promise won. */
|
|
908
|
-
function raceWith(promise, other) {
|
|
909
|
-
const left = promise.then((value) => ({
|
|
910
|
-
ok: true,
|
|
911
|
-
value
|
|
912
|
-
}));
|
|
913
|
-
if (!other) return left;
|
|
914
|
-
return Promise.race([left, other.then((value) => ({
|
|
915
|
-
ok: false,
|
|
916
|
-
value
|
|
917
|
-
}))]);
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
//#endregion
|
|
921
|
-
exports.SnapshotClient = SnapshotClient;
|
|
922
|
-
exports.addSerializer = addSerializer;
|
|
923
|
-
exports.stripSnapshotIndentation = stripSnapshotIndentation;
|