diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index 13e994812b27..db2b1e389f96 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -8,11 +8,12 @@ export function createAssertionMessage( assertion: Assertion, hasArgs: boolean, ) { + const soft = util.flag(assertion, 'soft') ? '.soft' : '' const not = util.flag(assertion, 'negate') ? 'not.' : '' const name = `${util.flag(assertion, '_name')}(${hasArgs ? 'expected' : ''})` const promiseName = util.flag(assertion, 'promise') const promise = promiseName ? `.${promiseName}` : '' - return `expect(actual)${promise}.${not}${name}` + return `expect${soft}(actual)${promise}.${not}${name}` } export function recordAsyncExpect( @@ -20,6 +21,7 @@ export function recordAsyncExpect( promise: Promise, assertion: string, error: Error, + isSoft?: boolean, ): Promise { const test = _test as Test | undefined // record promise for test, that resolves before test ends @@ -39,6 +41,13 @@ export function recordAsyncExpect( if (!test.promises) { test.promises = [] } + // setup `expect.soft` handler here instead of `wrapAssertion` + // to avoid double error tracking while keeping non-await promise detection. + if (isSoft) { + promise = promise.then(noop, (err) => { + handleTestError(test, err) + }) + } test.promises.push(promise) let resolved = false @@ -93,7 +102,14 @@ export function wrapAssertion( } if (!utils.flag(this, 'soft')) { - return fn.apply(this, args) + // avoid WebKit's proper tail call to preserve stacktrace offset for inline snapshot + // https://webkit.org/blog/6240/ecmascript-6-proper-tail-calls-in-webkit + try { + return fn.apply(this, args) + } + finally { + // no lint + } } const test: Test = utils.flag(this, 'vitest-test') diff --git a/packages/snapshot/src/port/state.ts b/packages/snapshot/src/port/state.ts index e691822ba8d4..b197bc577e50 100644 --- a/packages/snapshot/src/port/state.ts +++ b/packages/snapshot/src/port/state.ts @@ -168,6 +168,15 @@ export default class SnapshotState { return stacks[promiseIndex + 3] } + // inline snapshot function can be named __INLINE_SNAPSHOT_OFFSET___ + // 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 + } + } + // inline snapshot function is called __INLINE_SNAPSHOT__ // in integrations/snapshot/chai.ts const stackIndex = stacks.findIndex(i => diff --git a/packages/vitest/src/integrations/snapshot/chai.ts b/packages/vitest/src/integrations/snapshot/chai.ts index 27bd424e4fef..9bbc1f1bcfc8 100644 --- a/packages/vitest/src/integrations/snapshot/chai.ts +++ b/packages/vitest/src/integrations/snapshot/chai.ts @@ -7,7 +7,7 @@ import { SnapshotClient, stripSnapshotIndentation, } from '@vitest/snapshot' -import { createAssertionMessage, recordAsyncExpect } from '../../../../expect/src/utils' +import { createAssertionMessage, recordAsyncExpect, wrapAssertion } from '../../../../expect/src/utils' let _client: SnapshotClient @@ -65,8 +65,8 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { utils.addMethod( chai.Assertion.prototype, key, - function ( - this: Record, + wrapAssertion(utils, key, function ( + this, properties?: object, message?: string, ) { @@ -90,7 +90,7 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { errorMessage, ...getTestNames(test), }) - }, + }), ) } @@ -124,6 +124,7 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { promise, createAssertionMessage(utils, this, true), error, + utils.flag(this, 'soft'), ) }, ) @@ -131,8 +132,8 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { utils.addMethod( chai.Assertion.prototype, 'toMatchInlineSnapshot', - function __INLINE_SNAPSHOT__( - this: Record, + wrapAssertion(utils, 'toMatchInlineSnapshot', function __INLINE_SNAPSHOT_OFFSET_3__( + this, properties?: object, inlineSnapshot?: string, message?: string, @@ -171,12 +172,12 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { errorMessage, ...getTestNames(test), }) - }, + }), ) utils.addMethod( chai.Assertion.prototype, 'toThrowErrorMatchingSnapshot', - function (this: Record, message?: string) { + wrapAssertion(utils, 'toThrowErrorMatchingSnapshot', function (this, properties?: object, message?: string) { utils.flag(this, '_name', 'toThrowErrorMatchingSnapshot') const isNot = utils.flag(this, 'negate') if (isNot) { @@ -194,13 +195,13 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { errorMessage, ...getTestNames(test), }) - }, + }), ) utils.addMethod( chai.Assertion.prototype, 'toThrowErrorMatchingInlineSnapshot', - function __INLINE_SNAPSHOT__( - this: Record, + wrapAssertion(utils, 'toThrowErrorMatchingInlineSnapshot', function __INLINE_SNAPSHOT_OFFSET_3__( + this, inlineSnapshot: string, message: string, ) { @@ -235,7 +236,7 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { errorMessage, ...getTestNames(test), }) - }, + }), ) utils.addMethod(chai.expect, 'addSnapshotSerializer', addSerializer) } diff --git a/test/cli/test/fails.test.ts b/test/cli/test/fails.test.ts index 3113d215be18..a20c6eb35a3f 100644 --- a/test/cli/test/fails.test.ts +++ b/test/cli/test/fails.test.ts @@ -1,4 +1,3 @@ -import type { TestCase } from 'vitest/node' import { playwright } from '@vitest/browser-playwright' import { resolve } from 'pathe' @@ -51,7 +50,7 @@ it('should not report coverage when "coverage.reportOnFailure" has default value }) it('prints a warning if the assertion is not awaited', async () => { - const { stderr, results, root } = await runInlineTests({ + const { stderr, root, errorTree } = await runInlineTests({ 'base.test.js': ts` import { expect, test } from 'vitest'; @@ -69,21 +68,30 @@ it('prints a warning if the assertion is not awaited', async () => { expect(1).toBe(2) }) - test('toMatchSnapshot not awaited', () => { + test('toMatchFileSnapshot not awaited', () => { expect(1).toMatchFileSnapshot('./snapshot.txt') }) + + test('soft + toMatchFileSnapshot not awaited', () => { + expect.soft(1).toMatchFileSnapshot('./snapshot-soft.txt') + }) `, + }, { + update: true, }) - expect(results[0].children.size).toEqual(4) - const failedTest = results[0].children.at(2) as TestCase - expect(failedTest.result()).toEqual({ - state: 'failed', - errors: [ - expect.objectContaining({ - message: expect.stringContaining('expected 1 to be 2'), - }), - ], - }) + expect(errorTree()).toMatchInlineSnapshot(` + { + "base.test.js": { + "not awaited and failed": [ + "expected 1 to be 2 // Object.is equality", + ], + "several not awaited": "passed", + "single not awaited": "passed", + "soft + toMatchFileSnapshot not awaited": "passed", + "toMatchFileSnapshot not awaited": "passed", + }, + } + `) const warnings: string[] = [] const lines = stderr.split('\n') lines.forEach((line, index) => { @@ -103,6 +111,8 @@ it('prints a warning if the assertion is not awaited', async () => { at /base.test.js:14:33", "Promise returned by \`expect(actual).toMatchFileSnapshot(expected)\` was not awaited. Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in the next Vitest major. Please remember to await the assertion. at /base.test.js:19:17", + "Promise returned by \`expect.soft(actual).toMatchFileSnapshot(expected)\` was not awaited. Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in the next Vitest major. Please remember to await the assertion. + at /base.test.js:23:22", ] `) }) diff --git a/test/snapshots/README.md b/test/snapshots/README.md new file mode 100644 index 000000000000..a2f4427e10fc --- /dev/null +++ b/test/snapshots/README.md @@ -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 +``` diff --git a/test/snapshots/package.json b/test/snapshots/package.json index 2a86029d5d7f..4f216938bb8c 100644 --- a/test/snapshots/package.json +++ b/test/snapshots/package.json @@ -3,9 +3,9 @@ "type": "module", "private": true, "scripts": { - "test": "pnpm run test:generate && pnpm run test:update && pnpm test:update-new && pnpm test:update-none && pnpm run test:snaps", + "test": "pnpm run test:generate && pnpm run test:update && pnpm test:update-new && pnpm test:update-none && pnpm run test:integration", "test:generate": "node ./generate.mjs", - "test:snaps": "vitest run --dir test", + "test:integration": "vitest run --dir test", "test:update": "vitest run -u --dir test-update", "test:update-none": "CI=true vitest run --dir test-update", "test:update-new": "CI=false vitest run --dir test-update", diff --git a/test/snapshots/test/fixtures/soft-inline/basic.test.ts b/test/snapshots/test/fixtures/soft-inline/basic.test.ts new file mode 100644 index 000000000000..b46e53389bad --- /dev/null +++ b/test/snapshots/test/fixtures/soft-inline/basic.test.ts @@ -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--]`) +}) diff --git a/test/snapshots/test/fixtures/soft/.gitignore b/test/snapshots/test/fixtures/soft/.gitignore new file mode 100644 index 000000000000..b05c2dfa7007 --- /dev/null +++ b/test/snapshots/test/fixtures/soft/.gitignore @@ -0,0 +1 @@ +__snapshots__ diff --git a/test/snapshots/test/fixtures/soft/basic.test.ts b/test/snapshots/test/fixtures/soft/basic.test.ts new file mode 100644 index 000000000000..3ddc4c68db40 --- /dev/null +++ b/test/snapshots/test/fixtures/soft/basic.test.ts @@ -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() +}) diff --git a/test/snapshots/test/soft-inline.test.ts b/test/snapshots/test/soft-inline.test.ts new file mode 100644 index 000000000000..a1050b9c9279 --- /dev/null +++ b/test/snapshots/test/soft-inline.test.ts @@ -0,0 +1,89 @@ +import { readFileSync } from 'node:fs' +import { join } from 'node:path' +import { expect, test } from 'vitest' +import { editFile, runVitest } from '../../test-utils' + +test('soft inline', async () => { + const root = join(import.meta.dirname, 'fixtures/soft-inline') + const testFile = join(root, 'basic.test.ts') + + // remove inline snapshots + editFile(testFile, s => s + .replace(/toMatchInlineSnapshot\(`[^`]*`\)/g, 'toMatchInlineSnapshot()') + .replace(/toThrowErrorMatchingInlineSnapshot\(`[^`]*`\)/g, 'toThrowErrorMatchingInlineSnapshot()')) + + // create snapshots from scratch + let result = await runVitest({ root, update: 'new' }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` + "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--]\`) + }) + " + `) + expect(result.errorTree()).toMatchInlineSnapshot(` + Object { + "basic.test.ts": Object { + "toMatchInlineSnapshot": "passed", + "toThrowErrorMatchingInlineSnapshot": "passed", + }, + } + `) + + // edit tests to introduce snapshot errors + editFile(testFile, s => s + .replace('expect.soft(\'--snap-1--\')', 'expect.soft(\'--snap-1-edit--\')') + .replace('expect.soft(\'--snap-2--\')', 'expect.soft(\'--snap-2-edit--\')') + .replace('new Error(\'--error-1--\')', 'new Error(\'--error-1-edit--\')') + .replace('new Error(\'--error-2--\')', 'new Error(\'--error-2-edit--\')')) + + result = await runVitest({ root, update: false }) + expect(result.errorTree()).toMatchInlineSnapshot(` + Object { + "basic.test.ts": Object { + "toMatchInlineSnapshot": Array [ + "Snapshot \`toMatchInlineSnapshot 1\` mismatched", + "Snapshot \`toMatchInlineSnapshot 2\` mismatched", + ], + "toThrowErrorMatchingInlineSnapshot": Array [ + "Snapshot \`toThrowErrorMatchingInlineSnapshot 1\` mismatched", + "Snapshot \`toThrowErrorMatchingInlineSnapshot 2\` mismatched", + ], + }, + } + `) + + // run with update + result = await runVitest({ root, update: 'all' }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` + "import { expect, test } from 'vitest' + + test('toMatchInlineSnapshot', () => { + expect.soft('--snap-1-edit--').toMatchInlineSnapshot(\`"--snap-1-edit--"\`) + expect.soft('--snap-2-edit--').toMatchInlineSnapshot(\`"--snap-2-edit--"\`) + }) + + test('toThrowErrorMatchingInlineSnapshot', () => { + expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-1-edit--]\`) + expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-2-edit--]\`) + }) + " + `) + expect(result.errorTree()).toMatchInlineSnapshot(` + Object { + "basic.test.ts": Object { + "toMatchInlineSnapshot": "passed", + "toThrowErrorMatchingInlineSnapshot": "passed", + }, + } + `) +}) diff --git a/test/snapshots/test/soft.test.ts b/test/snapshots/test/soft.test.ts new file mode 100644 index 000000000000..8692ab4fad3a --- /dev/null +++ b/test/snapshots/test/soft.test.ts @@ -0,0 +1,200 @@ +import fs, { readFileSync } from 'node:fs' +import { join } from 'node:path' +import { expect, test } from 'vitest' +import { editFile, runVitest } from '../../test-utils' + +test('soft', async () => { + const root = join(import.meta.dirname, 'fixtures/soft') + const testFile = join(root, 'basic.test.ts') + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') + const customFile1 = join(root, '__snapshots__/custom1.txt') + const customFile2 = join(root, '__snapshots__/custom2.txt') + + // remove snapshots + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) + + // create snapshots from scratch + let result = await runVitest({ root, update: 'new' }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + + exports[\`toMatchSnapshot 1\`] = \`"--snap-1--"\`; + + exports[\`toMatchSnapshot 2\`] = \`"--snap-2--"\`; + + exports[\`toThrowErrorMatchingSnapshot 1\`] = \`[Error: --error-1--]\`; + + exports[\`toThrowErrorMatchingSnapshot 2\`] = \`[Error: --error-2--]\`; + " + `) + expect(readFileSync(customFile1, 'utf-8')).toMatchInlineSnapshot(`"--file-1--"`) + expect(readFileSync(customFile2, 'utf-8')).toMatchInlineSnapshot(`"--file-2--"`) + expect(result.errorTree()).toMatchInlineSnapshot(` + Object { + "basic.test.ts": Object { + "toMatchFileSnapshot": "passed", + "toMatchSnapshot": "passed", + "toThrowErrorMatchingSnapshot": "passed", + }, + } + `) + + // edit tests to introduce snapshot errors + editFile(testFile, s => s + .replace(`--snap-1--`, `--snap-1-edit--`) + .replace(`--snap-2--`, `--snap-2-edit--`) + .replace(`--file-1--`, `--file-1-edit--`) + .replace(`--file-2--`, `--file-2-edit--`) + .replace(`--error-1--`, `--error-1-edit--`) + .replace(`--error-2--`, `--error-2-edit--`)) + + result = await runVitest({ root, update: false }) + expect(result.stderr).toMatchInlineSnapshot(` + " + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ + + FAIL basic.test.ts > toMatchSnapshot + Error: Snapshot \`toMatchSnapshot 1\` mismatched + + Expected: ""--snap-1--"" + Received: ""--snap-1-edit--"" + + ❯ basic.test.ts:4:34 + 2| + 3| test('toMatchSnapshot', () => { + 4| expect.soft('--snap-1-edit--').toMatchSnapshot() + | ^ + 5| expect.soft('--snap-2-edit--').toMatchSnapshot() + 6| }) + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ + + FAIL basic.test.ts > toMatchSnapshot + Error: Snapshot \`toMatchSnapshot 2\` mismatched + + Expected: ""--snap-2--"" + Received: ""--snap-2-edit--"" + + ❯ basic.test.ts:5:34 + 3| test('toMatchSnapshot', () => { + 4| expect.soft('--snap-1-edit--').toMatchSnapshot() + 5| expect.soft('--snap-2-edit--').toMatchSnapshot() + | ^ + 6| }) + 7| + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ + + FAIL basic.test.ts > toMatchFileSnapshot + Error: Snapshot \`toMatchFileSnapshot 1\` mismatched + + Expected: "--file-1--" + Received: "--file-1-edit--" + + ❯ basic.test.ts:9:3 + 7| + 8| test('toMatchFileSnapshot', async () => { + 9| await expect.soft('--file-1-edit--').toMatchFileSnapshot('./__snapsh… + | ^ + 10| await expect.soft('--file-2-edit--').toMatchFileSnapshot('./__snapsh… + 11| }) + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ + + FAIL basic.test.ts > toMatchFileSnapshot + Error: Snapshot \`toMatchFileSnapshot 2\` mismatched + + Expected: "--file-2--" + Received: "--file-2-edit--" + + ❯ basic.test.ts:10:3 + 8| test('toMatchFileSnapshot', async () => { + 9| await expect.soft('--file-1-edit--').toMatchFileSnapshot('./__snapsh… + 10| await expect.soft('--file-2-edit--').toMatchFileSnapshot('./__snapsh… + | ^ + 11| }) + 12| + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ + + FAIL basic.test.ts > toThrowErrorMatchingSnapshot + Error: Snapshot \`toThrowErrorMatchingSnapshot 1\` mismatched + + Expected: "[Error: --error-1--]" + Received: "[Error: --error-1-edit--]" + + ❯ basic.test.ts:14:62 + 12| + 13| test('toThrowErrorMatchingSnapshot', () => { + 14| expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowEr… + | ^ + 15| expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowEr… + 16| }) + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ + + FAIL basic.test.ts > toThrowErrorMatchingSnapshot + Error: Snapshot \`toThrowErrorMatchingSnapshot 2\` mismatched + + Expected: "[Error: --error-2--]" + Received: "[Error: --error-2-edit--]" + + ❯ basic.test.ts:15:62 + 13| test('toThrowErrorMatchingSnapshot', () => { + 14| expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowEr… + 15| expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowEr… + | ^ + 16| }) + 17| + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯ + + " + `) + expect(result.errorTree()).toMatchInlineSnapshot(` + Object { + "basic.test.ts": Object { + "toMatchFileSnapshot": Array [ + "Snapshot \`toMatchFileSnapshot 1\` mismatched", + "Snapshot \`toMatchFileSnapshot 2\` mismatched", + ], + "toMatchSnapshot": Array [ + "Snapshot \`toMatchSnapshot 1\` mismatched", + "Snapshot \`toMatchSnapshot 2\` mismatched", + ], + "toThrowErrorMatchingSnapshot": Array [ + "Snapshot \`toThrowErrorMatchingSnapshot 1\` mismatched", + "Snapshot \`toThrowErrorMatchingSnapshot 2\` mismatched", + ], + }, + } + `) + + // run with update + result = await runVitest({ root, update: 'all' }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + + exports[\`toMatchSnapshot 1\`] = \`"--snap-1-edit--"\`; + + exports[\`toMatchSnapshot 2\`] = \`"--snap-2-edit--"\`; + + exports[\`toThrowErrorMatchingSnapshot 1\`] = \`[Error: --error-1-edit--]\`; + + exports[\`toThrowErrorMatchingSnapshot 2\`] = \`[Error: --error-2-edit--]\`; + " + `) + expect(readFileSync(customFile1, 'utf-8')).toMatchInlineSnapshot(`"--file-1-edit--"`) + expect(readFileSync(customFile2, 'utf-8')).toMatchInlineSnapshot(`"--file-2-edit--"`) + expect(result.errorTree()).toMatchInlineSnapshot(` + Object { + "basic.test.ts": Object { + "toMatchFileSnapshot": "passed", + "toMatchSnapshot": "passed", + "toThrowErrorMatchingSnapshot": "passed", + }, + } + `) +}) diff --git a/test/snapshots/tools/generate-inline-test.mjs b/test/snapshots/tools/generate-inline-test.mjs deleted file mode 100644 index 3e775e092a71..000000000000 --- a/test/snapshots/tools/generate-inline-test.mjs +++ /dev/null @@ -1,22 +0,0 @@ -import fs from 'node:fs/promises' -import { fileURLToPath } from 'node:url' -import { dirname, resolve } from 'pathe' - -const dir = dirname(fileURLToPath(import.meta.url)) - -export async function generateInlineTest(templatePath, testPath) { - const template = await fs.readFile(templatePath, 'utf8') - await fs.writeFile(testPath, template) - console.warn(`Generated ${testPath}`) -} - -const filepath = resolve(dir, '../test-update/snapshots-inline-js.test.js') -const template = resolve(dir, './inline-test-template.js'); - -(async () => { - await generateInlineTest(template, filepath) - await generateInlineTest( - resolve(dir, './inline-test-template-concurrent.js'), - resolve(dir, '../test-update/inline-test-template-concurrent.test.js'), - ) -})()