import fs, { readFileSync } from 'node:fs' import { join } from 'node:path' import { expect, test } from 'vitest' import { editFile, runVitest } from '../../test-utils' test('domain snapshot', async () => { const root = join(import.meta.dirname, 'fixtures/domain') const testFile = join(root, 'basic.test.ts') const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') // clean slate fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) // create snapshots from scratch — literal rendered values let result = await runVitest({ root, update: 'new' }) expect(result.stderr).toMatchInlineSnapshot(`""`) expect(result.errorTree()).toMatchInlineSnapshot(` { "basic.test.ts": { "all literal": "passed", "empty snapshot": "passed", "with regex": "passed", }, } `) expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[\`all literal 1\`] = \` name=alice age=30 \`; exports[\`empty snapshot 1\`] = \`\`; exports[\`with regex 1\`] = \` name=bob age=24 score=999 status=active \`; " `) // hand-edit snapshot editFile(snapshotFile, s => s // match any numbers match for score .replace('score=999', 'score=/\\\\d+/') .replace('age=24\n', '')) // re-run without update result = await runVitest({ root, update: 'none' }) expect(result.stderr).toMatchInlineSnapshot(`""`) expect(result.errorTree()).toMatchInlineSnapshot(` { "basic.test.ts": { "all literal": "passed", "empty snapshot": "passed", "with regex": "passed", }, } `) expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[\`all literal 1\`] = \` name=alice age=30 \`; exports[\`empty snapshot 1\`] = \`\`; exports[\`with regex 1\`] = \` name=bob score=/\\\\d+/ status=active \`; " `) // edit test editFile(testFile, s => s .replace(`name: 'alice',`, ``) .replace(`score: '999'`, `score: '42'`) .replace(`status: 'active'`, `status: 'inactive'`)) // run without update // (note that `age` and `score` is not in diff) result = await runVitest({ root, update: 'none' }) expect(result.stderr).toMatchInlineSnapshot(` " ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ FAIL basic.test.ts > all literal Error: Snapshot \`all literal 1\` mismatched - Expected + Received - name=alice age=30 ❯ basic.test.ts:5:26 3| 4| test('all literal', () => { 5| expect({ age: '30' }).toMatchKvSnapshot() | ^ 6| }) 7| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ FAIL basic.test.ts > with regex Error: Snapshot \`with regex 1\` mismatched - Expected + Received name=bob score=/\\d+/ - status=active + status=inactive ❯ basic.test.ts:9:71 7| 8| test('with regex', () => { 9| expect({ name: 'bob', age: '24', score: '42', status: 'inactive' }).… | ^ 10| }) 11| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ " `) expect(result.errorTree()).toMatchInlineSnapshot(` { "basic.test.ts": { "all literal": [ "Snapshot \`all literal 1\` mismatched", ], "empty snapshot": "passed", "with regex": [ "Snapshot \`with regex 1\` mismatched", ], }, } `) // run with update — should preserve score regex (matched), // overwrite status with literal (didn't match) result = await runVitest({ root, update: 'all' }) expect(result.stderr).toMatchInlineSnapshot(`""`) expect(result.errorTree()).toMatchInlineSnapshot(` { "basic.test.ts": { "all literal": "passed", "empty snapshot": "passed", "with regex": "passed", }, } `) // NOTE // score regex matched '42' -> preserved as /\d+/ // status literal 'active' != 'inactive' -> overwritten with literal expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[\`all literal 1\`] = \` age=30 \`; exports[\`empty snapshot 1\`] = \`\`; exports[\`with regex 1\`] = \` name=bob score=/\\\\d+/ status=inactive \`; " `) }) test('domain parseExpected error', async () => { const root = join(import.meta.dirname, 'fixtures/domain-error') const result = await runVitest({ root, update: 'none' }) expect(result.stderr).toMatchInlineSnapshot(` " ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ FAIL basic.test.ts > file Error: Invalid KV Format: 'file-broken' ❯ ../domain/basic.ts:38:15 36| const eq = line.indexOf('=') 37| if (eq === -1) { 38| throw new Error(\`Invalid KV Format: '\${line}'\`) | ^ 39| } 40| const key = line.slice(0, eq) ❯ Object.parseExpected ../domain/basic.ts:35:46 ❯ Object.toMatchKvSnapshot ../domain/basic-extend.ts:16:44 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ FAIL basic.test.ts > inline Error: Invalid KV Format: 'inine-broken' ❯ ../domain/basic.ts:38:15 36| const eq = line.indexOf('=') 37| if (eq === -1) { 38| throw new Error(\`Invalid KV Format: '\${line}'\`) | ^ 39| } 40| const key = line.slice(0, eq) ❯ Object.parseExpected ../domain/basic.ts:35:46 ❯ Object.toMatchKvInlineSnapshot ../domain/basic-extend.ts:22:50 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ " `) expect(result.errorTree()).toMatchInlineSnapshot(` { "basic.test.ts": { "file": [ "Invalid KV Format: 'file-broken'", ], "inline": [ "Invalid KV Format: 'inine-broken'", ], }, } `) })