Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/issue-labeled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ permissions:
issues: write
pull-requests: write


jobs:
reply-labeled:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion docs/api/browser/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ utils.configurePrettyDOM({
- **`maxLength`** - Maximum length of the output string (default: `7000`)
- **`filterNode`** - A CSS selector string or function to filter out nodes from the output. When a string is provided, elements matching the selector will be excluded. When a function is provided, it should return `false` to exclude a node.
- **`highlight`** - Enable syntax highlighting (default: `true`)
- And other options from [`pretty-format`](https://npmx.dev/package/@vitest/pretty-format)
- And other options from [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format)

#### Filtering with CSS Selectors <Version>4.1.0</Version> {#filtering-with-css-selectors}

Expand Down
2 changes: 2 additions & 0 deletions docs/config/diff.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ outline: deep

`DiffOptions` object or a path to a module which exports `DiffOptions`. Useful if you want to customize diff display.

Vitest diff rendering uses [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format) under the hood and a part of `DiffOptions` is forwarded to the pretty-format configuration, while the rest affects diff rendering itself.

For example, as a config object:

```ts
Expand Down
25 changes: 21 additions & 4 deletions docs/config/snapshotformat.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,29 @@ outline: deep

# snapshotFormat <CRoot />

- **Type:** `PrettyFormatOptions`
- **Type:** `Omit<PrettyFormatOptions, 'plugins' | 'compareKeys'> & { compareKeys?: null | undefined }`

Format options for snapshot testing. These options are passed down to our fork of [`pretty-format`](https://npmx.dev/package/pretty-format). In addition to the `pretty-format` options we support `printShadowRoot: boolean`.
Format options for snapshot testing. These options configure the snapshot-specific formatting layer built on top of [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format).

For the full option surface of `PrettyFormatOptions`, see [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format). This page focuses on the Vitest snapshot-specific defaults and constraints.

Vitest snapshots already apply these defaults before your `snapshotFormat` overrides:

- `printBasicPrototype: false`
- `escapeString: false`
- `escapeRegex: true`
- `printFunctionName: false`

Vitest also supports formatter options such as `printShadowRoot` and `maxOutputLength` in `snapshotFormat`.

`printShadowRoot` controls whether shadow-root contents are included in DOM snapshots.

`maxOutputLength` is an approximate per-depth output budget, not a hard cap on the final rendered string.

By default, snapshot keys are sorted using the formatter's default behavior. Set `compareKeys` to `null` to disable key sorting. Custom compare functions are not supported in `snapshotFormat`.

::: tip
Beware that `plugins` field on this object will be ignored.
Beware that `plugins` on this object will be ignored.

If you need to extend snapshot serializer via pretty-format plugins, please, use [`expect.addSnapshotSerializer`](/api/expect#expect-addsnapshotserializer) API or [snapshotSerializers](/config/snapshotserializers) option.
If you need to extend snapshot serialization via pretty-format plugins, use [`expect.addSnapshotSerializer`](/api/expect#expect-addsnapshotserializer) or [`snapshotSerializers`](/config/snapshotserializers) instead.
:::
6 changes: 3 additions & 3 deletions docs/guide/snapshot.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ exports['toUpperCase 1'] = '"FOOBAR"'

The snapshot artifact should be committed alongside code changes, and reviewed as part of your code review process. On subsequent test runs, Vitest will compare the rendered output with the previous snapshot. If they match, the test will pass. If they don't match, either the test runner found a bug in your code that should be fixed, or the implementation has changed and the snapshot needs to be updated.

Vitest stores a serialized representation of the received value. Snapshot rendering is powered by [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format). [`snapshotFormat`](/config/snapshotformat) allows configuring general snapshot formatting behavior in Vitest. For further customization, you can implement your own [custom serializers](#custom-serializer) or [custom snapshot matchers](#custom-snapshot-matchers).

::: warning
When using Snapshots with async concurrent tests, `expect` from the local [Test Context](/guide/test-context) must be used to ensure the right test is detected.
:::
Expand Down Expand Up @@ -198,8 +200,6 @@ Pretty foo: Object {
}
```

We are using Jest's `pretty-format` for serializing snapshots. You can read more about it here: [pretty-format](https://github.com/facebook/jest/blob/main/packages/pretty-format/README.md#serialize).

## Custom Snapshot Matchers <Badge type="warning">experimental</Badge> <Version>4.1.3</Version> {#custom-snapshot-matchers}

You can build custom snapshot matchers using the composable functions exported from `vitest/runtime`. These let you transform values before snapshotting while preserving full snapshot lifecycle support (creation, update, inline rewriting).
Expand Down Expand Up @@ -285,7 +285,7 @@ This does not really affect the functionality but might affect your commit diff

#### 2. `printBasicPrototype` is default to `false`

Both Jest and Vitest's snapshots are powered by [`pretty-format`](https://github.com/facebook/jest/blob/main/packages/pretty-format). In Vitest we set `printBasicPrototype` default to `false` to provide a cleaner snapshot output, while in Jest <29.0.0 it's `true` by default.
Both Jest and Vitest snapshots are powered by `pretty-format`, but Vitest applies its own snapshot defaults on top of [`@vitest/pretty-format`](https://npmx.dev/package/@vitest/pretty-format). In particular, Vitest sets `printBasicPrototype` to `false` to provide a cleaner snapshot output, while in Jest <29.0.0 it is `true` by default.

```ts
import { expect, test } from 'vitest'
Expand Down
4 changes: 2 additions & 2 deletions packages/pretty-format/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

[![NPM version](https://img.shields.io/npm/v/@vitest/pretty-format?color=a1b858&label=)](https://npmx.dev/package/@vitest/pretty-format)

Jest's `pretty-format` implementation that only supports ESM.
Vitest's fork of Jest's [`pretty-format`](https://npmx.dev/package/pretty-format).

[GitHub](https://github.com/vitest-dev/vitest/tree/main/packages/pretty-format) | [Documentation](https://vitest.dev/)
[GitHub](https://github.com/vitest-dev/vitest/tree/main/packages/pretty-format) | [Documentation](https://github.com/vitest-dev/vitest/blob/main/packages/pretty-format/USAGE.md)
170 changes: 170 additions & 0 deletions packages/pretty-format/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# @vitest/pretty-format

Vitest's fork of Jest's [`pretty-format`](https://npmx.dev/package/pretty-format), published as an ESM-only package.

This package powers several formatting paths in Vitest:

- snapshot serialization
- assertion diff rendering
- matcher and error messages
- browser `prettyDOM` output

## Usage

```ts
import { format } from '@vitest/pretty-format'

const value = {
user: 'Ada',
items: [1, 2, 3],
}

console.log(format(value))
/*
-- output --
Object {
"items": Array [
1,
2,
3,
],
"user": "Ada",
}
*/
```

## Options

| key | type | default | notes |
| :-------------------- | :--------------- | :---------- | :------------------------------------------------------------------- |
| `callToJSON` | `boolean` | `true` | Call `toJSON` if present |
| `compareKeys` | `function\|null` | `undefined` | Compare function for sorting object keys. Use `null` to skip sorting |
| `escapeRegex` | `boolean` | `false` | Escape special characters in regular expressions |
| `escapeString` | `boolean` | `true` | Escape special characters in strings |
| `highlight` | `boolean` | `false` | Highlight syntax with terminal colors |
| `indent` | `number` | `2` | Spaces per indentation level |
| `maxDepth` | `number` | `Infinity` | Maximum depth to print |
| `maxOutputLength` | `number` | `1_000_000` | Approximate per-depth output budget |
| `maxWidth` | `number` | `Infinity` | Maximum number of items to print in collections |
| `min` | `boolean` | `false` | Minimize added whitespace |
| `plugins` | `array` | `[]` | Plugins to serialize application-specific data types |
| `printBasicPrototype` | `boolean` | `true` | Print `Object` and `Array` prefixes for plain objects and arrays |
| `printFunctionName` | `boolean` | `true` | Include or omit the function name |
| `printShadowRoot` | `boolean` | `true` | Include shadow-root contents when formatting DOM nodes |

Important:

- `plugins: []` means the package does not auto-enable its built-in plugins by default
- Vitest features opt into their own plugin stacks and option presets

## Built-in Plugins

The package exports these built-in plugins:

- `ReactTestComponent`
- `ReactElement`
- `DOMElement`
- `DOMCollection`
- `Immutable`
- `AsymmetricMatcher`
- `Error`

You can use them directly with `format(..., { plugins })`:

```ts
import { format, plugins } from '@vitest/pretty-format'

console.log(
format(document.body, {
plugins: [plugins.DOMElement, plugins.DOMCollection],
}),
)
```

## Vitest Extensions

Besides the inherited `pretty-format` API surface, Vitest currently adds and documents these notable behaviors:

### `printShadowRoot`

Controls whether DOM serialization includes shadow-root contents.

```ts
format(element, {
printShadowRoot: false,
})
```

### `maxOutputLength`

Approximate per-depth output budget used to prevent pathological expansion of large recursive structures.

This is a heuristic safety valve, not a hard cap on the final string length.

```ts
format(value, {
maxOutputLength: 100_000,
})
```

## How Vitest Uses It

### Snapshots

Snapshots use `@vitest/pretty-format` with snapshot-specific defaults such as:

- `printBasicPrototype: false`
- `escapeString: false`
- `escapeRegex: true`
- `printFunctionName: false`

Default snapshot plugin stack:

- `ReactTestComponent`
- `ReactElement`
- `DOMElement`
- `DOMCollection`
- `Immutable`
- `AsymmetricMatcher`
- `MockSerializer`

Snapshot formatting is configured through [`test.snapshotFormat`](https://vitest.dev/config/snapshotformat), while serializer registration goes through [`expect.addSnapshotSerializer`](https://vitest.dev/api/expect#expect-addsnapshotserializer) or [`snapshotSerializers`](https://vitest.dev/config/snapshotserializers).

### Diffs

Assertion diffs use a different preset and plugin stack.

Default diff plugins:

- `ReactTestComponent`
- `ReactElement`
- `DOMElement`
- `DOMCollection`
- `Immutable`
- `AsymmetricMatcher`
- `Error`

### Vitest `stringify`

Matcher and error messages commonly go through Vitest's internal [`stringify`](https://github.com/vitest-dev/vitest/blob/59b0e6411be2b4aa5f2b339d02691aa83d5e403f/packages/utils/src/display.ts#L49) utility, which uses:

- `ReactTestComponent`
- `ReactElement`
- `DOMElement`
- `DOMCollection`
- `Immutable`
- `AsymmetricMatcher`

`stringify` also adds wrapper-level behavior on top of `@vitest/pretty-format`:

- `maxLength`: if the formatted output grows too large, `stringify` retries with a smaller `maxDepth` to keep the result bounded
- `filterNode`: swaps the default DOM plugin for a filtered variant so selected nodes are omitted from the output
- fallback on formatter errors: if formatting throws, `stringify` retries with `callToJSON: false`

### Browser `prettyDOM`

Browser `prettyDOM` builds on Vitest's `stringify` path and enables browser-oriented defaults such as:

- `highlight: true`

It can also replace the default DOM plugin with a filtered variant when `filterNode` is configured.
52 changes: 52 additions & 0 deletions packages/pretty-format/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,41 @@ export interface Options
}

export interface PrettyFormatOptions {
/**
* Call `toJSON` on objects before formatting them.
* Ignored after the formatter has already called `toJSON` once for a value.
* @default true
*/
callToJSON?: boolean
/**
* Whether to escape special characters in regular expressions.
* @default false
*/
escapeRegex?: boolean
/**
* Whether to escape special characters in strings.
* @default true
*/
escapeString?: boolean
/**
* Whether to highlight syntax using terminal colors.
* @default false
*/
highlight?: boolean
/**
* Number of spaces to use for each level of indentation.
* @default 2
*/
indent?: number
/**
* Maximum depth to recurse into nested values.
* @default Infinity
*/
maxDepth?: number
/**
* Maximum number of items to print in arrays, sets, maps, and similar collections.
* @default Infinity
*/
maxWidth?: number
/**
* Approximate per-depth-level budget for output length.
Expand All @@ -53,11 +82,34 @@ export interface PrettyFormatOptions {
* @default 1_000_000
*/
maxOutputLength?: number
/**
* Whether to minimize added whitespace, including indentation and line breaks.
* @default false
*/
min?: boolean
/**
* Whether to print `Object` / `Array` prefixes for plain objects and arrays.
* @default true
*/
printBasicPrototype?: boolean
/**
* Whether to include the function name when formatting functions.
* @default true
*/
printFunctionName?: boolean
/**
* Whether to include shadow-root contents when formatting DOM nodes.
* @default true
*/
printShadowRoot?: boolean
/**
* Compare function used when sorting object keys. Set to `null` to disable sorting.
*/
compareKeys?: CompareKeys
/**
* Plugins used to serialize application-specific data types.
* @default []
*/
plugins?: Plugins
}

Expand Down
Loading
Loading