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
4 changes: 4 additions & 0 deletions guide/extending-matchers.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ function customMatcher(this: MatcherState, received: unknown, arg1: unknown, arg

expect.extend({ customMatcher })
```
<!-- TODO: translation -->
::: tip
To build custom **snapshot matchers** (wrappers around `toMatchSnapshot` / `toMatchInlineSnapshot` / `toMatchFileSnapshot`), use the composable functions from `vitest/runtime`. See [Custom Snapshot Matchers](/guide/snapshot#custom-snapshot-matchers).
:::

断言方法可以访问上下文 `this` 对象中的这些属性:

Expand Down
30 changes: 30 additions & 0 deletions guide/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,36 @@ export default defineConfig({
```

否则快照中会出现大量转义的 `"` 字符。
<!-- TODO: translation -->
### Custom Snapshot Matchers <Badge type="warning">experimental</Badge> <Version>4.1.3</Version>

Jest imports snapshot composables from `jest-snapshot`. In Vitest, import from `vitest/runtime` instead:

```ts
const { toMatchSnapshot } = require('jest-snapshot') // [!code --]
import { toMatchSnapshot } from 'vitest/runtime' // [!code ++]

expect.extend({
toMatchTrimmedSnapshot(received: string, length: number) {
return toMatchSnapshot.call(this, received.slice(0, length))
},
})
```

For inline snapshots, the same applies:

```ts
const { toMatchInlineSnapshot } = require('jest-snapshot') // [!code --]
import { toMatchInlineSnapshot } from 'vitest/runtime' // [!code ++]

expect.extend({
toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) {
return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot)
},
})
```

See [Custom Snapshot Matchers](/guide/snapshot#custom-snapshot-matchers) for the full guide.

## 从 Mocha + Chai + Sinon 迁移 {#mocha-chai-sinon}

Expand Down
70 changes: 70 additions & 0 deletions guide/snapshot.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,76 @@ Pretty foo: Object {
```

我们使用的是 Jest 的 `pretty-format` 来序列化快照。你可以在这里阅读更多相关内容:[pretty-format](https://github.com/facebook/jest/blob/main/packages/pretty-format/README.md#serialize).
<!-- TODO: translation -->
## 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).

```ts
import { expect, test } from 'vitest'
import { toMatchFileSnapshot, toMatchInlineSnapshot, toMatchSnapshot } from 'vitest/runtime'

expect.extend({
toMatchTrimmedSnapshot(received: string, length: number) {
return toMatchSnapshot.call(this, received.slice(0, length))
},
toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) {
return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot)
},
async toMatchTrimmedFileSnapshot(received: string, file: string) {
return toMatchFileSnapshot.call(this, received.slice(0, 10), file)
},
})

test('file snapshot', () => {
expect('extra long string oh my gerd').toMatchTrimmedSnapshot(10)
})

test('inline snapshot', () => {
expect('extra long string oh my gerd').toMatchTrimmedInlineSnapshot()
})

test('raw file snapshot', async () => {
await expect('extra long string oh my gerd').toMatchTrimmedFileSnapshot('./raw-file.txt')
})
```

The composables return `{ pass, message }` so you can further customize the error:

```ts
expect.extend({
toMatchTrimmedSnapshot(received: string, length: number) {
const result = toMatchSnapshot.call(this, received.slice(0, length))
return { ...result, message: () => `Trimmed snapshot failed: ${result.message()}` }
},
})
```

::: warning
For inline snapshot matchers, the snapshot argument must be the last parameter (or second-to-last when using property matchers). Vitest rewrites the last string argument in the source code, so custom arguments before the snapshot work, but custom arguments after it are not supported.
:::

::: tip
File snapshot matchers must be `async` — `toMatchFileSnapshot` returns a `Promise`. Remember to `await` the result in the matcher and in your test.
:::

For TypeScript, extend the `Assertion` interface:

```ts
import 'vitest'

declare module 'vitest' {
interface Assertion<T = any> {
toMatchTrimmedSnapshot: (length: number) => T
toMatchTrimmedInlineSnapshot: (inlineSnapshot?: string) => T
toMatchTrimmedFileSnapshot: (file: string) => Promise<T>
}
}
```

::: tip
See [Extending Matchers](/guide/extending-matchers) for more on `expect.extend` and custom matcher conventions.
:::

## 与 Jest 的区别 {#difference-from-jest}

Expand Down
2 changes: 1 addition & 1 deletion guide/test-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ This applies to all suite-level hooks: `beforeAll`, `afterAll`, and `aroundAll`.
:::

::: tip
Suite-level hooks can only access [**file-scoped** and **worker-scoped** fixtures](#fixture-scopes). Test-scoped fixtures are not available in these hooks because they run outside the context of individual tests. If you try to access a test-scoped fixture in a suite-level hook, Vitest will throw an error.
Suite-level hooks can only access [**file-scoped** and **worker-scoped** fixtures](#fixture-scopes), including `auto` fixtures. Test-scoped fixtures are not available in these hooks because they run outside the context of individual tests. If you try to access a test-scoped fixture in a suite-level hook, Vitest will throw an error.

```ts
const test = baseTest
Expand Down
Loading