@vitest/utils 0.29.8 → 0.30.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-colors.js +77 -0
- package/dist/diff.d.ts +173 -10
- package/dist/diff.js +106 -85
- package/dist/helpers.d.ts +13 -1
- package/dist/helpers.js +35 -1
- package/dist/index.d.ts +15 -3
- package/dist/index.js +195 -76
- package/dist/types.d.ts +21 -1
- package/package.json +2 -6
@@ -0,0 +1,77 @@
|
|
1
|
+
const SAFE_TIMERS_SYMBOL = Symbol("vitest:SAFE_TIMERS");
|
2
|
+
const SAFE_COLORS_SYMBOL = Symbol("vitest:SAFE_COLORS");
|
3
|
+
|
4
|
+
const colorsMap = {
|
5
|
+
bold: ["\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"],
|
6
|
+
dim: ["\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"],
|
7
|
+
italic: ["\x1B[3m", "\x1B[23m"],
|
8
|
+
underline: ["\x1B[4m", "\x1B[24m"],
|
9
|
+
inverse: ["\x1B[7m", "\x1B[27m"],
|
10
|
+
hidden: ["\x1B[8m", "\x1B[28m"],
|
11
|
+
strikethrough: ["\x1B[9m", "\x1B[29m"],
|
12
|
+
black: ["\x1B[30m", "\x1B[39m"],
|
13
|
+
red: ["\x1B[31m", "\x1B[39m"],
|
14
|
+
green: ["\x1B[32m", "\x1B[39m"],
|
15
|
+
yellow: ["\x1B[33m", "\x1B[39m"],
|
16
|
+
blue: ["\x1B[34m", "\x1B[39m"],
|
17
|
+
magenta: ["\x1B[35m", "\x1B[39m"],
|
18
|
+
cyan: ["\x1B[36m", "\x1B[39m"],
|
19
|
+
white: ["\x1B[37m", "\x1B[39m"],
|
20
|
+
gray: ["\x1B[90m", "\x1B[39m"],
|
21
|
+
bgBlack: ["\x1B[40m", "\x1B[49m"],
|
22
|
+
bgRed: ["\x1B[41m", "\x1B[49m"],
|
23
|
+
bgGreen: ["\x1B[42m", "\x1B[49m"],
|
24
|
+
bgYellow: ["\x1B[43m", "\x1B[49m"],
|
25
|
+
bgBlue: ["\x1B[44m", "\x1B[49m"],
|
26
|
+
bgMagenta: ["\x1B[45m", "\x1B[49m"],
|
27
|
+
bgCyan: ["\x1B[46m", "\x1B[49m"],
|
28
|
+
bgWhite: ["\x1B[47m", "\x1B[49m"]
|
29
|
+
};
|
30
|
+
const colorsEntries = Object.entries(colorsMap);
|
31
|
+
function string(str) {
|
32
|
+
return String(str);
|
33
|
+
}
|
34
|
+
string.open = "";
|
35
|
+
string.close = "";
|
36
|
+
const defaultColors = /* @__PURE__ */ colorsEntries.reduce((acc, [key]) => {
|
37
|
+
acc[key] = string;
|
38
|
+
return acc;
|
39
|
+
}, { isColorSupported: false });
|
40
|
+
function getDefaultColors() {
|
41
|
+
return { ...defaultColors };
|
42
|
+
}
|
43
|
+
function getColors() {
|
44
|
+
return globalThis[SAFE_COLORS_SYMBOL] || defaultColors;
|
45
|
+
}
|
46
|
+
function createColors(isTTY = false) {
|
47
|
+
const enabled = typeof process !== "undefined" && !("NO_COLOR" in process.env || process.argv.includes("--no-color")) && !("GITHUB_ACTIONS" in process.env) && ("FORCE_COLOR" in process.env || process.argv.includes("--color") || process.platform === "win32" || isTTY && process.env.TERM !== "dumb" || "CI" in process.env);
|
48
|
+
const replaceClose = (string2, close, replace, index) => {
|
49
|
+
const start = string2.substring(0, index) + replace;
|
50
|
+
const end = string2.substring(index + close.length);
|
51
|
+
const nextIndex = end.indexOf(close);
|
52
|
+
return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end;
|
53
|
+
};
|
54
|
+
const formatter = (open, close, replace = open) => {
|
55
|
+
const fn = (input) => {
|
56
|
+
const string2 = String(input);
|
57
|
+
const index = string2.indexOf(close, open.length);
|
58
|
+
return ~index ? open + replaceClose(string2, close, replace, index) + close : open + string2 + close;
|
59
|
+
};
|
60
|
+
fn.open = open;
|
61
|
+
fn.close = close;
|
62
|
+
return fn;
|
63
|
+
};
|
64
|
+
const colorsObject = {
|
65
|
+
isColorSupported: enabled,
|
66
|
+
reset: enabled ? (s) => `\x1B[0m${s}\x1B[0m` : string
|
67
|
+
};
|
68
|
+
for (const [name, formatterArgs] of colorsEntries) {
|
69
|
+
colorsObject[name] = enabled ? formatter(...formatterArgs) : string;
|
70
|
+
}
|
71
|
+
return colorsObject;
|
72
|
+
}
|
73
|
+
function setupColors(colors) {
|
74
|
+
globalThis[SAFE_COLORS_SYMBOL] = colors;
|
75
|
+
}
|
76
|
+
|
77
|
+
export { SAFE_TIMERS_SYMBOL as S, SAFE_COLORS_SYMBOL as a, getColors as b, createColors as c, getDefaultColors as g, setupColors as s };
|
package/dist/diff.d.ts
CHANGED
@@ -1,13 +1,176 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
import { DisplayOptions } from 'concordance';
|
2
|
+
|
3
|
+
declare function getConcordanceTheme(): {
|
4
|
+
boolean: {
|
5
|
+
(input: unknown): string;
|
6
|
+
open: string;
|
7
|
+
close: string;
|
8
|
+
};
|
9
|
+
circular: string;
|
10
|
+
date: {
|
11
|
+
invalid: string;
|
12
|
+
value: {
|
13
|
+
(input: unknown): string;
|
14
|
+
open: string;
|
15
|
+
close: string;
|
16
|
+
};
|
17
|
+
};
|
18
|
+
diffGutters: {
|
19
|
+
actual: string;
|
20
|
+
expected: string;
|
21
|
+
padding: string;
|
22
|
+
};
|
23
|
+
error: {
|
24
|
+
ctor: {
|
25
|
+
open: string;
|
26
|
+
close: string;
|
27
|
+
};
|
28
|
+
name: {
|
29
|
+
(input: unknown): string;
|
30
|
+
open: string;
|
31
|
+
close: string;
|
32
|
+
};
|
33
|
+
};
|
34
|
+
function: {
|
35
|
+
name: {
|
36
|
+
(input: unknown): string;
|
37
|
+
open: string;
|
38
|
+
close: string;
|
39
|
+
};
|
40
|
+
stringTag: {
|
41
|
+
(input: unknown): string;
|
42
|
+
open: string;
|
43
|
+
close: string;
|
44
|
+
};
|
45
|
+
};
|
46
|
+
global: {
|
47
|
+
(input: unknown): string;
|
48
|
+
open: string;
|
49
|
+
close: string;
|
50
|
+
};
|
51
|
+
item: {
|
52
|
+
after: string;
|
53
|
+
};
|
54
|
+
list: {
|
55
|
+
openBracket: string;
|
56
|
+
closeBracket: string;
|
57
|
+
};
|
58
|
+
mapEntry: {
|
59
|
+
after: string;
|
60
|
+
};
|
61
|
+
maxDepth: string;
|
62
|
+
null: {
|
63
|
+
(input: unknown): string;
|
64
|
+
open: string;
|
65
|
+
close: string;
|
66
|
+
};
|
67
|
+
number: {
|
68
|
+
(input: unknown): string;
|
69
|
+
open: string;
|
70
|
+
close: string;
|
71
|
+
};
|
72
|
+
object: {
|
73
|
+
openBracket: string;
|
74
|
+
closeBracket: string;
|
75
|
+
ctor: {
|
76
|
+
(input: unknown): string;
|
77
|
+
open: string;
|
78
|
+
close: string;
|
79
|
+
};
|
80
|
+
stringTag: {
|
81
|
+
open: string;
|
82
|
+
close: string;
|
83
|
+
};
|
84
|
+
secondaryStringTag: {
|
85
|
+
open: string;
|
86
|
+
close: string;
|
87
|
+
};
|
88
|
+
};
|
89
|
+
property: {
|
90
|
+
after: string;
|
91
|
+
keyBracket: {
|
92
|
+
open: string;
|
93
|
+
close: string;
|
94
|
+
};
|
95
|
+
valueFallback: string;
|
96
|
+
};
|
97
|
+
regexp: {
|
98
|
+
source: {
|
99
|
+
open: string;
|
100
|
+
close: string;
|
101
|
+
};
|
102
|
+
flags: {
|
103
|
+
(input: unknown): string;
|
104
|
+
open: string;
|
105
|
+
close: string;
|
106
|
+
};
|
107
|
+
};
|
108
|
+
stats: {
|
109
|
+
separator: string;
|
110
|
+
};
|
111
|
+
string: {
|
112
|
+
open: string;
|
113
|
+
close: string;
|
114
|
+
line: {
|
115
|
+
open: string;
|
116
|
+
close: string;
|
117
|
+
};
|
118
|
+
multiline: {
|
119
|
+
start: string;
|
120
|
+
end: string;
|
121
|
+
};
|
122
|
+
controlPicture: {
|
123
|
+
(input: unknown): string;
|
124
|
+
open: string;
|
125
|
+
close: string;
|
126
|
+
};
|
127
|
+
diff: {
|
128
|
+
insert: {
|
129
|
+
open: string;
|
130
|
+
close: string;
|
131
|
+
};
|
132
|
+
delete: {
|
133
|
+
open: string;
|
134
|
+
close: string;
|
135
|
+
};
|
136
|
+
equal: {
|
137
|
+
(input: unknown): string;
|
138
|
+
open: string;
|
139
|
+
close: string;
|
140
|
+
};
|
141
|
+
insertLine: {
|
142
|
+
open: string;
|
143
|
+
close: string;
|
144
|
+
};
|
145
|
+
deleteLine: {
|
146
|
+
open: string;
|
147
|
+
close: string;
|
148
|
+
};
|
149
|
+
};
|
150
|
+
};
|
151
|
+
symbol: {
|
152
|
+
(input: unknown): string;
|
153
|
+
open: string;
|
154
|
+
close: string;
|
155
|
+
};
|
156
|
+
typedArray: {
|
157
|
+
bytes: {
|
158
|
+
(input: unknown): string;
|
159
|
+
open: string;
|
160
|
+
close: string;
|
161
|
+
};
|
162
|
+
};
|
163
|
+
undefined: {
|
164
|
+
(input: unknown): string;
|
165
|
+
open: string;
|
166
|
+
close: string;
|
167
|
+
};
|
168
|
+
};
|
169
|
+
declare function diffDescriptors(actual: unknown, expected: unknown, options: DisplayOptions): string;
|
170
|
+
declare function formatDescriptor(value: unknown, options: DisplayOptions): string;
|
171
|
+
|
3
172
|
interface DiffOptions {
|
4
|
-
outputDiffMaxLines?: number;
|
5
|
-
outputTruncateLength?: number;
|
6
|
-
outputDiffLines?: number;
|
7
173
|
showLegend?: boolean;
|
8
|
-
colorSuccess?: Color;
|
9
|
-
colorError?: Color;
|
10
|
-
colorDim?: Color;
|
11
174
|
}
|
12
175
|
/**
|
13
176
|
* Returns unified diff between two strings with coloured ANSI output.
|
@@ -17,6 +180,6 @@ interface DiffOptions {
|
|
17
180
|
* @param {String} expected
|
18
181
|
* @return {string} The diff.
|
19
182
|
*/
|
20
|
-
declare function unifiedDiff(actual:
|
183
|
+
declare function unifiedDiff(actual: unknown, expected: unknown, options?: DiffOptions): string;
|
21
184
|
|
22
|
-
export { DiffOptions,
|
185
|
+
export { DiffOptions, diffDescriptors, formatDescriptor, getConcordanceTheme, unifiedDiff };
|
package/dist/diff.js
CHANGED
@@ -1,97 +1,118 @@
|
|
1
|
-
import
|
2
|
-
import
|
1
|
+
import { b as getColors } from './chunk-colors.js';
|
2
|
+
import concordance from 'concordance';
|
3
3
|
|
4
|
-
function
|
5
|
-
|
6
|
-
return
|
4
|
+
function getConcordanceTheme() {
|
5
|
+
const c = getColors();
|
6
|
+
return {
|
7
|
+
boolean: c.yellow,
|
8
|
+
circular: c.gray("[Circular]"),
|
9
|
+
date: {
|
10
|
+
invalid: c.red("invalid"),
|
11
|
+
value: c.blue
|
12
|
+
},
|
13
|
+
diffGutters: {
|
14
|
+
actual: ` ${c.red("-")} `,
|
15
|
+
expected: ` ${c.green("+")} `,
|
16
|
+
padding: " "
|
17
|
+
},
|
18
|
+
error: {
|
19
|
+
ctor: { open: `${c.gray.open}(`, close: `)${c.gray.close}` },
|
20
|
+
name: c.magenta
|
21
|
+
},
|
22
|
+
function: {
|
23
|
+
name: c.blue,
|
24
|
+
stringTag: c.magenta
|
25
|
+
},
|
26
|
+
global: c.magenta,
|
27
|
+
item: { after: c.gray(",") },
|
28
|
+
list: { openBracket: c.gray("["), closeBracket: c.gray("]") },
|
29
|
+
mapEntry: { after: c.gray(",") },
|
30
|
+
maxDepth: c.gray("\u2026"),
|
31
|
+
null: c.yellow,
|
32
|
+
number: c.yellow,
|
33
|
+
object: {
|
34
|
+
openBracket: c.gray("{"),
|
35
|
+
closeBracket: c.gray("}"),
|
36
|
+
ctor: c.magenta,
|
37
|
+
stringTag: { open: `${c.magenta.open}@`, close: c.magenta.close },
|
38
|
+
secondaryStringTag: { open: `${c.gray.open}@`, close: c.gray.close }
|
39
|
+
},
|
40
|
+
property: {
|
41
|
+
after: c.gray(","),
|
42
|
+
keyBracket: { open: c.gray("["), close: c.gray("]") },
|
43
|
+
valueFallback: c.gray("\u2026")
|
44
|
+
},
|
45
|
+
regexp: {
|
46
|
+
source: { open: `${c.blue.open}/`, close: `/${c.blue.close}` },
|
47
|
+
flags: c.yellow
|
48
|
+
},
|
49
|
+
stats: { separator: c.gray("---") },
|
50
|
+
string: {
|
51
|
+
open: c.blue.open,
|
52
|
+
close: c.blue.close,
|
53
|
+
line: { open: c.blue("'"), close: c.blue("'") },
|
54
|
+
multiline: { start: c.blue("`"), end: c.blue("`") },
|
55
|
+
controlPicture: c.gray,
|
56
|
+
diff: {
|
57
|
+
insert: {
|
58
|
+
open: c.bgGreen.open + c.black.open,
|
59
|
+
close: c.black.close + c.bgGreen.close
|
60
|
+
},
|
61
|
+
delete: {
|
62
|
+
open: c.bgRed.open + c.black.open,
|
63
|
+
close: c.black.close + c.bgRed.close
|
64
|
+
},
|
65
|
+
equal: c.blue,
|
66
|
+
insertLine: {
|
67
|
+
open: c.green.open,
|
68
|
+
close: c.green.close
|
69
|
+
},
|
70
|
+
deleteLine: {
|
71
|
+
open: c.red.open,
|
72
|
+
close: c.red.close
|
73
|
+
}
|
74
|
+
}
|
75
|
+
},
|
76
|
+
symbol: c.yellow,
|
77
|
+
typedArray: {
|
78
|
+
bytes: c.yellow
|
79
|
+
},
|
80
|
+
undefined: c.yellow
|
81
|
+
};
|
82
|
+
}
|
83
|
+
function diffDescriptors(actual, expected, options) {
|
84
|
+
return concordance.diff(expected, actual, options);
|
7
85
|
}
|
86
|
+
function formatDescriptor(value, options) {
|
87
|
+
return concordance.formatDescriptor(value, options);
|
88
|
+
}
|
89
|
+
|
8
90
|
function unifiedDiff(actual, expected, options = {}) {
|
9
|
-
|
10
|
-
|
11
|
-
const {
|
12
|
-
const indent = " ";
|
13
|
-
const diffLimit = outputDiffLines || 15;
|
14
|
-
const diffMaxLines = outputDiffMaxLines || 50;
|
91
|
+
const theme = getConcordanceTheme();
|
92
|
+
const diff = diffDescriptors(actual, expected, { theme });
|
93
|
+
const { showLegend = true } = options;
|
15
94
|
const counts = {
|
16
95
|
"+": 0,
|
17
96
|
"-": 0
|
18
97
|
};
|
19
|
-
|
20
|
-
|
21
|
-
const
|
22
|
-
const
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
if (
|
27
|
-
|
28
|
-
const char = line[0];
|
29
|
-
if ("-+".includes(char)) {
|
30
|
-
if (previousState !== char) {
|
31
|
-
previousState = char;
|
32
|
-
previousCount = 0;
|
33
|
-
}
|
34
|
-
previousCount++;
|
35
|
-
counts[char]++;
|
36
|
-
if (previousCount === diffLimit)
|
37
|
-
return dim(`${char} ...`);
|
38
|
-
else if (previousCount > diffLimit)
|
39
|
-
return;
|
40
|
-
}
|
41
|
-
return line;
|
42
|
-
}
|
43
|
-
const msg = diff.createPatch("string", expected, actual);
|
44
|
-
let lines = msg.split("\n").slice(5).map(preprocess).filter(Boolean);
|
45
|
-
let moreLines = 0;
|
46
|
-
const isCompact = counts["+"] === 1 && counts["-"] === 1 && lines.length === 2;
|
47
|
-
if (lines.length > diffMaxLines) {
|
48
|
-
const firstDiff = lines.findIndex((line) => line[0] === "-" || line[0] === "+");
|
49
|
-
const displayLines = lines.slice(firstDiff - 2, diffMaxLines);
|
50
|
-
const lastDisplayedIndex = firstDiff - 2 + diffMaxLines;
|
51
|
-
if (lastDisplayedIndex < lines.length)
|
52
|
-
moreLines = lines.length - lastDisplayedIndex;
|
53
|
-
lines = displayLines;
|
54
|
-
}
|
55
|
-
let formatted = lines.map((line) => {
|
56
|
-
line = line.replace(/\\"/g, '"');
|
57
|
-
if (line[0] === "-") {
|
58
|
-
line = formatLine(line.slice(1), outputTruncateLength);
|
59
|
-
if (isCompact)
|
60
|
-
return green(line);
|
61
|
-
return green(`- ${formatLine(line, outputTruncateLength)}`);
|
62
|
-
}
|
63
|
-
if (line[0] === "+") {
|
64
|
-
line = formatLine(line.slice(1), outputTruncateLength);
|
65
|
-
if (isCompact)
|
66
|
-
return red(line);
|
67
|
-
return red(`+ ${formatLine(line, outputTruncateLength)}`);
|
68
|
-
}
|
69
|
-
if (line.match(/@@/))
|
70
|
-
return "--";
|
71
|
-
return ` ${line}`;
|
98
|
+
const c = getColors();
|
99
|
+
const plus = theme.diffGutters.actual;
|
100
|
+
const minus = ` ${c.green("+")}`;
|
101
|
+
const lines = diff.split(/\r?\n/g);
|
102
|
+
lines.forEach((line) => {
|
103
|
+
if (line.startsWith(plus))
|
104
|
+
counts["+"]++;
|
105
|
+
else if (line.startsWith(minus))
|
106
|
+
counts["-"]++;
|
72
107
|
});
|
73
|
-
|
74
|
-
formatted.push(dim(`... ${moreLines} more lines`));
|
108
|
+
let legend = "";
|
75
109
|
if (showLegend) {
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
];
|
81
|
-
} else {
|
82
|
-
if (formatted[0].includes('"'))
|
83
|
-
formatted[0] = formatted[0].replace('"', "");
|
84
|
-
const last = formatted.length - 1;
|
85
|
-
if (formatted[last].endsWith('"'))
|
86
|
-
formatted[last] = formatted[last].slice(0, formatted[last].length - 1);
|
87
|
-
formatted.unshift(
|
88
|
-
green(`- Expected - ${counts["-"]}`),
|
89
|
-
red(`+ Received + ${counts["+"]}`),
|
90
|
-
""
|
91
|
-
);
|
92
|
-
}
|
110
|
+
legend = ` ${c.green(`- Expected - ${counts["-"]}`)}
|
111
|
+
${c.red(`+ Received + ${counts["+"]}`)}
|
112
|
+
|
113
|
+
`;
|
93
114
|
}
|
94
|
-
return
|
115
|
+
return legend + diff.replace(/␊\s*$/mg, "");
|
95
116
|
}
|
96
117
|
|
97
|
-
export {
|
118
|
+
export { diffDescriptors, formatDescriptor, getConcordanceTheme, unifiedDiff };
|
package/dist/helpers.d.ts
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import { Nullable, Arrayable } from './types.js';
|
2
2
|
|
3
|
+
declare function notNullish<T>(v: T | null | undefined): v is NonNullable<T>;
|
3
4
|
declare function assertTypes(value: unknown, name: string, types: string[]): void;
|
5
|
+
declare function isPrimitive(value: unknown): boolean;
|
4
6
|
declare function slash(path: string): string;
|
5
7
|
declare function parseRegexp(input: string): RegExp;
|
6
8
|
declare function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T>;
|
@@ -16,5 +18,15 @@ type DeferPromise<T> = Promise<T> & {
|
|
16
18
|
reject: (reason?: any) => void;
|
17
19
|
};
|
18
20
|
declare function createDefer<T>(): DeferPromise<T>;
|
21
|
+
/**
|
22
|
+
* If code starts with a function call, will return its last index, respecting arguments.
|
23
|
+
* This will return 25 - last ending character of toMatch ")"
|
24
|
+
* Also works with callbacks
|
25
|
+
* ```
|
26
|
+
* toMatch({ test: '123' });
|
27
|
+
* toBeAliased('123')
|
28
|
+
* ```
|
29
|
+
*/
|
30
|
+
declare function getCallLastIndex(code: string): number | null;
|
19
31
|
|
20
|
-
export { assertTypes, clone, createDefer, deepClone, getOwnProperties, getType, isObject, noop, objectAttr, parseRegexp, slash, toArray };
|
32
|
+
export { assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray };
|
package/dist/helpers.js
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
function notNullish(v) {
|
2
|
+
return v != null;
|
3
|
+
}
|
1
4
|
function assertTypes(value, name, types) {
|
2
5
|
const receivedType = typeof value;
|
3
6
|
const pass = types.includes(receivedType);
|
4
7
|
if (!pass)
|
5
8
|
throw new TypeError(`${name} value must be ${types.join(" or ")}, received "${receivedType}"`);
|
6
9
|
}
|
10
|
+
function isPrimitive(value) {
|
11
|
+
return value === null || typeof value !== "function" && typeof value !== "object";
|
12
|
+
}
|
7
13
|
function slash(path) {
|
8
14
|
return path.replace(/\\/g, "/");
|
9
15
|
}
|
@@ -108,5 +114,33 @@ function createDefer() {
|
|
108
114
|
p.reject = reject;
|
109
115
|
return p;
|
110
116
|
}
|
117
|
+
function getCallLastIndex(code) {
|
118
|
+
let charIndex = -1;
|
119
|
+
let inString = null;
|
120
|
+
let startedBracers = 0;
|
121
|
+
let endedBracers = 0;
|
122
|
+
let beforeChar = null;
|
123
|
+
while (charIndex <= code.length) {
|
124
|
+
beforeChar = code[charIndex];
|
125
|
+
charIndex++;
|
126
|
+
const char = code[charIndex];
|
127
|
+
const isCharString = char === '"' || char === "'" || char === "`";
|
128
|
+
if (isCharString && beforeChar !== "\\") {
|
129
|
+
if (inString === char)
|
130
|
+
inString = null;
|
131
|
+
else if (!inString)
|
132
|
+
inString = char;
|
133
|
+
}
|
134
|
+
if (!inString) {
|
135
|
+
if (char === "(")
|
136
|
+
startedBracers++;
|
137
|
+
if (char === ")")
|
138
|
+
endedBracers++;
|
139
|
+
}
|
140
|
+
if (startedBracers && endedBracers && startedBracers === endedBracers)
|
141
|
+
return charIndex;
|
142
|
+
}
|
143
|
+
return null;
|
144
|
+
}
|
111
145
|
|
112
|
-
export { assertTypes, clone, createDefer, deepClone, getOwnProperties, getType, isObject, noop, objectAttr, parseRegexp, slash, toArray };
|
146
|
+
export { assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray };
|
package/dist/index.d.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
export { assertTypes, clone, createDefer, deepClone, getOwnProperties, getType, isObject, noop, objectAttr, parseRegexp, slash, toArray } from './helpers.js';
|
1
|
+
export { assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, isPrimitive, noop, notNullish, objectAttr, parseRegexp, slash, toArray } from './helpers.js';
|
2
|
+
import { ParsedStack, ErrorWithDiff } from './types.js';
|
2
3
|
export { ArgumentsType, Arrayable, Awaitable, Constructable, DeepMerge, MergeInsertions, MutableArray, Nullable } from './types.js';
|
3
4
|
import { PrettyFormatOptions } from 'pretty-format';
|
4
5
|
import util from 'util';
|
@@ -56,7 +57,11 @@ declare const colorsMap: {
|
|
56
57
|
};
|
57
58
|
type ColorName = keyof typeof colorsMap;
|
58
59
|
type ColorsMethods = {
|
59
|
-
[Key in ColorName]:
|
60
|
+
[Key in ColorName]: {
|
61
|
+
(input: unknown): string;
|
62
|
+
open: string;
|
63
|
+
close: string;
|
64
|
+
};
|
60
65
|
};
|
61
66
|
type Colors = ColorsMethods & {
|
62
67
|
isColorSupported: boolean;
|
@@ -78,4 +83,11 @@ interface ErrorOptions {
|
|
78
83
|
*/
|
79
84
|
declare function createSimpleStackTrace(options?: ErrorOptions): string;
|
80
85
|
|
81
|
-
|
86
|
+
declare const lineSplitRE: RegExp;
|
87
|
+
declare function parseSingleStack(raw: string): ParsedStack | null;
|
88
|
+
declare function parseStacktrace(stack: string, ignore?: (string | RegExp)[]): ParsedStack[];
|
89
|
+
declare function parseErrorStacktrace(e: ErrorWithDiff, ignore?: (string | RegExp)[]): ParsedStack[];
|
90
|
+
declare function positionToOffset(source: string, lineNumber: number, columnNumber: number): number;
|
91
|
+
declare function offsetToLineNumber(source: string, offset: number): number;
|
92
|
+
|
93
|
+
export { ErrorWithDiff, ParsedStack, SAFE_COLORS_SYMBOL, SAFE_TIMERS_SYMBOL, createColors, createSimpleStackTrace, format, getColors, getDefaultColors, getSafeTimers, lineSplitRE, loupeInspect, objDisplay, offsetToLineNumber, parseErrorStacktrace, parseSingleStack, parseStacktrace, positionToOffset, setSafeTimers, setupColors, shuffle, stringify, utilInspect };
|
package/dist/index.js
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
1
|
+
import { notNullish, isPrimitive } from './helpers.js';
|
2
|
+
export { assertTypes, clone, createDefer, deepClone, getCallLastIndex, getOwnProperties, getType, isObject, noop, objectAttr, parseRegexp, slash, toArray } from './helpers.js';
|
2
3
|
import { format as format$1, plugins } from 'pretty-format';
|
4
|
+
import { S as SAFE_TIMERS_SYMBOL } from './chunk-colors.js';
|
5
|
+
export { a as SAFE_COLORS_SYMBOL, c as createColors, b as getColors, g as getDefaultColors, s as setupColors } from './chunk-colors.js';
|
3
6
|
import util from 'util';
|
4
7
|
import loupeImport from 'loupe';
|
5
8
|
|
@@ -26,6 +29,7 @@ function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) {
|
|
26
29
|
result = format$1(object, {
|
27
30
|
maxDepth,
|
28
31
|
escapeString: false,
|
32
|
+
// min: true,
|
29
33
|
plugins: PLUGINS,
|
30
34
|
...options
|
31
35
|
});
|
@@ -34,6 +38,7 @@ function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) {
|
|
34
38
|
callToJSON: false,
|
35
39
|
maxDepth,
|
36
40
|
escapeString: false,
|
41
|
+
// min: true,
|
37
42
|
plugins: PLUGINS,
|
38
43
|
...options
|
39
44
|
});
|
@@ -41,9 +46,6 @@ function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) {
|
|
41
46
|
return result.length >= MAX_LENGTH && maxDepth > 1 ? stringify(object, Math.floor(maxDepth / 2)) : result;
|
42
47
|
}
|
43
48
|
|
44
|
-
const SAFE_TIMERS_SYMBOL = Symbol("vitest:SAFE_TIMERS");
|
45
|
-
const SAFE_COLORS_SYMBOL = Symbol("vitest:SAFE_COLORS");
|
46
|
-
|
47
49
|
function getSafeTimers() {
|
48
50
|
const {
|
49
51
|
setTimeout: safeSetTimeout,
|
@@ -141,77 +143,6 @@ function objDisplay(obj) {
|
|
141
143
|
return str;
|
142
144
|
}
|
143
145
|
|
144
|
-
const colorsMap = {
|
145
|
-
bold: ["\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"],
|
146
|
-
dim: ["\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"],
|
147
|
-
italic: ["\x1B[3m", "\x1B[23m"],
|
148
|
-
underline: ["\x1B[4m", "\x1B[24m"],
|
149
|
-
inverse: ["\x1B[7m", "\x1B[27m"],
|
150
|
-
hidden: ["\x1B[8m", "\x1B[28m"],
|
151
|
-
strikethrough: ["\x1B[9m", "\x1B[29m"],
|
152
|
-
black: ["\x1B[30m", "\x1B[39m"],
|
153
|
-
red: ["\x1B[31m", "\x1B[39m"],
|
154
|
-
green: ["\x1B[32m", "\x1B[39m"],
|
155
|
-
yellow: ["\x1B[33m", "\x1B[39m"],
|
156
|
-
blue: ["\x1B[34m", "\x1B[39m"],
|
157
|
-
magenta: ["\x1B[35m", "\x1B[39m"],
|
158
|
-
cyan: ["\x1B[36m", "\x1B[39m"],
|
159
|
-
white: ["\x1B[37m", "\x1B[39m"],
|
160
|
-
gray: ["\x1B[90m", "\x1B[39m"],
|
161
|
-
bgBlack: ["\x1B[40m", "\x1B[49m"],
|
162
|
-
bgRed: ["\x1B[41m", "\x1B[49m"],
|
163
|
-
bgGreen: ["\x1B[42m", "\x1B[49m"],
|
164
|
-
bgYellow: ["\x1B[43m", "\x1B[49m"],
|
165
|
-
bgBlue: ["\x1B[44m", "\x1B[49m"],
|
166
|
-
bgMagenta: ["\x1B[45m", "\x1B[49m"],
|
167
|
-
bgCyan: ["\x1B[46m", "\x1B[49m"],
|
168
|
-
bgWhite: ["\x1B[47m", "\x1B[49m"]
|
169
|
-
};
|
170
|
-
const colorsEntries = Object.entries(colorsMap);
|
171
|
-
const string = (str) => String(str);
|
172
|
-
string.open = "";
|
173
|
-
string.close = "";
|
174
|
-
const defaultColors = colorsEntries.reduce((acc, [key]) => {
|
175
|
-
acc[key] = string;
|
176
|
-
return acc;
|
177
|
-
}, { isColorSupported: false });
|
178
|
-
function getDefaultColors() {
|
179
|
-
return { ...defaultColors };
|
180
|
-
}
|
181
|
-
function getColors() {
|
182
|
-
return globalThis[SAFE_COLORS_SYMBOL] || defaultColors;
|
183
|
-
}
|
184
|
-
function createColors(isTTY = false) {
|
185
|
-
const enabled = typeof process !== "undefined" && !("NO_COLOR" in process.env || process.argv.includes("--no-color")) && !("GITHUB_ACTIONS" in process.env) && ("FORCE_COLOR" in process.env || process.argv.includes("--color") || process.platform === "win32" || isTTY && process.env.TERM !== "dumb" || "CI" in process.env);
|
186
|
-
const replaceClose = (string2, close, replace, index) => {
|
187
|
-
const start = string2.substring(0, index) + replace;
|
188
|
-
const end = string2.substring(index + close.length);
|
189
|
-
const nextIndex = end.indexOf(close);
|
190
|
-
return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end;
|
191
|
-
};
|
192
|
-
const formatter = (open, close, replace = open) => {
|
193
|
-
const fn = (input) => {
|
194
|
-
const string2 = String(input);
|
195
|
-
const index = string2.indexOf(close, open.length);
|
196
|
-
return ~index ? open + replaceClose(string2, close, replace, index) + close : open + string2 + close;
|
197
|
-
};
|
198
|
-
fn.open = open;
|
199
|
-
fn.close = close;
|
200
|
-
return fn;
|
201
|
-
};
|
202
|
-
const colorsObject = {
|
203
|
-
isColorSupported: enabled,
|
204
|
-
reset: enabled ? (s) => `\x1B[0m${s}\x1B[0m` : string
|
205
|
-
};
|
206
|
-
for (const [name, formatterArgs] of colorsEntries) {
|
207
|
-
colorsObject[name] = enabled ? formatter(...formatterArgs) : string;
|
208
|
-
}
|
209
|
-
return colorsObject;
|
210
|
-
}
|
211
|
-
function setupColors(colors) {
|
212
|
-
globalThis[SAFE_COLORS_SYMBOL] = colors;
|
213
|
-
}
|
214
|
-
|
215
146
|
function createSimpleStackTrace(options) {
|
216
147
|
const { message = "error", stackTraceLimit = 1 } = options || {};
|
217
148
|
const limit = Error.stackTraceLimit;
|
@@ -225,4 +156,192 @@ function createSimpleStackTrace(options) {
|
|
225
156
|
return stackTrace;
|
226
157
|
}
|
227
158
|
|
228
|
-
|
159
|
+
function normalizeWindowsPath(input = "") {
|
160
|
+
if (!input || !input.includes("\\")) {
|
161
|
+
return input;
|
162
|
+
}
|
163
|
+
return input.replace(/\\/g, "/");
|
164
|
+
}
|
165
|
+
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
166
|
+
function cwd() {
|
167
|
+
if (typeof process !== "undefined") {
|
168
|
+
return process.cwd().replace(/\\/g, "/");
|
169
|
+
}
|
170
|
+
return "/";
|
171
|
+
}
|
172
|
+
const resolve = function(...arguments_) {
|
173
|
+
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
174
|
+
let resolvedPath = "";
|
175
|
+
let resolvedAbsolute = false;
|
176
|
+
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
177
|
+
const path = index >= 0 ? arguments_[index] : cwd();
|
178
|
+
if (!path || path.length === 0) {
|
179
|
+
continue;
|
180
|
+
}
|
181
|
+
resolvedPath = `${path}/${resolvedPath}`;
|
182
|
+
resolvedAbsolute = isAbsolute(path);
|
183
|
+
}
|
184
|
+
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
185
|
+
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
|
186
|
+
return `/${resolvedPath}`;
|
187
|
+
}
|
188
|
+
return resolvedPath.length > 0 ? resolvedPath : ".";
|
189
|
+
};
|
190
|
+
function normalizeString(path, allowAboveRoot) {
|
191
|
+
let res = "";
|
192
|
+
let lastSegmentLength = 0;
|
193
|
+
let lastSlash = -1;
|
194
|
+
let dots = 0;
|
195
|
+
let char = null;
|
196
|
+
for (let index = 0; index <= path.length; ++index) {
|
197
|
+
if (index < path.length) {
|
198
|
+
char = path[index];
|
199
|
+
} else if (char === "/") {
|
200
|
+
break;
|
201
|
+
} else {
|
202
|
+
char = "/";
|
203
|
+
}
|
204
|
+
if (char === "/") {
|
205
|
+
if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) {
|
206
|
+
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
|
207
|
+
if (res.length > 2) {
|
208
|
+
const lastSlashIndex = res.lastIndexOf("/");
|
209
|
+
if (lastSlashIndex === -1) {
|
210
|
+
res = "";
|
211
|
+
lastSegmentLength = 0;
|
212
|
+
} else {
|
213
|
+
res = res.slice(0, lastSlashIndex);
|
214
|
+
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
215
|
+
}
|
216
|
+
lastSlash = index;
|
217
|
+
dots = 0;
|
218
|
+
continue;
|
219
|
+
} else if (res.length > 0) {
|
220
|
+
res = "";
|
221
|
+
lastSegmentLength = 0;
|
222
|
+
lastSlash = index;
|
223
|
+
dots = 0;
|
224
|
+
continue;
|
225
|
+
}
|
226
|
+
}
|
227
|
+
if (allowAboveRoot) {
|
228
|
+
res += res.length > 0 ? "/.." : "..";
|
229
|
+
lastSegmentLength = 2;
|
230
|
+
}
|
231
|
+
} else {
|
232
|
+
if (res.length > 0) {
|
233
|
+
res += `/${path.slice(lastSlash + 1, index)}`;
|
234
|
+
} else {
|
235
|
+
res = path.slice(lastSlash + 1, index);
|
236
|
+
}
|
237
|
+
lastSegmentLength = index - lastSlash - 1;
|
238
|
+
}
|
239
|
+
lastSlash = index;
|
240
|
+
dots = 0;
|
241
|
+
} else if (char === "." && dots !== -1) {
|
242
|
+
++dots;
|
243
|
+
} else {
|
244
|
+
dots = -1;
|
245
|
+
}
|
246
|
+
}
|
247
|
+
return res;
|
248
|
+
}
|
249
|
+
const isAbsolute = function(p) {
|
250
|
+
return _IS_ABSOLUTE_RE.test(p);
|
251
|
+
};
|
252
|
+
|
253
|
+
const lineSplitRE = /\r?\n/;
|
254
|
+
const stackIgnorePatterns = [
|
255
|
+
"node:internal",
|
256
|
+
/\/packages\/\w+\/dist\//,
|
257
|
+
/\/@vitest\/\w+\/dist\//,
|
258
|
+
"/vitest/dist/",
|
259
|
+
"/vitest/src/",
|
260
|
+
"/vite-node/dist/",
|
261
|
+
"/vite-node/src/",
|
262
|
+
"/node_modules/chai/",
|
263
|
+
"/node_modules/tinypool/",
|
264
|
+
"/node_modules/tinyspy/"
|
265
|
+
];
|
266
|
+
function extractLocation(urlLike) {
|
267
|
+
if (!urlLike.includes(":"))
|
268
|
+
return [urlLike];
|
269
|
+
const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
|
270
|
+
const parts = regExp.exec(urlLike.replace(/[()]/g, ""));
|
271
|
+
if (!parts)
|
272
|
+
return [urlLike];
|
273
|
+
return [parts[1], parts[2] || void 0, parts[3] || void 0];
|
274
|
+
}
|
275
|
+
function parseSingleStack(raw) {
|
276
|
+
let line = raw.trim();
|
277
|
+
if (line.includes("(eval "))
|
278
|
+
line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, "");
|
279
|
+
let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, "");
|
280
|
+
const location = sanitizedLine.match(/ (\(.+\)$)/);
|
281
|
+
sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine;
|
282
|
+
const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine);
|
283
|
+
let method = location && sanitizedLine || "";
|
284
|
+
let file = url && ["eval", "<anonymous>"].includes(url) ? void 0 : url;
|
285
|
+
if (!file || !lineNumber || !columnNumber)
|
286
|
+
return null;
|
287
|
+
if (method.startsWith("async "))
|
288
|
+
method = method.slice(6);
|
289
|
+
if (file.startsWith("file://"))
|
290
|
+
file = file.slice(7);
|
291
|
+
file = resolve(file);
|
292
|
+
return {
|
293
|
+
method,
|
294
|
+
file,
|
295
|
+
line: parseInt(lineNumber),
|
296
|
+
column: parseInt(columnNumber)
|
297
|
+
};
|
298
|
+
}
|
299
|
+
function parseStacktrace(stack, ignore = stackIgnorePatterns) {
|
300
|
+
const stackFrames = stack.split("\n").map((raw) => {
|
301
|
+
const stack2 = parseSingleStack(raw);
|
302
|
+
if (!stack2 || ignore.length && ignore.some((p) => stack2.file.match(p)))
|
303
|
+
return null;
|
304
|
+
return stack2;
|
305
|
+
}).filter(notNullish);
|
306
|
+
return stackFrames;
|
307
|
+
}
|
308
|
+
function parseErrorStacktrace(e, ignore = stackIgnorePatterns) {
|
309
|
+
if (!e || isPrimitive(e))
|
310
|
+
return [];
|
311
|
+
if (e.stacks)
|
312
|
+
return e.stacks;
|
313
|
+
const stackStr = e.stack || e.stackStr || "";
|
314
|
+
const stackFrames = parseStacktrace(stackStr, ignore);
|
315
|
+
e.stacks = stackFrames;
|
316
|
+
return stackFrames;
|
317
|
+
}
|
318
|
+
function positionToOffset(source, lineNumber, columnNumber) {
|
319
|
+
const lines = source.split(lineSplitRE);
|
320
|
+
const nl = /\r\n/.test(source) ? 2 : 1;
|
321
|
+
let start = 0;
|
322
|
+
if (lineNumber > lines.length)
|
323
|
+
return source.length;
|
324
|
+
for (let i = 0; i < lineNumber - 1; i++)
|
325
|
+
start += lines[i].length + nl;
|
326
|
+
return start + columnNumber;
|
327
|
+
}
|
328
|
+
function offsetToLineNumber(source, offset) {
|
329
|
+
if (offset > source.length) {
|
330
|
+
throw new Error(
|
331
|
+
`offset is longer than source length! offset ${offset} > length ${source.length}`
|
332
|
+
);
|
333
|
+
}
|
334
|
+
const lines = source.split(lineSplitRE);
|
335
|
+
const nl = /\r\n/.test(source) ? 2 : 1;
|
336
|
+
let counted = 0;
|
337
|
+
let line = 0;
|
338
|
+
for (; line < lines.length; line++) {
|
339
|
+
const lineLength = lines[line].length + nl;
|
340
|
+
if (counted + lineLength >= offset)
|
341
|
+
break;
|
342
|
+
counted += lineLength;
|
343
|
+
}
|
344
|
+
return line + 1;
|
345
|
+
}
|
346
|
+
|
347
|
+
export { SAFE_TIMERS_SYMBOL, createSimpleStackTrace, format, getSafeTimers, isPrimitive, lineSplitRE, loupeInspect, notNullish, objDisplay, offsetToLineNumber, parseErrorStacktrace, parseSingleStack, parseStacktrace, positionToOffset, setSafeTimers, shuffle, stringify, utilInspect };
|
package/dist/types.d.ts
CHANGED
@@ -14,5 +14,25 @@ type MutableArray<T extends readonly any[]> = {
|
|
14
14
|
interface Constructable {
|
15
15
|
new (...args: any[]): any;
|
16
16
|
}
|
17
|
+
interface ParsedStack {
|
18
|
+
method: string;
|
19
|
+
file: string;
|
20
|
+
line: number;
|
21
|
+
column: number;
|
22
|
+
}
|
23
|
+
interface ErrorWithDiff extends Error {
|
24
|
+
name: string;
|
25
|
+
nameStr?: string;
|
26
|
+
stack?: string;
|
27
|
+
stackStr?: string;
|
28
|
+
stacks?: ParsedStack[];
|
29
|
+
showDiff?: boolean;
|
30
|
+
actual?: any;
|
31
|
+
expected?: any;
|
32
|
+
operator?: string;
|
33
|
+
type?: string;
|
34
|
+
frame?: string;
|
35
|
+
diff?: string;
|
36
|
+
}
|
17
37
|
|
18
|
-
export { ArgumentsType, Arrayable, Awaitable, Constructable, DeepMerge, MergeInsertions, MutableArray, Nullable };
|
38
|
+
export { ArgumentsType, Arrayable, Awaitable, Constructable, DeepMerge, ErrorWithDiff, MergeInsertions, MutableArray, Nullable, ParsedStack };
|
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.30.0",
|
5
5
|
"description": "Shared Vitest utility functions",
|
6
6
|
"license": "MIT",
|
7
7
|
"repository": {
|
@@ -32,14 +32,10 @@
|
|
32
32
|
"dist"
|
33
33
|
],
|
34
34
|
"dependencies": {
|
35
|
-
"
|
36
|
-
"diff": "^5.1.0",
|
35
|
+
"concordance": "^5.0.4",
|
37
36
|
"loupe": "^2.3.6",
|
38
37
|
"pretty-format": "^27.5.1"
|
39
38
|
},
|
40
|
-
"devDependencies": {
|
41
|
-
"@types/diff": "^5.0.2"
|
42
|
-
},
|
43
39
|
"scripts": {
|
44
40
|
"build": "rimraf dist && rollup -c",
|
45
41
|
"dev": "rollup -c --watch"
|