Skip to content

Commit

Permalink
feat: support inline diff options and support printBasicPrototype (
Browse files Browse the repository at this point in the history
…#6740)

Co-authored-by: Vladimir <[email protected]>
Co-authored-by: Michał Grzegorzewski <[email protected]>
  • Loading branch information
3 people authored Nov 13, 2024
1 parent 32f23b9 commit 391860f
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 20 deletions.
58 changes: 48 additions & 10 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2284,22 +2284,32 @@ export default defineConfig({
### diff

- **Type:** `string`
- **CLI:** `--diff=<value>`
- **CLI:** `--diff=<path>`

Path to a diff config that will be used to generate diff interface. Useful if you want to customize diff display.
`DiffOptions` object or a path to a module which exports `DiffOptions`. Useful if you want to customize diff display.

For example, as a config object:

:::code-group
```ts [vitest.diff.ts]
import type { DiffOptions } from 'vitest'
import c from 'tinyrainbow'
```ts [vitest.config.js]
import { defineConfig } from 'vitest/config'
import c from 'picocolors'

export default {
aIndicator: c.bold('--'),
bIndicator: c.bold('++'),
omitAnnotationLines: true,
} satisfies DiffOptions
export default defineConfig({
test: {
diff: {
aIndicator: c.bold('--'),
bIndicator: c.bold('++'),
omitAnnotationLines: true,
}
}
})
```
:::

Or as a module:

:::code-group
```ts [vitest.config.js]
import { defineConfig } from 'vitest/config'

Expand All @@ -2309,12 +2319,32 @@ export default defineConfig({
}
})
```

```ts [vitest.diff.ts]
import type { DiffOptions } from 'vitest'
import c from 'picocolors'

export default {
aIndicator: c.bold('--'),
bIndicator: c.bold('++'),
omitAnnotationLines: true,
} satisfies DiffOptions
```
:::

#### diff.expand

- **Type**: `boolean`
- **Default**: `true`
- **CLI:** `--diff.expand=false`

Expand all common lines.

#### diff.truncateThreshold

- **Type**: `number`
- **Default**: `0`
- **CLI:** `--diff.truncateThreshold=<path>`

The maximum length of diff result to be displayed. Diffs above this threshold will be truncated.
Truncation won't take effect with default value 0.
Expand All @@ -2323,6 +2353,7 @@ Truncation won't take effect with default value 0.

- **Type**: `string`
- **Default**: `'... Diff result is truncated'`
- **CLI:** `--diff.truncateAnnotation=<annotation>`

Annotation that is output at the end of diff result if it's truncated.

Expand All @@ -2333,6 +2364,13 @@ Annotation that is output at the end of diff result if it's truncated.

Color of truncate annotation, default is output with no color.

#### diff.printBasicPrototype

- **Type**: `boolean`
- **Default**: `true`

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

### fakeTimers

- **Type:** `FakeTimerInstallOpts`
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/src/node/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
'msw/browser',
]

if (project.config.diff) {
if (typeof project.config.diff === 'string') {
entries.push(project.config.diff)
}

Expand Down
5 changes: 3 additions & 2 deletions packages/utils/src/diff/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { getType } from './getType'
import { normalizeDiffOptions } from './normalizeDiffOptions'
import { diffStringsRaw, diffStringsUnified } from './printDiffs'

export type { DiffOptions, DiffOptionsColor } from './types'
export type { DiffOptions, DiffOptionsColor, SerializedDiffOptions } from './types'

export { diffLinesRaw, diffLinesUnified, diffLinesUnified2 }
export { diffStringsRaw, diffStringsUnified }
Expand Down Expand Up @@ -180,11 +180,12 @@ function getFormatOptions(
formatOptions: PrettyFormatOptions,
options?: DiffOptions,
): PrettyFormatOptions {
const { compareKeys } = normalizeDiffOptions(options)
const { compareKeys, printBasicPrototype } = normalizeDiffOptions(options)

return {
...formatOptions,
compareKeys,
printBasicPrototype,
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/diff/normalizeDiffOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function getDefaultOptions(): DiffOptionsNormalized {
includeChangeCounts: false,
omitAnnotationLines: false,
patchColor: c.yellow,
printBasicPrototype: true,
truncateThreshold: DIFF_TRUNCATE_THRESHOLD_DEFAULT,
truncateAnnotation: '... Diff result is truncated',
truncateAnnotationColor: noColor,
Expand Down
18 changes: 18 additions & 0 deletions packages/utils/src/diff/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,29 @@ export interface DiffOptions {
includeChangeCounts?: boolean
omitAnnotationLines?: boolean
patchColor?: DiffOptionsColor
printBasicPrototype?: boolean
compareKeys?: CompareKeys
truncateThreshold?: number
truncateAnnotation?: string
truncateAnnotationColor?: DiffOptionsColor
}

export interface SerializedDiffOptions {
aAnnotation?: string
aIndicator?: string
bAnnotation?: string
bIndicator?: string
commonIndicator?: string
contextLines?: number
emptyFirstOrLastLinePlaceholder?: string
expand?: boolean
includeChangeCounts?: boolean
omitAnnotationLines?: boolean
printBasicPrototype?: boolean
truncateThreshold?: number
truncateAnnotation?: string
}

export interface DiffOptionsNormalized {
aAnnotation: string
aColor: DiffOptionsColor
Expand All @@ -51,6 +68,7 @@ export interface DiffOptionsNormalized {
includeChangeCounts: boolean
omitAnnotationLines: boolean
patchColor: DiffOptionsColor
printBasicPrototype: boolean
truncateThreshold: number
truncateAnnotation: string
truncateAnnotationColor: DiffOptionsColor
Expand Down
53 changes: 51 additions & 2 deletions packages/vitest/src/node/cli/cli-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,9 +599,58 @@ export const cliOptionsConfig: VitestCLIOptions = {
},
diff: {
description:
'Path to a diff config that will be used to generate diff interface',
'DiffOptions object or a path to a module which exports DiffOptions object',
argument: '<path>',
normalize: true,
subcommands: {
aAnnotation: {
description: 'Annotation for expected lines (default: `Expected`)',
argument: '<annotation>',
},
aIndicator: {
description: 'Indicator for expected lines (default: `-`)',
argument: '<indicator>',
},
bAnnotation: {
description: 'Annotation for received lines (default: `Received`)',
argument: '<annotation>',
},
bIndicator: {
description: 'Indicator for received lines (default: `+`)',
argument: '<indicator>',
},
commonIndicator: {
description: 'Indicator for common lines (default: ` `)',
argument: '<indicator>',
},
contextLines: {
description: 'Number of lines of context to show around each change (default: `5`)',
argument: '<lines>',
},
emptyFirstOrLastLinePlaceholder: {
description: 'Placeholder for an empty first or last line (default: `""`)',
argument: '<placeholder>',
},
expand: {
description: 'Expand all common lines (default: `true`)',
},
includeChangeCounts: {
description: 'Include comparison counts in diff output (default: `false`)',
},
omitAnnotationLines: {
description: 'Omit annotation lines from the output (default: `false`)',
},
printBasicPrototype: {
description: 'Print basic prototype Object and Array (default: `true`)',
},
truncateThreshold: {
description: 'Number of lines to show before and after each change (default: `0`)',
argument: '<threshold>',
},
truncateAnnotation: {
description: 'Annotation for truncated lines (default: `... Diff result is truncated`)',
argument: '<annotation>',
},
},
},
exclude: {
description: 'Additional file globs to be excluded from test',
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/config/resolveConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ export function resolveConfig(
}
}

if (resolved.diff) {
if (typeof resolved.diff === 'string') {
resolved.diff = resolvePath(resolved.diff, resolved.root)
resolved.forceRerunTriggers.push(resolved.diff)
}
Expand Down
1 change: 1 addition & 0 deletions packages/vitest/src/node/config/serializeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export function serializeConfig(
pool: config.pool,
expect: config.expect,
snapshotSerializers: config.snapshotSerializers,
// TODO: non serializable function?
diff: config.diff,
retry: config.retry,
disableConsoleIntercept: config.disableConsoleIntercept,
Expand Down
5 changes: 3 additions & 2 deletions packages/vitest/src/node/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers'
import type { PrettyFormatOptions } from '@vitest/pretty-format'
import type { SequenceHooks, SequenceSetupFiles } from '@vitest/runner'
import type { SnapshotStateOptions } from '@vitest/snapshot'
import type { SerializedDiffOptions } from '@vitest/utils/diff'
import type { AliasOptions, ConfigEnv, DepOptimizationConfig, ServerOptions, UserConfig as ViteUserConfig } from 'vite'
import type { ViteNodeServerOptions } from 'vite-node'
import type { ChaiConfig } from '../../integrations/chai/config'
Expand Down Expand Up @@ -563,7 +564,7 @@ export interface InlineConfig {
/**
* Path to a module which has a default export of diff config.
*/
diff?: string
diff?: string | SerializedDiffOptions

/**
* Paths to snapshot serializer modules.
Expand Down Expand Up @@ -979,7 +980,7 @@ export interface ResolvedConfig
mode: VitestRunMode

base?: string
diff?: string
diff?: string | SerializedDiffOptions
bail?: number

setupFiles: string[]
Expand Down
3 changes: 2 additions & 1 deletion packages/vitest/src/runtime/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { PrettyFormatOptions } from '@vitest/pretty-format'
import type { SequenceHooks, SequenceSetupFiles } from '@vitest/runner'
import type { SnapshotUpdateState } from '@vitest/snapshot'
import type { SnapshotEnvironment } from '@vitest/snapshot/environment'
import type { SerializedDiffOptions } from '@vitest/utils/diff'

/**
* Config that tests have access to.
Expand Down Expand Up @@ -98,7 +99,7 @@ export interface SerializedConfig {
showDiff?: boolean
truncateThreshold?: number
} | undefined
diff: string | undefined
diff: string | SerializedDiffOptions | undefined
retry: number
includeTaskLocation: boolean | undefined
inspect: boolean | string | undefined
Expand Down
3 changes: 3 additions & 0 deletions packages/vitest/src/runtime/setup-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export async function loadDiffConfig(
config: SerializedConfig,
executor: VitestExecutor,
) {
if (typeof config.diff === 'object') {
return config.diff
}
if (typeof config.diff !== 'string') {
return
}
Expand Down
20 changes: 20 additions & 0 deletions test/config/fixtures/diff/basic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, test } from 'vitest'

test('large diff', () => {
const x = [...Array(30)].map((_, i) => i);
const y = [...x];
y[0] = 1000;
y[15] = 2000;
y[29] = 3000;
expect(x).toEqual(y)
})

test("printBasicPrototype", () => {
expect({
obj: { k: "foo" },
arr: [1, 2]
}).toEqual({
obj: { k: "bar" },
arr: [1, 3]
});
})
10 changes: 10 additions & 0 deletions test/config/fixtures/diff/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {defineConfig} from 'vitest/config'

export default defineConfig({
test: {
diff: {
// expand: false,
// printBasicPrototype: false,
}
}
})
Loading

0 comments on commit 391860f

Please sign in to comment.