-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix: support snapshot with expect.soft
#9231
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
Changes from 33 commits
b46594e
81bddb7
135dbc1
84e80f7
48e2175
ddb7747
654bb37
10b2914
ad74f7e
4e43f49
ffa7cf4
a7305c1
4da1cf4
686f7da
bc08a4c
d49fb31
71449ab
bd60ae4
d3ac41b
b24963b
b65a986
c2a0c90
add5a14
445a8f4
834aed2
9aad5a4
dbd3bd3
59f03fa
893628e
847a2bd
a03645f
6b6bdf4
7d754ab
658a1a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -168,6 +168,15 @@ export default class SnapshotState { | |
| return stacks[promiseIndex + 3] | ||
| } | ||
|
|
||
| // inline snapshot function can be named __INLINE_SNAPSHOT_OFFSET_<n>__ | ||
| // to specify a custom stack offset | ||
| for (let i = 0; i < stacks.length; i++) { | ||
| const match = stacks[i].method.match(/__INLINE_SNAPSHOT_OFFSET_(\d+)__/) | ||
| if (match) { | ||
| return stacks[i + Number(match[1])] ?? null | ||
| } | ||
| } | ||
|
Comment on lines
+171
to
+178
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added minor enhancement on |
||
|
|
||
| // inline snapshot function is called __INLINE_SNAPSHOT__ | ||
| // in integrations/snapshot/chai.ts | ||
| const stackIndex = stacks.findIndex(i => | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a quick guide for snapshot test suites. We can likely simplify |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # Snapshot Tests | ||
|
|
||
| This directory contains integration tests for Vitest's snapshot functionality. It uses a meta-testing approach where integration tests programmatically run fixture tests to validate snapshot behavior. | ||
|
|
||
| ## Directory Structure | ||
|
|
||
| ``` | ||
| test/snapshots/ | ||
| ├── test/ # Integration tests that validate snapshot features | ||
| │ └── fixtures/ # Test fixture files (copied to test-update/) | ||
| ├── test-update/ # Generated directory - populated from fixtures | ||
| ├── generate.mjs # Resets test-update/ from fixtures | ||
| └── vitest.config.ts # Test configuration | ||
| ``` | ||
|
|
||
| ## Test Scripts | ||
|
|
||
| | Script | Purpose | | ||
| |--------|---------| | ||
| | `test` | Runs the complete test suite (all scripts below in sequence) | | ||
| | `test:generate` | Resets `test-update/` by copying fresh fixtures | | ||
| | `test:update` | Runs tests with `-u` flag to update existing snapshots | | ||
| | `test:update-new` | Runs with `CI=false` to create new snapshots | | ||
| | `test:update-none` | Runs with `CI=true` to validate without updates (strict mode) | | ||
| | `test:integration` | Runs the main integration tests in `test/` | | ||
|
|
||
| ## How It Works | ||
|
|
||
| 1. **`generate.mjs`** copies fixture files from `test/fixtures/test-update/` to `test-update/` | ||
| 2. **`test:update*` scripts** run the fixture tests with different snapshot update modes | ||
| 3. **`test:integration`** runs integration tests that use `runVitest()` to programmatically execute fixtures and assert on the results | ||
|
|
||
| This setup allows testing snapshot features like: | ||
| - Inline snapshots (`toMatchInlineSnapshot`) | ||
| - File-based snapshots (`toMatchFileSnapshot`) | ||
| - Snapshot update behavior with `-u` flag | ||
| - CI vs non-CI snapshot creation modes | ||
| - Custom serializers, soft assertions, retry logic, etc. | ||
|
|
||
| ## Running Tests | ||
|
|
||
| ```bash | ||
| # Run all snapshot tests | ||
| pnpm test | ||
|
|
||
| # Or run individual stages | ||
| # - Reset fixtures | ||
| pnpm test:generate | ||
| # - Run integration tests only | ||
| pnpm test:integration | ||
| pnpm test:integration test/summary.test.ts | ||
|
|
||
| # Run one of fixtures directly | ||
| pnpm test:fixtures --root test/fixtures/summary | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { expect, test } from 'vitest' | ||
|
|
||
| test('toMatchInlineSnapshot', () => { | ||
| expect.soft('--snap-1--').toMatchInlineSnapshot(`"--snap-1--"`) | ||
| expect.soft('--snap-2--').toMatchInlineSnapshot(`"--snap-2--"`) | ||
| }) | ||
|
|
||
| test('toThrowErrorMatchingInlineSnapshot', () => { | ||
| expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingInlineSnapshot(`[Error: --error-1--]`) | ||
| expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingInlineSnapshot(`[Error: --error-2--]`) | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| __snapshots__ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { expect, test } from 'vitest' | ||
|
|
||
| test('toMatchSnapshot', () => { | ||
| expect.soft('--snap-1--').toMatchSnapshot() | ||
| expect.soft('--snap-2--').toMatchSnapshot() | ||
| }) | ||
|
|
||
| test('toMatchFileSnapshot', async () => { | ||
| await expect.soft('--file-1--').toMatchFileSnapshot('./__snapshots__/custom1.txt') | ||
| await expect.soft('--file-2--').toMatchFileSnapshot('./__snapshots__/custom2.txt') | ||
| }) | ||
|
|
||
| test('toThrowErrorMatchingSnapshot', () => { | ||
| expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingSnapshot() | ||
| expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingSnapshot() | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are likely several ways to make
softand async assertion work together. Some coupling ofrecordAsyncExpectandwrapAssertionis imminent and I went with this approach ofrecordAsyncExpecttaking over soft logic. Not too clean but code wise simplest.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually if
recordAsyncExpectis handingexpect.softlogic,wrapAssertionshouldn't be needed. Rethinking.EDIT: 658a1a1