@vitest/utils 0.31.4 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-display.js +79 -0
- package/dist/error.d.ts +10 -0
- package/dist/error.js +148 -0
- package/dist/index.js +5 -78
- package/error.d.ts +1 -0
- package/package.json +5 -1
@@ -0,0 +1,79 @@
|
|
1
|
+
import { format as format$1, plugins } from 'pretty-format';
|
2
|
+
import util from 'util';
|
3
|
+
import loupeImport from 'loupe';
|
4
|
+
|
5
|
+
const {
|
6
|
+
AsymmetricMatcher,
|
7
|
+
DOMCollection,
|
8
|
+
DOMElement,
|
9
|
+
Immutable,
|
10
|
+
ReactElement,
|
11
|
+
ReactTestComponent
|
12
|
+
} = plugins;
|
13
|
+
const PLUGINS = [
|
14
|
+
ReactTestComponent,
|
15
|
+
ReactElement,
|
16
|
+
DOMElement,
|
17
|
+
DOMCollection,
|
18
|
+
Immutable,
|
19
|
+
AsymmetricMatcher
|
20
|
+
];
|
21
|
+
function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) {
|
22
|
+
const MAX_LENGTH = maxLength ?? 1e4;
|
23
|
+
let result;
|
24
|
+
try {
|
25
|
+
result = format$1(object, {
|
26
|
+
maxDepth,
|
27
|
+
escapeString: false,
|
28
|
+
// min: true,
|
29
|
+
plugins: PLUGINS,
|
30
|
+
...options
|
31
|
+
});
|
32
|
+
} catch {
|
33
|
+
result = format$1(object, {
|
34
|
+
callToJSON: false,
|
35
|
+
maxDepth,
|
36
|
+
escapeString: false,
|
37
|
+
// min: true,
|
38
|
+
plugins: PLUGINS,
|
39
|
+
...options
|
40
|
+
});
|
41
|
+
}
|
42
|
+
return result.length >= MAX_LENGTH && maxDepth > 1 ? stringify(object, Math.floor(maxDepth / 2)) : result;
|
43
|
+
}
|
44
|
+
|
45
|
+
const loupe = typeof loupeImport.default === "function" ? loupeImport.default : loupeImport;
|
46
|
+
function format(...args) {
|
47
|
+
return util.format(...args);
|
48
|
+
}
|
49
|
+
function utilInspect(item, options) {
|
50
|
+
return util.inspect(item, options);
|
51
|
+
}
|
52
|
+
function loupeInspect(obj, options = {}) {
|
53
|
+
return loupe(obj, {
|
54
|
+
depth: 2,
|
55
|
+
truncate: options.truncateThreshold === 0 ? Infinity : options.truncateThreshold ?? 40
|
56
|
+
});
|
57
|
+
}
|
58
|
+
function objDisplay(obj, options = {}) {
|
59
|
+
const truncateThreshold = options.truncateThreshold ?? 40;
|
60
|
+
const str = loupeInspect(obj, options);
|
61
|
+
const type = Object.prototype.toString.call(obj);
|
62
|
+
if (truncateThreshold && str.length >= truncateThreshold) {
|
63
|
+
if (type === "[object Function]") {
|
64
|
+
const fn = obj;
|
65
|
+
return !fn.name || fn.name === "" ? "[Function]" : `[Function: ${fn.name}]`;
|
66
|
+
} else if (type === "[object Array]") {
|
67
|
+
return `[ Array(${obj.length}) ]`;
|
68
|
+
} else if (type === "[object Object]") {
|
69
|
+
const keys = Object.keys(obj);
|
70
|
+
const kstr = keys.length > 2 ? `${keys.splice(0, 2).join(", ")}, ...` : keys.join(", ");
|
71
|
+
return `{ Object (${kstr}) }`;
|
72
|
+
} else {
|
73
|
+
return str;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
return str;
|
77
|
+
}
|
78
|
+
|
79
|
+
export { format as f, loupeInspect as l, objDisplay as o, stringify as s, utilInspect as u };
|
package/dist/error.d.ts
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
import { DiffOptions } from './diff.js';
|
2
|
+
|
3
|
+
declare function serializeError(val: any, seen?: WeakMap<object, any>): any;
|
4
|
+
declare function processError(err: any, options?: DiffOptions): any;
|
5
|
+
declare function replaceAsymmetricMatcher(actual: any, expected: any, actualReplaced?: WeakSet<object>, expectedReplaced?: WeakSet<object>): {
|
6
|
+
replacedActual: any;
|
7
|
+
replacedExpected: any;
|
8
|
+
};
|
9
|
+
|
10
|
+
export { processError, replaceAsymmetricMatcher, serializeError };
|
package/dist/error.js
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
import { unifiedDiff } from './diff.js';
|
2
|
+
import { f as format, s as stringify } from './chunk-display.js';
|
3
|
+
import { deepClone, getOwnProperties, getType } from './helpers.js';
|
4
|
+
import './chunk-colors.js';
|
5
|
+
import 'concordance';
|
6
|
+
import 'pretty-format';
|
7
|
+
import 'util';
|
8
|
+
import 'loupe';
|
9
|
+
|
10
|
+
const IS_RECORD_SYMBOL = "@@__IMMUTABLE_RECORD__@@";
|
11
|
+
const IS_COLLECTION_SYMBOL = "@@__IMMUTABLE_ITERABLE__@@";
|
12
|
+
function isImmutable(v) {
|
13
|
+
return v && (v[IS_COLLECTION_SYMBOL] || v[IS_RECORD_SYMBOL]);
|
14
|
+
}
|
15
|
+
const OBJECT_PROTO = Object.getPrototypeOf({});
|
16
|
+
function getUnserializableMessage(err) {
|
17
|
+
if (err instanceof Error)
|
18
|
+
return `<unserializable>: ${err.message}`;
|
19
|
+
if (typeof err === "string")
|
20
|
+
return `<unserializable>: ${err}`;
|
21
|
+
return "<unserializable>";
|
22
|
+
}
|
23
|
+
function serializeError(val, seen = /* @__PURE__ */ new WeakMap()) {
|
24
|
+
if (!val || typeof val === "string")
|
25
|
+
return val;
|
26
|
+
if (typeof val === "function")
|
27
|
+
return `Function<${val.name || "anonymous"}>`;
|
28
|
+
if (typeof val === "symbol")
|
29
|
+
return val.toString();
|
30
|
+
if (typeof val !== "object")
|
31
|
+
return val;
|
32
|
+
if (isImmutable(val))
|
33
|
+
return serializeError(val.toJSON(), seen);
|
34
|
+
if (val instanceof Promise || val.constructor && val.constructor.prototype === "AsyncFunction")
|
35
|
+
return "Promise";
|
36
|
+
if (typeof Element !== "undefined" && val instanceof Element)
|
37
|
+
return val.tagName;
|
38
|
+
if (typeof val.asymmetricMatch === "function")
|
39
|
+
return `${val.toString()} ${format(val.sample)}`;
|
40
|
+
if (seen.has(val))
|
41
|
+
return seen.get(val);
|
42
|
+
if (Array.isArray(val)) {
|
43
|
+
const clone = new Array(val.length);
|
44
|
+
seen.set(val, clone);
|
45
|
+
val.forEach((e, i) => {
|
46
|
+
try {
|
47
|
+
clone[i] = serializeError(e, seen);
|
48
|
+
} catch (err) {
|
49
|
+
clone[i] = getUnserializableMessage(err);
|
50
|
+
}
|
51
|
+
});
|
52
|
+
return clone;
|
53
|
+
} else {
|
54
|
+
const clone = /* @__PURE__ */ Object.create(null);
|
55
|
+
seen.set(val, clone);
|
56
|
+
let obj = val;
|
57
|
+
while (obj && obj !== OBJECT_PROTO) {
|
58
|
+
Object.getOwnPropertyNames(obj).forEach((key) => {
|
59
|
+
if (key in clone)
|
60
|
+
return;
|
61
|
+
try {
|
62
|
+
clone[key] = serializeError(val[key], seen);
|
63
|
+
} catch (err) {
|
64
|
+
delete clone[key];
|
65
|
+
clone[key] = getUnserializableMessage(err);
|
66
|
+
}
|
67
|
+
});
|
68
|
+
obj = Object.getPrototypeOf(obj);
|
69
|
+
}
|
70
|
+
return clone;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
function normalizeErrorMessage(message) {
|
74
|
+
return message.replace(/__vite_ssr_import_\d+__\./g, "");
|
75
|
+
}
|
76
|
+
function processError(err, options = {}) {
|
77
|
+
if (!err || typeof err !== "object")
|
78
|
+
return { message: err };
|
79
|
+
if (err.stack)
|
80
|
+
err.stackStr = String(err.stack);
|
81
|
+
if (err.name)
|
82
|
+
err.nameStr = String(err.name);
|
83
|
+
const clonedActual = deepClone(err.actual, { forceWritable: true });
|
84
|
+
const clonedExpected = deepClone(err.expected, { forceWritable: true });
|
85
|
+
const { replacedActual, replacedExpected } = replaceAsymmetricMatcher(clonedActual, clonedExpected);
|
86
|
+
if (err.showDiff || err.showDiff === void 0 && err.expected !== void 0 && err.actual !== void 0)
|
87
|
+
err.diff = unifiedDiff(replacedActual, replacedExpected, options);
|
88
|
+
if (typeof err.expected !== "string")
|
89
|
+
err.expected = stringify(err.expected, 10);
|
90
|
+
if (typeof err.actual !== "string")
|
91
|
+
err.actual = stringify(err.actual, 10);
|
92
|
+
try {
|
93
|
+
if (typeof err.message === "string")
|
94
|
+
err.message = normalizeErrorMessage(err.message);
|
95
|
+
if (typeof err.cause === "object" && typeof err.cause.message === "string")
|
96
|
+
err.cause.message = normalizeErrorMessage(err.cause.message);
|
97
|
+
} catch {
|
98
|
+
}
|
99
|
+
try {
|
100
|
+
return serializeError(err);
|
101
|
+
} catch (e) {
|
102
|
+
return serializeError(new Error(`Failed to fully serialize error: ${e == null ? void 0 : e.message}
|
103
|
+
Inner error message: ${err == null ? void 0 : err.message}`));
|
104
|
+
}
|
105
|
+
}
|
106
|
+
function isAsymmetricMatcher(data) {
|
107
|
+
const type = getType(data);
|
108
|
+
return type === "Object" && typeof data.asymmetricMatch === "function";
|
109
|
+
}
|
110
|
+
function isReplaceable(obj1, obj2) {
|
111
|
+
const obj1Type = getType(obj1);
|
112
|
+
const obj2Type = getType(obj2);
|
113
|
+
return obj1Type === obj2Type && obj1Type === "Object";
|
114
|
+
}
|
115
|
+
function replaceAsymmetricMatcher(actual, expected, actualReplaced = /* @__PURE__ */ new WeakSet(), expectedReplaced = /* @__PURE__ */ new WeakSet()) {
|
116
|
+
if (!isReplaceable(actual, expected))
|
117
|
+
return { replacedActual: actual, replacedExpected: expected };
|
118
|
+
if (actualReplaced.has(actual) || expectedReplaced.has(expected))
|
119
|
+
return { replacedActual: actual, replacedExpected: expected };
|
120
|
+
actualReplaced.add(actual);
|
121
|
+
expectedReplaced.add(expected);
|
122
|
+
getOwnProperties(expected).forEach((key) => {
|
123
|
+
const expectedValue = expected[key];
|
124
|
+
const actualValue = actual[key];
|
125
|
+
if (isAsymmetricMatcher(expectedValue)) {
|
126
|
+
if (expectedValue.asymmetricMatch(actualValue))
|
127
|
+
actual[key] = expectedValue;
|
128
|
+
} else if (isAsymmetricMatcher(actualValue)) {
|
129
|
+
if (actualValue.asymmetricMatch(expectedValue))
|
130
|
+
expected[key] = actualValue;
|
131
|
+
} else if (isReplaceable(actualValue, expectedValue)) {
|
132
|
+
const replaced = replaceAsymmetricMatcher(
|
133
|
+
actualValue,
|
134
|
+
expectedValue,
|
135
|
+
actualReplaced,
|
136
|
+
expectedReplaced
|
137
|
+
);
|
138
|
+
actual[key] = replaced.replacedActual;
|
139
|
+
expected[key] = replaced.replacedExpected;
|
140
|
+
}
|
141
|
+
});
|
142
|
+
return {
|
143
|
+
replacedActual: actual,
|
144
|
+
replacedExpected: expected
|
145
|
+
};
|
146
|
+
}
|
147
|
+
|
148
|
+
export { processError, replaceAsymmetricMatcher, serializeError };
|
package/dist/index.js
CHANGED
@@ -1,50 +1,11 @@
|
|
1
1
|
import { notNullish, isPrimitive } from './helpers.js';
|
2
2
|
export { assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, noop, objectAttr, parseRegexp, slash, toArray } from './helpers.js';
|
3
|
-
|
3
|
+
export { f as format, l as loupeInspect, o as objDisplay, s as stringify, u as utilInspect } from './chunk-display.js';
|
4
4
|
import { S as SAFE_TIMERS_SYMBOL } from './chunk-colors.js';
|
5
5
|
export { a as SAFE_COLORS_SYMBOL, c as createColors, b as getColors, g as getDefaultColors, s as setupColors } from './chunk-colors.js';
|
6
|
-
import
|
7
|
-
import
|
8
|
-
|
9
|
-
const {
|
10
|
-
AsymmetricMatcher,
|
11
|
-
DOMCollection,
|
12
|
-
DOMElement,
|
13
|
-
Immutable,
|
14
|
-
ReactElement,
|
15
|
-
ReactTestComponent
|
16
|
-
} = plugins;
|
17
|
-
const PLUGINS = [
|
18
|
-
ReactTestComponent,
|
19
|
-
ReactElement,
|
20
|
-
DOMElement,
|
21
|
-
DOMCollection,
|
22
|
-
Immutable,
|
23
|
-
AsymmetricMatcher
|
24
|
-
];
|
25
|
-
function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) {
|
26
|
-
const MAX_LENGTH = maxLength ?? 1e4;
|
27
|
-
let result;
|
28
|
-
try {
|
29
|
-
result = format$1(object, {
|
30
|
-
maxDepth,
|
31
|
-
escapeString: false,
|
32
|
-
// min: true,
|
33
|
-
plugins: PLUGINS,
|
34
|
-
...options
|
35
|
-
});
|
36
|
-
} catch {
|
37
|
-
result = format$1(object, {
|
38
|
-
callToJSON: false,
|
39
|
-
maxDepth,
|
40
|
-
escapeString: false,
|
41
|
-
// min: true,
|
42
|
-
plugins: PLUGINS,
|
43
|
-
...options
|
44
|
-
});
|
45
|
-
}
|
46
|
-
return result.length >= MAX_LENGTH && maxDepth > 1 ? stringify(object, Math.floor(maxDepth / 2)) : result;
|
47
|
-
}
|
6
|
+
import 'pretty-format';
|
7
|
+
import 'util';
|
8
|
+
import 'loupe';
|
48
9
|
|
49
10
|
function getSafeTimers() {
|
50
11
|
const {
|
@@ -109,40 +70,6 @@ function shuffle(array, seed = RealDate.now()) {
|
|
109
70
|
return array;
|
110
71
|
}
|
111
72
|
|
112
|
-
const loupe = typeof loupeImport.default === "function" ? loupeImport.default : loupeImport;
|
113
|
-
function format(...args) {
|
114
|
-
return util.format(...args);
|
115
|
-
}
|
116
|
-
function utilInspect(item, options) {
|
117
|
-
return util.inspect(item, options);
|
118
|
-
}
|
119
|
-
function loupeInspect(obj, options = {}) {
|
120
|
-
return loupe(obj, {
|
121
|
-
depth: 2,
|
122
|
-
truncate: options.truncateThreshold === 0 ? Infinity : options.truncateThreshold ?? 40
|
123
|
-
});
|
124
|
-
}
|
125
|
-
function objDisplay(obj, options = {}) {
|
126
|
-
const truncateThreshold = options.truncateThreshold ?? 40;
|
127
|
-
const str = loupeInspect(obj, options);
|
128
|
-
const type = Object.prototype.toString.call(obj);
|
129
|
-
if (truncateThreshold && str.length >= truncateThreshold) {
|
130
|
-
if (type === "[object Function]") {
|
131
|
-
const fn = obj;
|
132
|
-
return !fn.name || fn.name === "" ? "[Function]" : `[Function: ${fn.name}]`;
|
133
|
-
} else if (type === "[object Array]") {
|
134
|
-
return `[ Array(${obj.length}) ]`;
|
135
|
-
} else if (type === "[object Object]") {
|
136
|
-
const keys = Object.keys(obj);
|
137
|
-
const kstr = keys.length > 2 ? `${keys.splice(0, 2).join(", ")}, ...` : keys.join(", ");
|
138
|
-
return `{ Object (${kstr}) }`;
|
139
|
-
} else {
|
140
|
-
return str;
|
141
|
-
}
|
142
|
-
}
|
143
|
-
return str;
|
144
|
-
}
|
145
|
-
|
146
73
|
function createSimpleStackTrace(options) {
|
147
74
|
const { message = "error", stackTraceLimit = 1 } = options || {};
|
148
75
|
const limit = Error.stackTraceLimit;
|
@@ -344,4 +271,4 @@ function offsetToLineNumber(source, offset) {
|
|
344
271
|
return line + 1;
|
345
272
|
}
|
346
273
|
|
347
|
-
export { SAFE_TIMERS_SYMBOL, createSimpleStackTrace,
|
274
|
+
export { SAFE_TIMERS_SYMBOL, createSimpleStackTrace, getSafeTimers, isPrimitive, lineSplitRE, notNullish, offsetToLineNumber, parseErrorStacktrace, parseSingleStack, parseStacktrace, positionToOffset, setSafeTimers, shuffle };
|
package/error.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export * from './dist/error.js'
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitest/utils",
|
3
3
|
"type": "module",
|
4
|
-
"version": "0.
|
4
|
+
"version": "0.32.0",
|
5
5
|
"description": "Shared Vitest utility functions",
|
6
6
|
"license": "MIT",
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
@@ -24,6 +24,10 @@
|
|
24
24
|
"types": "./dist/diff.d.ts",
|
25
25
|
"import": "./dist/diff.js"
|
26
26
|
},
|
27
|
+
"./error": {
|
28
|
+
"types": "./dist/error.d.ts",
|
29
|
+
"import": "./dist/error.js"
|
30
|
+
},
|
27
31
|
"./helpers": {
|
28
32
|
"types": "./dist/helpers.d.ts",
|
29
33
|
"import": "./dist/helpers.js"
|