Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support inline diff options and support printBasicPrototype #6740

Merged
merged 17 commits into from
Nov 13, 2024
Merged
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