@antdv-next/x-sdk 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/chat-providers/types/model.d.ts +1 -1
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +76 -0
- package/dist/node_modules/{vitest/dist/@vitest/expect → .pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist}/index.js +76 -51
- package/dist/node_modules/{vitest/dist/@vitest/pretty-format → .pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist}/index.js +11 -10
- package/dist/node_modules/{vitest/dist/@vitest/runner → .pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist}/chunk-artifact.js +18 -41
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +2 -0
- package/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +2 -0
- package/dist/node_modules/{vitest/dist/@vitest/snapshot → .pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist}/index.js +455 -195
- package/dist/node_modules/{vitest/dist/@vitest/spy → .pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist}/index.js +3 -3
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/chunk-pathe.M-eThtNZ.js +2 -2
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/diff.js +40 -30
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/display.js +3 -3
- package/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +34 -0
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/helpers.js +3 -3
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/offset.js +1 -1
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/serialize.js +1 -1
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/source-map.js +6 -6
- package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/timers.js +1 -1
- package/dist/node_modules/{vitest/dist/vendor/chai.js → .pnpm/chai@6.2.2/node_modules/chai/index.js} +103 -3
- package/dist/node_modules/{vitest/dist/vendor/magic-string.js → .pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js} +4 -76
- package/dist/node_modules/.pnpm/tinyrainbow@3.1.1/node_modules/tinyrainbow/dist/index.js +84 -0
- package/dist/node_modules/.pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +4 -0
- package/dist/node_modules/{vitest → .pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest}/dist/chunks/rpc.MzXet3jl.js +2 -2
- package/dist/node_modules/{vitest/dist/chunks/test.CBQUpOM3.js → .pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js} +383 -327
- package/dist/node_modules/{vitest → .pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest}/dist/chunks/utils.BX5Fg8C4.js +3 -3
- package/dist/x-chat/__tests__/index.test.js +3 -2
- package/dist/x-chat/index.js +3 -2
- package/dist/x-conversations/__tests__/index.test.js +2 -2
- package/dist/x-request/__tests__/index.test.js +2 -2
- package/dist/x-stream/__tests__/index.test.d.ts +1 -0
- package/dist/x-stream/__tests__/index.test.js +62 -0
- package/dist/x-stream/index.js +16 -5
- package/package.json +2 -1
- package/dist/node_modules/vitest/dist/@vitest/utils/error.js +0 -27
- package/dist/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -4
- package/dist/node_modules/vitest/dist/vendor/tinyrainbow.js +0 -84
|
@@ -1,114 +1,8 @@
|
|
|
1
|
-
import { format, plugins } from "
|
|
2
|
-
import { getCallLastIndex, isObject } from "
|
|
3
|
-
import { parseErrorStacktrace } from "
|
|
4
|
-
import { lineSplitRE, offsetToLineNumber, positionToOffset } from "
|
|
5
|
-
//#region ../../node_modules
|
|
6
|
-
async function saveInlineSnapshots(environment, snapshots) {
|
|
7
|
-
const MagicString = (await import("../../vendor/magic-string.js")).default;
|
|
8
|
-
const files = new Set(snapshots.map((i) => i.file));
|
|
9
|
-
await Promise.all(Array.from(files).map(async (file) => {
|
|
10
|
-
const snaps = snapshots.filter((i) => i.file === file);
|
|
11
|
-
const code = await environment.readSnapshotFile(file);
|
|
12
|
-
if (code == null) throw new Error(`cannot read ${file} when saving inline snapshot`);
|
|
13
|
-
const s = new MagicString(code);
|
|
14
|
-
for (const snap of snaps) replaceInlineSnap(code, s, positionToOffset(code, snap.line, snap.column), snap.snapshot);
|
|
15
|
-
const transformed = s.toString();
|
|
16
|
-
if (transformed !== code) await environment.saveSnapshotFile(file, transformed);
|
|
17
|
-
}));
|
|
18
|
-
}
|
|
19
|
-
var startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*\{/;
|
|
20
|
-
function replaceObjectSnap(code, s, index, newSnap) {
|
|
21
|
-
let _code = code.slice(index);
|
|
22
|
-
const startMatch = startObjectRegex.exec(_code);
|
|
23
|
-
if (!startMatch) return false;
|
|
24
|
-
_code = _code.slice(startMatch.index);
|
|
25
|
-
let callEnd = getCallLastIndex(_code);
|
|
26
|
-
if (callEnd === null) return false;
|
|
27
|
-
callEnd += index + startMatch.index;
|
|
28
|
-
const shapeEnd = getObjectShapeEndIndex(code, index + startMatch.index + startMatch[0].length);
|
|
29
|
-
const snap = `, ${prepareSnapString(newSnap, code, index)}`;
|
|
30
|
-
if (shapeEnd === callEnd) s.appendLeft(callEnd, snap);
|
|
31
|
-
else s.overwrite(shapeEnd, callEnd, snap);
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
function getObjectShapeEndIndex(code, index) {
|
|
35
|
-
let startBraces = 1;
|
|
36
|
-
let endBraces = 0;
|
|
37
|
-
while (startBraces !== endBraces && index < code.length) {
|
|
38
|
-
const s = code[index++];
|
|
39
|
-
if (s === "{") startBraces++;
|
|
40
|
-
else if (s === "}") endBraces++;
|
|
41
|
-
}
|
|
42
|
-
return index;
|
|
43
|
-
}
|
|
44
|
-
function prepareSnapString(snap, source, index) {
|
|
45
|
-
const lineNumber = offsetToLineNumber(source, index);
|
|
46
|
-
const indent = source.split(lineSplitRE)[lineNumber - 1].match(/^\s*/)[0] || "";
|
|
47
|
-
const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `;
|
|
48
|
-
const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
|
|
49
|
-
const isOneline = lines.length <= 1;
|
|
50
|
-
const quote = "`";
|
|
51
|
-
if (isOneline) return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}${quote}`;
|
|
52
|
-
return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}\n${indent}${quote}`;
|
|
53
|
-
}
|
|
54
|
-
var toMatchInlineName = "toMatchInlineSnapshot";
|
|
55
|
-
var toThrowErrorMatchingInlineName = "toThrowErrorMatchingInlineSnapshot";
|
|
56
|
-
function getCodeStartingAtIndex(code, index) {
|
|
57
|
-
const indexInline = index - 21;
|
|
58
|
-
if (code.slice(indexInline, index) === toMatchInlineName) return {
|
|
59
|
-
code: code.slice(indexInline),
|
|
60
|
-
index: indexInline
|
|
61
|
-
};
|
|
62
|
-
const indexThrowInline = index - 34;
|
|
63
|
-
if (code.slice(index - indexThrowInline, index) === toThrowErrorMatchingInlineName) return {
|
|
64
|
-
code: code.slice(index - indexThrowInline),
|
|
65
|
-
index: index - indexThrowInline
|
|
66
|
-
};
|
|
67
|
-
return {
|
|
68
|
-
code: code.slice(index),
|
|
69
|
-
index
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
var 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$]*(['"`)])/;
|
|
73
|
-
function replaceInlineSnap(code, s, currentIndex, newSnap) {
|
|
74
|
-
const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex);
|
|
75
|
-
const startMatch = startRegex.exec(codeStartingAtIndex);
|
|
76
|
-
const firstKeywordMatch = /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/.exec(codeStartingAtIndex);
|
|
77
|
-
if (!startMatch || startMatch.index !== firstKeywordMatch?.index) return replaceObjectSnap(code, s, index, newSnap);
|
|
78
|
-
const quote = startMatch[1];
|
|
79
|
-
const startIndex = index + startMatch.index + startMatch[0].length;
|
|
80
|
-
const snapString = prepareSnapString(newSnap, code, index);
|
|
81
|
-
if (quote === ")") {
|
|
82
|
-
s.appendRight(startIndex - 1, snapString);
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
const endMatch = new RegExp(`(?:^|[^\\\\])${quote}`).exec(code.slice(startIndex));
|
|
86
|
-
if (!endMatch) return false;
|
|
87
|
-
const endIndex = startIndex + endMatch.index + endMatch[0].length;
|
|
88
|
-
s.overwrite(startIndex - 1, endIndex, snapString);
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
var INDENTATION_REGEX = /^([^\S\n]*)\S/m;
|
|
92
|
-
function stripSnapshotIndentation(inlineSnapshot) {
|
|
93
|
-
const match = inlineSnapshot.match(INDENTATION_REGEX);
|
|
94
|
-
if (!match || !match[1]) return inlineSnapshot;
|
|
95
|
-
const indentation = match[1];
|
|
96
|
-
const lines = inlineSnapshot.split(/\n/g);
|
|
97
|
-
if (lines.length <= 2) return inlineSnapshot;
|
|
98
|
-
if (lines[0].trim() !== "" || lines.at(-1)?.trim() !== "") return inlineSnapshot;
|
|
99
|
-
for (let i = 1; i < lines.length - 1; i++) if (lines[i] !== "") {
|
|
100
|
-
if (lines[i].indexOf(indentation) !== 0) return inlineSnapshot;
|
|
101
|
-
lines[i] = lines[i].substring(indentation.length);
|
|
102
|
-
}
|
|
103
|
-
lines[lines.length - 1] = "";
|
|
104
|
-
inlineSnapshot = lines.join("\n");
|
|
105
|
-
return inlineSnapshot;
|
|
106
|
-
}
|
|
107
|
-
async function saveRawSnapshots(environment, snapshots) {
|
|
108
|
-
await Promise.all(snapshots.map(async (snap) => {
|
|
109
|
-
if (!snap.readonly) await environment.saveSnapshotFile(snap.file, snap.snapshot);
|
|
110
|
-
}));
|
|
111
|
-
}
|
|
1
|
+
import { format, plugins } from "../../../../../@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js";
|
|
2
|
+
import { getCallLastIndex, isObject } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js";
|
|
3
|
+
import { parseErrorStacktrace } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js";
|
|
4
|
+
import { lineSplitRE, offsetToLineNumber, positionToOffset } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js";
|
|
5
|
+
//#region ../../node_modules/.pnpm/@vitest+snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js
|
|
112
6
|
function getDefaultExportFromCjs(x) {
|
|
113
7
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
114
8
|
}
|
|
@@ -153,7 +47,7 @@ function requireNaturalCompare() {
|
|
|
153
47
|
}
|
|
154
48
|
return naturalCompare$1.exports;
|
|
155
49
|
}
|
|
156
|
-
var naturalCompare =
|
|
50
|
+
var naturalCompare = /*@__PURE__*/ getDefaultExportFromCjs(requireNaturalCompare());
|
|
157
51
|
var serialize$1 = (val, config, indentation, depth, refs, printer) => {
|
|
158
52
|
const name = val.getMockName();
|
|
159
53
|
const nameString = name === "vi.fn()" ? "" : ` ${name}`;
|
|
@@ -304,6 +198,127 @@ var CounterMap = class extends DefaultMap {
|
|
|
304
198
|
return total;
|
|
305
199
|
}
|
|
306
200
|
};
|
|
201
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
202
|
+
function memo(fn) {
|
|
203
|
+
const cache = /* @__PURE__ */ new Map();
|
|
204
|
+
return (arg) => {
|
|
205
|
+
if (!cache.has(arg)) cache.set(arg, fn(arg));
|
|
206
|
+
return cache.get(arg);
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
async function saveInlineSnapshots(environment, snapshots) {
|
|
210
|
+
const MagicString = (await import("../../../../../magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js")).default;
|
|
211
|
+
const files = new Set(snapshots.map((i) => i.file));
|
|
212
|
+
await Promise.all(Array.from(files).map(async (file) => {
|
|
213
|
+
const snaps = snapshots.filter((i) => i.file === file);
|
|
214
|
+
const code = await environment.readSnapshotFile(file);
|
|
215
|
+
if (code == null) throw new Error(`cannot read ${file} when saving inline snapshot`);
|
|
216
|
+
const s = new MagicString(code);
|
|
217
|
+
for (const snap of snaps) replaceInlineSnap(code, s, positionToOffset(code, snap.line, snap.column), snap.snapshot, snap.assertionName);
|
|
218
|
+
const transformed = s.toString();
|
|
219
|
+
if (transformed !== code) await environment.saveSnapshotFile(file, transformed);
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
222
|
+
var defaultStartObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*\{/;
|
|
223
|
+
function escapeRegExp(s) {
|
|
224
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
225
|
+
}
|
|
226
|
+
var buildStartObjectRegex = /* @__PURE__ */ memo((assertionName) => {
|
|
227
|
+
const replaced = defaultStartObjectRegex.source.replace("toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot", escapeRegExp(assertionName));
|
|
228
|
+
return new RegExp(replaced);
|
|
229
|
+
});
|
|
230
|
+
function replaceObjectSnap(code, s, index, newSnap, assertionName) {
|
|
231
|
+
let _code = code.slice(index);
|
|
232
|
+
const startMatch = (assertionName ? buildStartObjectRegex(assertionName) : defaultStartObjectRegex).exec(_code);
|
|
233
|
+
if (!startMatch) return false;
|
|
234
|
+
_code = _code.slice(startMatch.index);
|
|
235
|
+
let callEnd = getCallLastIndex(_code);
|
|
236
|
+
if (callEnd === null) return false;
|
|
237
|
+
callEnd += index + startMatch.index;
|
|
238
|
+
const shapeEnd = getObjectShapeEndIndex(code, index + startMatch.index + startMatch[0].length);
|
|
239
|
+
const snap = `, ${prepareSnapString(newSnap, code, index)}`;
|
|
240
|
+
if (shapeEnd === callEnd) s.appendLeft(callEnd, snap);
|
|
241
|
+
else s.overwrite(shapeEnd, callEnd, snap);
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
function getObjectShapeEndIndex(code, index) {
|
|
245
|
+
let startBraces = 1;
|
|
246
|
+
let endBraces = 0;
|
|
247
|
+
while (startBraces !== endBraces && index < code.length) {
|
|
248
|
+
const s = code[index++];
|
|
249
|
+
if (s === "{") startBraces++;
|
|
250
|
+
else if (s === "}") endBraces++;
|
|
251
|
+
}
|
|
252
|
+
return index;
|
|
253
|
+
}
|
|
254
|
+
function prepareSnapString(snap, source, index) {
|
|
255
|
+
const lineNumber = offsetToLineNumber(source, index);
|
|
256
|
+
const indent = source.split(lineSplitRE)[lineNumber - 1].match(/^\s*/)[0] || "";
|
|
257
|
+
const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `;
|
|
258
|
+
const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
|
|
259
|
+
const isOneline = lines.length <= 1;
|
|
260
|
+
const quote = "`";
|
|
261
|
+
if (isOneline) return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}${quote}`;
|
|
262
|
+
return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}\n${indent}${quote}`;
|
|
263
|
+
}
|
|
264
|
+
var defaultMethodNames = ["toMatchInlineSnapshot", "toThrowErrorMatchingInlineSnapshot"];
|
|
265
|
+
function getCodeStartingAtIndex(code, index, methodNames) {
|
|
266
|
+
for (const name of methodNames) {
|
|
267
|
+
const adjusted = index - name.length;
|
|
268
|
+
if (adjusted >= 0 && code.slice(adjusted, index) === name) return {
|
|
269
|
+
code: code.slice(adjusted),
|
|
270
|
+
index: adjusted
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
code: code.slice(index),
|
|
275
|
+
index
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
var 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$]*(['"`)])/;
|
|
279
|
+
var buildStartRegex = /* @__PURE__ */ memo((assertionName) => {
|
|
280
|
+
const replaced = defaultStartRegex.source.replace("toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot", escapeRegExp(assertionName));
|
|
281
|
+
return new RegExp(replaced);
|
|
282
|
+
});
|
|
283
|
+
function replaceInlineSnap(code, s, currentIndex, newSnap, assertionName) {
|
|
284
|
+
const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex, assertionName ? [assertionName] : defaultMethodNames);
|
|
285
|
+
const startMatch = (assertionName ? buildStartRegex(assertionName) : defaultStartRegex).exec(codeStartingAtIndex);
|
|
286
|
+
const firstKeywordMatch = (assertionName ? new RegExp(escapeRegExp(assertionName)) : /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/).exec(codeStartingAtIndex);
|
|
287
|
+
if (!startMatch || startMatch.index !== firstKeywordMatch?.index) return replaceObjectSnap(code, s, index, newSnap, assertionName);
|
|
288
|
+
const quote = startMatch[1];
|
|
289
|
+
const startIndex = index + startMatch.index + startMatch[0].length;
|
|
290
|
+
const snapString = prepareSnapString(newSnap, code, index);
|
|
291
|
+
if (quote === ")") {
|
|
292
|
+
s.appendRight(startIndex - 1, snapString);
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
const endMatch = new RegExp(`(?:^|[^\\\\])${quote}`).exec(code.slice(startIndex));
|
|
296
|
+
if (!endMatch) return false;
|
|
297
|
+
const endIndex = startIndex + endMatch.index + endMatch[0].length;
|
|
298
|
+
s.overwrite(startIndex - 1, endIndex, snapString);
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
var INDENTATION_REGEX = /^([^\S\n]*)\S/m;
|
|
302
|
+
function stripSnapshotIndentation(inlineSnapshot) {
|
|
303
|
+
const match = inlineSnapshot.match(INDENTATION_REGEX);
|
|
304
|
+
if (!match || !match[1]) return inlineSnapshot;
|
|
305
|
+
const indentation = match[1];
|
|
306
|
+
const lines = inlineSnapshot.split(/\n/g);
|
|
307
|
+
if (lines.length <= 2) return inlineSnapshot;
|
|
308
|
+
if (lines[0].trim() !== "" || lines.at(-1)?.trim() !== "") return inlineSnapshot;
|
|
309
|
+
for (let i = 1; i < lines.length - 1; i++) if (lines[i] !== "") {
|
|
310
|
+
if (lines[i].indexOf(indentation) !== 0) return inlineSnapshot;
|
|
311
|
+
lines[i] = lines[i].substring(indentation.length);
|
|
312
|
+
}
|
|
313
|
+
lines[lines.length - 1] = "";
|
|
314
|
+
inlineSnapshot = lines.join("\n");
|
|
315
|
+
return inlineSnapshot;
|
|
316
|
+
}
|
|
317
|
+
async function saveRawSnapshots(environment, snapshots) {
|
|
318
|
+
await Promise.all(snapshots.map(async (snap) => {
|
|
319
|
+
if (!snap.readonly) await environment.saveSnapshotFile(snap.file, snap.snapshot);
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
307
322
|
function isSameStackPosition(x, y) {
|
|
308
323
|
return x.file === y.file && x.column === y.column && x.line === y.line;
|
|
309
324
|
}
|
|
@@ -367,13 +382,18 @@ var SnapshotState = class SnapshotState {
|
|
|
367
382
|
this._snapshotFormat = {
|
|
368
383
|
printBasicPrototype: false,
|
|
369
384
|
escapeString: false,
|
|
385
|
+
maxOutputLength: 2 ** 27,
|
|
370
386
|
...options.snapshotFormat
|
|
371
387
|
};
|
|
372
388
|
this._environment = options.snapshotEnvironment;
|
|
373
389
|
}
|
|
374
390
|
static async create(testFilePath, options) {
|
|
375
391
|
const snapshotPath = await options.snapshotEnvironment.resolvePath(testFilePath);
|
|
376
|
-
|
|
392
|
+
const content = await options.snapshotEnvironment.readSnapshotFile(snapshotPath);
|
|
393
|
+
return new SnapshotState(testFilePath, snapshotPath, content, options);
|
|
394
|
+
}
|
|
395
|
+
get snapshotUpdateState() {
|
|
396
|
+
return this._updateSnapshot;
|
|
377
397
|
}
|
|
378
398
|
get environment() {
|
|
379
399
|
return this._environment;
|
|
@@ -403,19 +423,24 @@ var SnapshotState = class SnapshotState {
|
|
|
403
423
|
_inferInlineSnapshotStack(stacks) {
|
|
404
424
|
const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/));
|
|
405
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];
|
|
406
428
|
for (let i = 0; i < stacks.length; i++) {
|
|
407
429
|
const match = stacks[i].method.match(/__INLINE_SNAPSHOT_OFFSET_(\d+)__/);
|
|
408
430
|
if (match) return stacks[i + Number(match[1])] ?? null;
|
|
409
431
|
}
|
|
432
|
+
const customMatcherIndex = stacks.findIndex((i) => i.method.includes("__VITEST_EXTEND_ASSERTION__"));
|
|
433
|
+
if (customMatcherIndex !== -1) return stacks[customMatcherIndex + 3] ?? null;
|
|
410
434
|
const stackIndex = stacks.findIndex((i) => i.method.includes("__INLINE_SNAPSHOT__"));
|
|
411
435
|
return stackIndex !== -1 ? stacks[stackIndex + 2] : null;
|
|
412
436
|
}
|
|
413
437
|
_addSnapshot(key, receivedSerialized, options) {
|
|
414
438
|
this._dirty = true;
|
|
415
439
|
if (options.stack) this._inlineSnapshots.push({
|
|
440
|
+
...options.stack,
|
|
416
441
|
snapshot: receivedSerialized,
|
|
417
442
|
testId: options.testId,
|
|
418
|
-
|
|
443
|
+
assertionName: options.assertionName
|
|
419
444
|
});
|
|
420
445
|
else if (options.rawSnapshot) this._rawSnapshots.push({
|
|
421
446
|
...options.rawSnapshot,
|
|
@@ -423,6 +448,90 @@ var SnapshotState = class SnapshotState {
|
|
|
423
448
|
});
|
|
424
449
|
else this._snapshotData[key] = receivedSerialized;
|
|
425
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 = 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
|
+
}
|
|
426
535
|
async save() {
|
|
427
536
|
const hasExternalSnapshots = Object.keys(this._snapshotData).length;
|
|
428
537
|
const hasInlineSnapshots = this._inlineSnapshots.length;
|
|
@@ -462,11 +571,24 @@ var SnapshotState = class SnapshotState {
|
|
|
462
571
|
this._uncheckedKeys.clear();
|
|
463
572
|
}
|
|
464
573
|
}
|
|
465
|
-
|
|
466
|
-
this._counters.
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
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;
|
|
470
592
|
if (!(isInline && this._snapshotData[key] !== void 0)) this._uncheckedKeys.delete(key);
|
|
471
593
|
let receivedSerialized = rawSnapshot && typeof received === "string" ? received : serialize(received, void 0, this._snapshotFormat);
|
|
472
594
|
if (!rawSnapshot) receivedSerialized = addExtraLineBreaks(receivedSerialized);
|
|
@@ -479,72 +601,49 @@ var SnapshotState = class SnapshotState {
|
|
|
479
601
|
const hasSnapshot = expected !== void 0;
|
|
480
602
|
const snapshotIsPersisted = isInline || this._fileExists || rawSnapshot && rawSnapshot.content != null;
|
|
481
603
|
if (pass && !isInline && !rawSnapshot) this._snapshotData[key] = receivedSerialized;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
expected: "",
|
|
526
|
-
key,
|
|
527
|
-
pass: true
|
|
528
|
-
};
|
|
529
|
-
} else if (!pass) {
|
|
530
|
-
this.unmatched.increment(testId);
|
|
531
|
-
return {
|
|
532
|
-
actual: rawSnapshot ? receivedSerialized : removeExtraLineBreaks(receivedSerialized),
|
|
533
|
-
count,
|
|
534
|
-
expected: expectedTrimmed !== void 0 ? rawSnapshot ? expectedTrimmed : removeExtraLineBreaks(expectedTrimmed) : void 0,
|
|
535
|
-
key,
|
|
536
|
-
pass: false
|
|
537
|
-
};
|
|
538
|
-
} else {
|
|
539
|
-
this.matched.increment(testId);
|
|
540
|
-
return {
|
|
541
|
-
actual: "",
|
|
542
|
-
count,
|
|
543
|
-
expected: "",
|
|
544
|
-
key,
|
|
545
|
-
pass: true
|
|
546
|
-
};
|
|
547
|
-
}
|
|
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
|
+
});
|
|
548
647
|
}
|
|
549
648
|
async pack() {
|
|
550
649
|
const snapshot = {
|
|
@@ -613,22 +712,41 @@ var SnapshotClient = class {
|
|
|
613
712
|
if (!state) throw new Error(`The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`);
|
|
614
713
|
return state;
|
|
615
714
|
}
|
|
616
|
-
|
|
617
|
-
const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot } = options;
|
|
715
|
+
match(options) {
|
|
716
|
+
const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot, assertionName } = options;
|
|
618
717
|
let { received } = options;
|
|
619
718
|
if (!filepath) throw new Error("Snapshot cannot be used outside of test");
|
|
620
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
|
+
});
|
|
621
727
|
if (typeof properties === "object") {
|
|
622
|
-
if (typeof received !== "object" || !received)
|
|
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;
|
|
623
733
|
try {
|
|
624
|
-
|
|
625
|
-
else received = deepMergeSnapshot(received, properties);
|
|
734
|
+
propertiesPass = this.options.isEqual?.(received, properties) ?? false;
|
|
626
735
|
} catch (err) {
|
|
627
|
-
|
|
736
|
+
expectedSnapshot.markAsChecked();
|
|
628
737
|
throw err;
|
|
629
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);
|
|
630
749
|
}
|
|
631
|
-
const testName = [name, ...message ? [message] : []].join(" > ");
|
|
632
750
|
const { actual, expected, key, pass } = snapshotState.match({
|
|
633
751
|
testId,
|
|
634
752
|
testName,
|
|
@@ -636,9 +754,97 @@ var SnapshotClient = class {
|
|
|
636
754
|
isInline,
|
|
637
755
|
error,
|
|
638
756
|
inlineSnapshot,
|
|
639
|
-
rawSnapshot
|
|
757
|
+
rawSnapshot,
|
|
758
|
+
assertionName
|
|
640
759
|
});
|
|
641
|
-
|
|
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
|
+
};
|
|
642
848
|
}
|
|
643
849
|
async assertRaw(options) {
|
|
644
850
|
if (!options.rawSnapshot) throw new Error("Raw snapshot is required");
|
|
@@ -656,5 +862,59 @@ var SnapshotClient = class {
|
|
|
656
862
|
this.snapshotStateMap.clear();
|
|
657
863
|
}
|
|
658
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
|
+
}
|
|
659
919
|
//#endregion
|
|
660
|
-
export { SnapshotClient, addSerializer, stripSnapshotIndentation };
|
|
920
|
+
export { SnapshotClient, SnapshotState, addSerializer, getSerializers, stripSnapshotIndentation };
|