Skip to content

Commit eacab25

Browse files
authored
feat: add diff.maxDepth option and set non-Infinity value as a default to reduce crash (#7481)
1 parent f9e1cb4 commit eacab25

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

docs/config/index.md

+7
Original file line numberDiff line numberDiff line change
@@ -2331,6 +2331,13 @@ Color of truncate annotation, default is output with no color.
23312331

23322332
Print basic prototype `Object` and `Array` in diff output
23332333

2334+
#### diff.maxDepth
2335+
2336+
- **Type**: `number`
2337+
- **Default**: `20` (or `8` when comparing different types)
2338+
2339+
Limit the depth to recurse when printing nested objects
2340+
23342341
### fakeTimers
23352342

23362343
- **Type:** `FakeTimerInstallOpts`

packages/utils/src/diff/index.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ const PLUGINS = [
5353
prettyFormatPlugins.Error,
5454
]
5555
const FORMAT_OPTIONS = {
56+
maxDepth: 20,
5657
plugins: PLUGINS,
57-
}
58+
} satisfies PrettyFormatOptions
5859
const FALLBACK_FORMAT_OPTIONS = {
5960
callToJSON: false,
6061
maxDepth: 8,
6162
plugins: PLUGINS,
62-
}
63+
} satisfies PrettyFormatOptions
6364

6465
// Generate a string that will highlight the difference between two values
6566
// with green and red. (similar to how github does code diffing)
@@ -191,12 +192,13 @@ function getFormatOptions(
191192
formatOptions: PrettyFormatOptions,
192193
options?: DiffOptions,
193194
): PrettyFormatOptions {
194-
const { compareKeys, printBasicPrototype } = normalizeDiffOptions(options)
195+
const { compareKeys, printBasicPrototype, maxDepth } = normalizeDiffOptions(options)
195196

196197
return {
197198
...formatOptions,
198199
compareKeys,
199200
printBasicPrototype,
201+
maxDepth: maxDepth ?? formatOptions.maxDepth,
200202
}
201203
}
202204

packages/utils/src/diff/types.ts

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export interface DiffOptions {
2727
omitAnnotationLines?: boolean
2828
patchColor?: DiffOptionsColor
2929
printBasicPrototype?: boolean
30+
maxDepth?: number
3031
compareKeys?: CompareKeys
3132
truncateThreshold?: number
3233
truncateAnnotation?: string
@@ -45,6 +46,7 @@ export interface SerializedDiffOptions {
4546
includeChangeCounts?: boolean
4647
omitAnnotationLines?: boolean
4748
printBasicPrototype?: boolean
49+
maxDepth?: number
4850
truncateThreshold?: number
4951
truncateAnnotation?: string
5052
}
@@ -69,6 +71,7 @@ export interface DiffOptionsNormalized {
6971
omitAnnotationLines: boolean
7072
patchColor: DiffOptionsColor
7173
printBasicPrototype: boolean
74+
maxDepth?: number
7275
truncateThreshold: number
7376
truncateAnnotation: string
7477
truncateAnnotationColor: DiffOptionsColor

packages/vitest/src/node/cli/cli-config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,10 @@ export const cliOptionsConfig: VitestCLIOptions = {
648648
printBasicPrototype: {
649649
description: 'Print basic prototype Object and Array (default: `true`)',
650650
},
651+
maxDepth: {
652+
description: 'Limit the depth to recurse when printing nested objects (default: `20`)',
653+
argument: '<maxDepth>',
654+
},
651655
truncateThreshold: {
652656
description: 'Number of lines to show before and after each change (default: `0`)',
653657
argument: '<threshold>',

test/core/test/diff.test.ts

+19
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,25 @@ test('truncate large diff', () => {
324324
expect(diff.trim()).toMatch(/\.\.\.$/)
325325
})
326326

327+
test('diff default maxDepth', () => {
328+
function generateCycle(n: number) {
329+
const nodes = Array.from({ length: n }, (_, i) => ({ i, next: null as any }))
330+
nodes.forEach((node, i) => {
331+
node.next = nodes[(i + 1) % n]
332+
})
333+
return nodes
334+
}
335+
336+
// diff only appears in a deeper depth than maxDepth
337+
const xs = generateCycle(20)
338+
const ys = generateCycle(20)
339+
ys[10].i = -1
340+
const diff = getErrorDiff(xs[0], ys[0], { maxDepth: 5 })
341+
expect(stripVTControlCharacters(diff)).toMatchInlineSnapshot(
342+
`"Compared values have no visual difference."`,
343+
)
344+
})
345+
327346
function getErrorDiff(actual: unknown, expected: unknown, options?: DiffOptions): string {
328347
try {
329348
expect(actual).toEqual(expected)

0 commit comments

Comments
 (0)