@vitest/utils 4.1.0-beta.1 → 4.1.0-beta.3

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/display.d.ts CHANGED
@@ -17,8 +17,9 @@ interface Options {
17
17
  type LoupeOptions = Partial<Options>;
18
18
  interface StringifyOptions extends PrettyFormatOptions {
19
19
  maxLength?: number;
20
+ filterNode?: string | ((node: any) => boolean);
20
21
  }
21
- declare function stringify(object: unknown, maxDepth?: number, { maxLength, ...options }?: StringifyOptions): string;
22
+ declare function stringify(object: unknown, maxDepth?: number, { maxLength, filterNode, ...options }?: StringifyOptions): string;
22
23
  declare const formatRegExp: RegExp;
23
24
  declare function format(...args: unknown[]): string;
24
25
  declare function browserFormat(...args: unknown[]): string;
package/dist/display.js CHANGED
@@ -1,4 +1,4 @@
1
- import { plugins, format as format$1 } from '@vitest/pretty-format';
1
+ import { plugins, createDOMElementFilter, format as format$1 } from '@vitest/pretty-format';
2
2
 
3
3
  const ansiColors = {
4
4
  bold: ['1', '22'],
@@ -583,14 +583,24 @@ const PLUGINS = [
583
583
  Immutable,
584
584
  AsymmetricMatcher
585
585
  ];
586
- function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) {
586
+ function stringify(object, maxDepth = 10, { maxLength, filterNode, ...options } = {}) {
587
587
  const MAX_LENGTH = maxLength ?? 1e4;
588
588
  let result;
589
+ // Convert string selector to filter function
590
+ const filterFn = typeof filterNode === "string" ? createNodeFilterFromSelector(filterNode) : filterNode;
591
+ const plugins = filterFn ? [
592
+ ReactTestComponent,
593
+ ReactElement,
594
+ createDOMElementFilter(filterFn),
595
+ DOMCollection,
596
+ Immutable,
597
+ AsymmetricMatcher
598
+ ] : PLUGINS;
589
599
  try {
590
600
  result = format$1(object, {
591
601
  maxDepth,
592
602
  escapeString: false,
593
- plugins: PLUGINS,
603
+ plugins,
594
604
  ...options
595
605
  });
596
606
  } catch {
@@ -598,16 +608,36 @@ function stringify(object, maxDepth = 10, { maxLength, ...options } = {}) {
598
608
  callToJSON: false,
599
609
  maxDepth,
600
610
  escapeString: false,
601
- plugins: PLUGINS,
611
+ plugins,
602
612
  ...options
603
613
  });
604
614
  }
605
615
  // Prevents infinite loop https://github.com/vitest-dev/vitest/issues/7249
606
616
  return result.length >= MAX_LENGTH && maxDepth > 1 ? stringify(object, Math.floor(Math.min(maxDepth, Number.MAX_SAFE_INTEGER) / 2), {
607
617
  maxLength,
618
+ filterNode,
608
619
  ...options
609
620
  }) : result;
610
621
  }
622
+ function createNodeFilterFromSelector(selector) {
623
+ const ELEMENT_NODE = 1;
624
+ const COMMENT_NODE = 8;
625
+ return (node) => {
626
+ // Filter out comments
627
+ if (node.nodeType === COMMENT_NODE) {
628
+ return false;
629
+ }
630
+ // Filter out elements matching the selector
631
+ if (node.nodeType === ELEMENT_NODE && node.matches) {
632
+ try {
633
+ return !node.matches(selector);
634
+ } catch {
635
+ return true;
636
+ }
637
+ }
638
+ return true;
639
+ };
640
+ }
611
641
  const formatRegExp = /%[sdjifoOc%]/g;
612
642
  function baseFormat(args, options = {}) {
613
643
  const formatArg = (item, inspecOptions) => {
package/dist/helpers.d.ts CHANGED
@@ -35,6 +35,7 @@ declare function wrapId(id: string): string;
35
35
  */
36
36
  declare function unwrapId(id: string): string;
37
37
  declare function withTrailingSlash(path: string): string;
38
+ declare function filterOutComments(s: string): string;
38
39
  declare function isBareImport(id: string): boolean;
39
40
  declare function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T>;
40
41
  declare function isObject(item: unknown): boolean;
@@ -68,6 +69,7 @@ declare function isNegativeNaN(val: number): boolean;
68
69
  * Do not merge types - it is very expensive and usually it's better to case a type here
69
70
  */
70
71
  declare function deepMerge<T extends object = object>(target: T, ...sources: any[]): T;
72
+ declare function unique<T>(array: T[]): T[];
71
73
 
72
- export { assertTypes, cleanUrl, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, getCallLastIndex, getOwnProperties, getType, isBareImport, isExternalUrl, isNegativeNaN, isObject, isPrimitive, nanoid, noop, notNullish, objectAttr, shuffle, slash, toArray, unwrapId, withTrailingSlash, wrapId };
74
+ export { assertTypes, cleanUrl, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, filterOutComments, getCallLastIndex, getOwnProperties, getType, isBareImport, isExternalUrl, isNegativeNaN, isObject, isPrimitive, nanoid, noop, notNullish, objectAttr, shuffle, slash, toArray, unique, unwrapId, withTrailingSlash, wrapId };
73
75
  export type { DeferPromise };
package/dist/helpers.js CHANGED
@@ -88,6 +88,31 @@ function withTrailingSlash(path) {
88
88
  }
89
89
  return path;
90
90
  }
91
+ function filterOutComments(s) {
92
+ const result = [];
93
+ let commentState = "none";
94
+ for (let i = 0; i < s.length; ++i) {
95
+ if (commentState === "singleline") {
96
+ if (s[i] === "\n") {
97
+ commentState = "none";
98
+ }
99
+ } else if (commentState === "multiline") {
100
+ if (s[i - 1] === "*" && s[i] === "/") {
101
+ commentState = "none";
102
+ }
103
+ } else if (commentState === "none") {
104
+ if (s[i] === "/" && s[i + 1] === "/") {
105
+ commentState = "singleline";
106
+ } else if (s[i] === "/" && s[i + 1] === "*") {
107
+ commentState = "multiline";
108
+ i += 2;
109
+ } else {
110
+ result.push(s[i]);
111
+ }
112
+ }
113
+ }
114
+ return result.join("");
115
+ }
91
116
  const bareImportRE = /^(?![a-z]:)[\w@](?!.*:\/\/)/i;
92
117
  function isBareImport(id) {
93
118
  return bareImportRE.test(id);
@@ -291,5 +316,8 @@ function deepMerge(target, ...sources) {
291
316
  }
292
317
  return deepMerge(target, ...sources);
293
318
  }
319
+ function unique(array) {
320
+ return Array.from(new Set(array));
321
+ }
294
322
 
295
- export { assertTypes, cleanUrl, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, getCallLastIndex, getOwnProperties, getType, isBareImport, isExternalUrl, isNegativeNaN, isObject, isPrimitive, nanoid, noop, notNullish, objectAttr, shuffle, slash, toArray, unwrapId, withTrailingSlash, wrapId };
323
+ export { assertTypes, cleanUrl, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, filterOutComments, getCallLastIndex, getOwnProperties, getType, isBareImport, isExternalUrl, isNegativeNaN, isObject, isPrimitive, nanoid, noop, notNullish, objectAttr, shuffle, slash, toArray, unique, unwrapId, withTrailingSlash, wrapId };
package/dist/serialize.js CHANGED
@@ -101,7 +101,7 @@ function serializeValue(val, seen = new WeakMap()) {
101
101
  obj = Object.getPrototypeOf(obj);
102
102
  }
103
103
  if (val instanceof Error) {
104
- safe(() => val.message = normalizeErrorMessage(val.message));
104
+ safe(() => clone.message = normalizeErrorMessage(val.message));
105
105
  }
106
106
  return clone;
107
107
  }
@@ -112,7 +112,7 @@ function safe(fn) {
112
112
  } catch {}
113
113
  }
114
114
  function normalizeErrorMessage(message) {
115
- return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, "");
115
+ return message.replace(/\(0\s?,\s?__vite_ssr_import_\d+__.(\w+)\)/g, "$1").replace(/__(vite_ssr_import|vi_import)_\d+__\./g, "").replace(/getByTestId('__vitest_\d+__')/g, "page");
116
116
  }
117
117
 
118
118
  export { serializeValue };
@@ -233,8 +233,11 @@ const stackIgnorePatterns = [
233
233
  /node:\w+/,
234
234
  /__vitest_test__/,
235
235
  /__vitest_browser__/,
236
+ "/@id/__x00__vitest/browser",
236
237
  /\/deps\/vitest_/
237
238
  ];
239
+ const NOW_LENGTH = Date.now().toString().length;
240
+ const REGEXP_VITEST = new RegExp(`vitest=\\d{${NOW_LENGTH}}`);
238
241
  function extractLocation(urlLike) {
239
242
  // Fail-fast but return locations like "(native)"
240
243
  if (!urlLike.includes(":")) {
@@ -259,6 +262,9 @@ function extractLocation(urlLike) {
259
262
  const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url);
260
263
  url = url.slice(isWindows ? 5 : 4);
261
264
  }
265
+ if (url.includes("vitest=")) {
266
+ url = url.replace(REGEXP_VITEST, "").replace(/[?&]$/, "");
267
+ }
262
268
  return [
263
269
  url,
264
270
  parts[2] || undefined,
@@ -352,7 +358,7 @@ function parseSingleV8Stack(raw) {
352
358
  // normalize Windows path (\ -> /)
353
359
  file = file.startsWith("node:") || file.startsWith("internal:") ? file : resolve(file);
354
360
  if (method) {
355
- method = method.replace(/__vite_ssr_import_\d+__\./g, "").replace(/(Object\.)?__vite_ssr_export_default__\s?/g, "");
361
+ method = method.replace(/\(0\s?,\s?__vite_ssr_import_\d+__.(\w+)\)/g, "$1").replace(/__(vite_ssr_import|vi_import)_\d+__\./g, "").replace(/(Object\.)?__vite_ssr_export_default__\s?/g, "");
356
362
  }
357
363
  return {
358
364
  method,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/utils",
3
3
  "type": "module",
4
- "version": "4.1.0-beta.1",
4
+ "version": "4.1.0-beta.3",
5
5
  "description": "Shared Vitest utility functions",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -82,7 +82,7 @@
82
82
  ],
83
83
  "dependencies": {
84
84
  "tinyrainbow": "^3.0.3",
85
- "@vitest/pretty-format": "4.1.0-beta.1"
85
+ "@vitest/pretty-format": "4.1.0-beta.3"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@jridgewell/trace-mapping": "0.3.31",