[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

test: move `test/snapshots` to `test/e2e` (#10241)

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

authored by

Hiroshi Ogawa
Copilot Autofix powered by AI
and committed by
GitHub
(May 11, 2026, 5:46 PM +0200) 7dcf3b2d 053e8b0d

+6301 -6287
+3 -13
pnpm-lock.yaml
··· 1433 1433 flatted: 1434 1434 specifier: 'catalog:' 1435 1435 version: 3.4.2 1436 + jest-image-snapshot: 1437 + specifier: ^6.5.1 1438 + version: 6.5.1 1436 1439 obug: 1437 1440 specifier: ^2.1.1 1438 1441 version: 2.1.1 ··· 1516 1519 version: link:../../../../packages/vitest 1517 1520 1518 1521 test/node-runner: {} 1519 - 1520 - test/snapshots: 1521 - dependencies: 1522 - vitest: 1523 - specifier: workspace:* 1524 - version: link:../../packages/vitest 1525 - devDependencies: 1526 - '@vitest/browser-playwright': 1527 - specifier: workspace:* 1528 - version: link:../../packages/browser-playwright 1529 - jest-image-snapshot: 1530 - specifier: ^6.5.1 1531 - version: 6.5.1 1532 1522 1533 1523 test/test-utils: 1534 1524 devDependencies:
+13
test/e2e/README.md
··· 1 + # e2e 2 + 3 + ## Snapshots 4 + 5 + This directory [`./snapshots`](./snapshots) 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, such as, snapshot update, snapshot error formatting, summary reporting, obsolete snapshots handling, etc. 6 + 7 + ```bash 8 + # Run all integration tests 9 + pnpm -C test/e2e test --project=snapshots 10 + 11 + # Run individual fixture directly 12 + pnpm -C test/e2e test --root snapshots/fixtures/domain 13 + ```
+1
test/e2e/package.json
··· 27 27 "@vitest/runner": "workspace:*", 28 28 "@vitest/utils": "workspace:*", 29 29 "flatted": "catalog:", 30 + "jest-image-snapshot": "^6.5.1", 30 31 "obug": "^2.1.1", 31 32 "playwright": "catalog:", 32 33 "test-dep-invalid": "link:./deps/dep-invalid",
+45 -20
test/e2e/vitest.config.ts
··· 1 + import path from 'node:path' 1 2 import { defineConfig } from 'vite' 3 + import { defaultExclude } from 'vitest/config' 2 4 3 5 export default defineConfig({ 4 6 test: { 5 - include: ['test/**/**.{test,spec}.ts'], 6 - includeTaskLocation: true, 7 7 reporters: [ 8 8 'verbose', 9 - ...(process.env.VITEST_CI_BLOB_LABEL 10 - ? [['blob', { label: process.env.VITEST_CI_BLOB_LABEL }] as any] 11 - : []), 9 + (process.env.VITEST_CI_BLOB_LABEL 10 + ? ['blob', { label: process.env.VITEST_CI_BLOB_LABEL }] 11 + : {}), 12 12 ], 13 - testTimeout: 60_000, 14 - isolate: false, 15 - fileParallelism: false, 16 - // TODO: should enabled when support for older node is dropped? 17 - // experimental: { 18 - // viteModuleRunner: false, 19 - // nodeLoader: false, 20 - // }, 21 - chaiConfig: { 22 - truncateThreshold: 999, 23 - }, 24 - typecheck: { 25 - enabled: true, 26 - include: ['./test/reporters/configuration-options.test-d.ts'], 27 - }, 28 13 onConsoleLog(log) { 29 14 if (log.includes('watcher is ready')) { 30 15 return false 31 16 } 32 17 }, 18 + projects: [ 19 + { 20 + extends: true, 21 + test: { 22 + name: 'main', 23 + include: ['test/**/**.{test,spec}.ts'], 24 + includeTaskLocation: true, 25 + testTimeout: 60_000, 26 + isolate: false, 27 + fileParallelism: false, 28 + // TODO: should enabled when support for older node is dropped? 29 + // experimental: { 30 + // viteModuleRunner: false, 31 + // nodeLoader: false, 32 + // }, 33 + chaiConfig: { 34 + truncateThreshold: 999, 35 + }, 36 + typecheck: { 37 + enabled: true, 38 + include: ['./test/reporters/configuration-options.test-d.ts'], 39 + }, 40 + sequence: { 41 + groupOrder: 0, 42 + }, 43 + }, 44 + }, 45 + { 46 + extends: true, 47 + test: { 48 + name: 'snapshots', 49 + root: path.join(import.meta.dirname, 'snapshots'), 50 + exclude: ['**/fixtures/**', ...defaultExclude], 51 + testTimeout: process.env.CI ? 20_000 : undefined, 52 + sequence: { 53 + groupOrder: 1, 54 + }, 55 + }, 56 + }, 57 + ], 33 58 }, 34 59 server: { 35 60 watch: {
-11
test/snapshots/README.md
··· 1 - # Snapshot Tests 2 - 3 - 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, such as, snapshot update, snapshot error formatting, summary reporting, obsolete snapshots handling, etc. 4 - 5 - ```bash 6 - # Run all integration tests 7 - pnpm test 8 - 9 - # Run one fixture directly 10 - pnpm test --root test/fixtures/summary 11 - ```
-15
test/snapshots/package.json
··· 1 - { 2 - "name": "@vitest/test-snapshots", 3 - "type": "module", 4 - "private": true, 5 - "scripts": { 6 - "test": "vitest" 7 - }, 8 - "dependencies": { 9 - "vitest": "workspace:*" 10 - }, 11 - "devDependencies": { 12 - "@vitest/browser-playwright": "workspace:*", 13 - "jest-image-snapshot": "^6.5.1" 14 - } 15 - }
-12
test/snapshots/vitest.config.ts
··· 1 - import { defineConfig } from 'vite' 2 - import { defaultExclude } from 'vitest/config' 3 - 4 - export default defineConfig({ 5 - test: { 6 - exclude: [...defaultExclude, '**/fixtures', '**/vitest-test-*/**'], 7 - snapshotFormat: { 8 - printBasicPrototype: true, 9 - }, 10 - testTimeout: process.env.CI ? 60_000 : 5_000, 11 - }, 12 - })
+54
test/e2e/snapshots/ci.test.ts
··· 1 + import fs from 'node:fs' 2 + import path from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { runVitestCli } from '../../test-utils' 5 + 6 + test('CI behavior', async () => { 7 + // cleanup snapshot 8 + const root = path.join(import.meta.dirname, 'fixtures/ci') 9 + fs.rmSync(path.join(root, '__snapshots__'), { recursive: true, force: true }) 10 + 11 + // snapshot fails with CI 12 + let result = await runVitestCli({ 13 + nodeOptions: { 14 + env: { 15 + CI: 'true', 16 + GITHUB_ACTIONS: 'true', 17 + }, 18 + }, 19 + }, '--root', root) 20 + expect(result.stderr).toMatchInlineSnapshot(` 21 + " 22 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 23 + 24 + FAIL basic.test.ts > basic 25 + Error: Snapshot \`basic 1\` mismatched 26 + ❯ basic.test.ts:4:16 27 + 2| 28 + 3| test("basic", () => { 29 + 4| expect("ok").toMatchSnapshot() 30 + | ^ 31 + 5| }) 32 + 6| 33 + 34 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 35 + 36 + " 37 + `) 38 + 39 + // snapshot created without CI 40 + result = await runVitestCli( 41 + { 42 + nodeOptions: { 43 + env: { 44 + CI: '', 45 + GITHUB_ACTIONS: '', 46 + }, 47 + }, 48 + }, 49 + '--root', 50 + root, 51 + ) 52 + expect(result.stderr).toMatchInlineSnapshot(`""`) 53 + expect(result.stdout).toContain('Snapshots 1 written') 54 + })
+85
test/e2e/snapshots/compare-keys.test.ts
··· 1 + import fs from 'node:fs' 2 + import { join } from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { runVitest } from '../../test-utils' 5 + 6 + test('compareKeys', async () => { 7 + const root = join(import.meta.dirname, 'fixtures/compare-keys') 8 + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 9 + 10 + // compareKeys null 11 + let vitest = await runVitest({ 12 + root, 13 + update: true, 14 + snapshotFormat: { 15 + compareKeys: null, 16 + }, 17 + }) 18 + expect(vitest.stderr).toBe('') 19 + expect(fs.readFileSync(join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 20 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 21 + 22 + exports[\`compareKeys 1\`] = \` 23 + { 24 + "a": 1, 25 + "b": 2, 26 + "c": 3, 27 + } 28 + \`; 29 + 30 + exports[\`compareKeys 2\`] = \` 31 + { 32 + "c": 1, 33 + "b": 2, 34 + "a": 3, 35 + } 36 + \`; 37 + 38 + exports[\`compareKeys 3\`] = \` 39 + { 40 + "b": 1, 41 + "a": 2, 42 + "c": 3, 43 + } 44 + \`; 45 + " 46 + `) 47 + 48 + // compareKeys undefined 49 + vitest = await runVitest({ 50 + root, 51 + update: true, 52 + snapshotFormat: { 53 + compareKeys: undefined, 54 + }, 55 + }) 56 + expect(vitest.stderr).toBe('') 57 + expect(fs.readFileSync(join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 58 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 59 + 60 + exports[\`compareKeys 1\`] = \` 61 + { 62 + "a": 1, 63 + "b": 2, 64 + "c": 3, 65 + } 66 + \`; 67 + 68 + exports[\`compareKeys 2\`] = \` 69 + { 70 + "a": 3, 71 + "b": 2, 72 + "c": 1, 73 + } 74 + \`; 75 + 76 + exports[\`compareKeys 3\`] = \` 77 + { 78 + "a": 2, 79 + "b": 1, 80 + "c": 3, 81 + } 82 + \`; 83 + " 84 + `) 85 + })
+33
test/e2e/snapshots/custom-environment.test.ts
··· 1 + import { readFileSync, rmSync, writeFileSync } from 'node:fs' 2 + import { dirname, resolve } from 'pathe' 3 + import { afterEach, expect, test } from 'vitest' 4 + import { runVitest } from '../../test-utils' 5 + 6 + const testFileName = resolve(import.meta.dirname, './fixtures/custom-snapshot-environment/test/snapshots.test.ts') 7 + const snapshotFile = resolve(dirname(testFileName), './__snapshots__/snapshots.test.ts.snap') 8 + const testFile = readFileSync(testFileName, 'utf-8') 9 + 10 + afterEach(() => { 11 + writeFileSync(testFileName, testFile) 12 + rmSync(snapshotFile) 13 + }) 14 + 15 + test('custom environment resolved correctly', async () => { 16 + const { stdout, stderr } = await runVitest({ 17 + root: resolve(import.meta.dirname, './fixtures/custom-snapshot-environment'), 18 + update: true, 19 + }) 20 + 21 + const snapshotLogs = stdout.split('\n').filter(i => i.startsWith('## ')).join('\n') 22 + expect(stderr).toBe('') 23 + expect(snapshotLogs).toMatchInlineSnapshot(` 24 + "## resolvePath snapshots/fixtures/custom-snapshot-environment/test/snapshots.test.ts 25 + ## readSnapshotFile snapshots/fixtures/custom-snapshot-environment/test/__snapshots__/snapshots.test.ts.snap 26 + ## getHeader 27 + ## getVersion 28 + ## readSnapshotFile snapshots/fixtures/custom-snapshot-environment/test/__snapshots__/snapshots.test.ts.snap 29 + ## saveSnapshotFile snapshots/fixtures/custom-snapshot-environment/test/__snapshots__/snapshots.test.ts.snap 30 + ## readSnapshotFile snapshots/fixtures/custom-snapshot-environment/test/snapshots.test.ts 31 + ## saveSnapshotFile snapshots/fixtures/custom-snapshot-environment/test/snapshots.test.ts" 32 + `) 33 + })
+556
test/e2e/snapshots/custom-matcher.test.ts
··· 1 + import fs, { readFileSync } from 'node:fs' 2 + import { join } from 'node:path' 3 + import { playwright } from '@vitest/browser-playwright' 4 + import { expect, test } from 'vitest' 5 + import { editFile, runInlineTests, runVitest } from '../../test-utils' 6 + import { extractInlineSnaphsots } from './utils' 7 + 8 + test('custom snapshot matcher', async () => { 9 + const root = join(import.meta.dirname, 'fixtures/custom-matcher') 10 + const testFile = join(root, 'basic.test.ts') 11 + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 12 + const rawSnapshotFile = join(root, '__snapshots__/raw.txt') 13 + 14 + // remove snapshots 15 + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 16 + editFile(testFile, s => s.replace(/(toMatchCustom(?:Async)?InlineSnapshot)\(`[^`]*`\)/g, '$1()')) 17 + 18 + // create snapshots from scratch 19 + let result = await runVitest({ root, update: 'new' }) 20 + expect(result.stderr).toMatchInlineSnapshot(`""`) 21 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 22 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 23 + 24 + exports[\`file 1\`] = \` 25 + { 26 + "length": 6, 27 + "reversed": "ahahah", 28 + } 29 + \`; 30 + 31 + exports[\`properties 1 1\`] = \` 32 + { 33 + "length": 6, 34 + "reversed": "opopop", 35 + } 36 + \`; 37 + 38 + exports[\`properties 2 1\`] = \` 39 + { 40 + "length": toSatisfy<[Function lessThan10]>, 41 + "reversed": "epepep", 42 + } 43 + \`; 44 + " 45 + `) 46 + expect(readFileSync(rawSnapshotFile, 'utf-8')).toMatchInlineSnapshot(` 47 + "{ 48 + "length": 6, 49 + "reversed": "ihihih", 50 + }" 51 + `) 52 + expect(extractInlineSnaphsots(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 53 + " 54 + expect(\`hehehe\`).toMatchCustomInlineSnapshot(\` 55 + { 56 + "length": 6, 57 + "reversed": "eheheh", 58 + } 59 + \`) 60 + 61 + expect(\`huhuhu\`).toMatchCustomAsyncInlineSnapshot(\` 62 + { 63 + "length": 6, 64 + "reversed": "uhuhuh", 65 + } 66 + \`) 67 + " 68 + `) 69 + expect(result.errorTree()).toMatchInlineSnapshot(` 70 + { 71 + "basic.test.ts": { 72 + "async inline": "passed", 73 + "file": "passed", 74 + "inline": "passed", 75 + "properties 1": "passed", 76 + "properties 2": "passed", 77 + "raw": "passed", 78 + }, 79 + } 80 + `) 81 + 82 + // edit tests to introduce snapshot errors 83 + editFile(testFile, s => s 84 + .replace('`hahaha`', '`hahaha-edit`') 85 + .replace('`popopo`', '`popopo-edit`') 86 + .replace('`pepepe`', '`pepepe-edit`') 87 + .replace('`hihihi`', '`hihihi-edit`') 88 + .replace('`huhuhu`', '`huhuhu-edit`') 89 + .replace('`hehehe`', '`hehehe-edit`')) 90 + 91 + result = await runVitest({ root, update: 'none' }) 92 + expect(result.stderr).toMatchInlineSnapshot(` 93 + " 94 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯ 95 + 96 + FAIL basic.test.ts > file 97 + Error: [custom error] Snapshot \`file 1\` mismatched 98 + 99 + - Expected 100 + + Received 101 + 102 + { 103 + - "length": 6, 104 + + "length": 11, 105 + - "reversed": "ahahah", 106 + + "reversed": "tide-ahahah", 107 + } 108 + 109 + ❯ basic.test.ts:66:25 110 + 64| 111 + 65| test('file', () => { 112 + 66| expect(\`hahaha-edit\`).toMatchCustomSnapshot() 113 + | ^ 114 + 67| }) 115 + 68| 116 + 117 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ 118 + 119 + FAIL basic.test.ts > properties 1 120 + Error: [custom error] Snapshot properties mismatched 121 + 122 + - Expected 123 + + Received 124 + 125 + { 126 + - "length": 6, 127 + + "length": 11, 128 + + "reversed": "tide-opopop", 129 + } 130 + 131 + ❯ basic.test.ts:70:25 132 + 68| 133 + 69| test('properties 1', () => { 134 + 70| expect(\`popopo-edit\`).toMatchCustomSnapshot({ length: 6 }) 135 + | ^ 136 + 71| }) 137 + 72| 138 + 139 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ 140 + 141 + FAIL basic.test.ts > properties 2 142 + Error: [custom error] Snapshot properties mismatched 143 + 144 + - Expected 145 + + Received 146 + 147 + { 148 + - "length": toSatisfy<[Function lessThan10]>, 149 + + "length": 11, 150 + + "reversed": "tide-epepep", 151 + } 152 + 153 + ❯ basic.test.ts:74:25 154 + 72| 155 + 73| test('properties 2', () => { 156 + 74| expect(\`pepepe-edit\`).toMatchCustomSnapshot({ length: expect.toSatis… 157 + | ^ 158 + 75| }) 159 + 76| 160 + 161 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ 162 + 163 + FAIL basic.test.ts > raw 164 + Error: [custom error] Snapshot \`raw 1\` mismatched 165 + 166 + - Expected 167 + + Received 168 + 169 + { 170 + - "length": 6, 171 + + "length": 11, 172 + - "reversed": "ihihih", 173 + + "reversed": "tide-ihihih", 174 + } 175 + 176 + ❯ basic.test.ts:78:3 177 + 76| 178 + 77| test('raw', async () => { 179 + 78| await expect(\`hihihi-edit\`).toMatchCustomFileSnapshot('./__snapshots… 180 + | ^ 181 + 79| }) 182 + 80| 183 + 184 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ 185 + 186 + FAIL basic.test.ts > inline 187 + Error: [custom error] Snapshot \`inline 1\` mismatched 188 + 189 + - Expected 190 + + Received 191 + 192 + { 193 + - "length": 6, 194 + + "length": 11, 195 + - "reversed": "eheheh", 196 + + "reversed": "tide-eheheh", 197 + } 198 + 199 + ❯ basic.test.ts:82:25 200 + 80| 201 + 81| test('inline', () => { 202 + 82| expect(\`hehehe-edit\`).toMatchCustomInlineSnapshot(\` 203 + | ^ 204 + 83| { 205 + 84| "length": 6, 206 + 207 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ 208 + 209 + FAIL basic.test.ts > async inline 210 + Error: [custom error] Snapshot \`async inline 1\` mismatched 211 + 212 + - Expected 213 + + Received 214 + 215 + { 216 + - "length": 6, 217 + + "length": 11, 218 + - "reversed": "uhuhuh", 219 + + "reversed": "tide-uhuhuh", 220 + } 221 + 222 + ❯ basic.test.ts:91:3 223 + 89| 224 + 90| test('async inline', async () => { 225 + 91| await expect(\`huhuhu-edit\`).toMatchCustomAsyncInlineSnapshot(\` 226 + | ^ 227 + 92| { 228 + 93| "length": 6, 229 + 230 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯ 231 + 232 + " 233 + `) 234 + expect(result.errorTree()).toMatchInlineSnapshot(` 235 + { 236 + "basic.test.ts": { 237 + "async inline": [ 238 + "[custom error] Snapshot \`async inline 1\` mismatched", 239 + ], 240 + "file": [ 241 + "[custom error] Snapshot \`file 1\` mismatched", 242 + ], 243 + "inline": [ 244 + "[custom error] Snapshot \`inline 1\` mismatched", 245 + ], 246 + "properties 1": [ 247 + "[custom error] Snapshot properties mismatched", 248 + ], 249 + "properties 2": [ 250 + "[custom error] Snapshot properties mismatched", 251 + ], 252 + "raw": [ 253 + "[custom error] Snapshot \`raw 1\` mismatched", 254 + ], 255 + }, 256 + } 257 + `) 258 + 259 + // run with update 260 + result = await runVitest({ root, update: 'all' }) 261 + expect(result.stderr).toMatchInlineSnapshot(` 262 + " 263 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 264 + 265 + FAIL basic.test.ts > properties 1 266 + Error: [custom error] Snapshot properties mismatched 267 + 268 + - Expected 269 + + Received 270 + 271 + { 272 + - "length": 6, 273 + + "length": 11, 274 + + "reversed": "tide-opopop", 275 + } 276 + 277 + ❯ basic.test.ts:70:25 278 + 68| 279 + 69| test('properties 1', () => { 280 + 70| expect(\`popopo-edit\`).toMatchCustomSnapshot({ length: 6 }) 281 + | ^ 282 + 71| }) 283 + 72| 284 + 285 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 286 + 287 + FAIL basic.test.ts > properties 2 288 + Error: [custom error] Snapshot properties mismatched 289 + 290 + - Expected 291 + + Received 292 + 293 + { 294 + - "length": toSatisfy<[Function lessThan10]>, 295 + + "length": 11, 296 + + "reversed": "tide-epepep", 297 + } 298 + 299 + ❯ basic.test.ts:74:25 300 + 72| 301 + 73| test('properties 2', () => { 302 + 74| expect(\`pepepe-edit\`).toMatchCustomSnapshot({ length: expect.toSatis… 303 + | ^ 304 + 75| }) 305 + 76| 306 + 307 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 308 + 309 + " 310 + `) 311 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 312 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 313 + 314 + exports[\`file 1\`] = \` 315 + { 316 + "length": 11, 317 + "reversed": "tide-ahahah", 318 + } 319 + \`; 320 + 321 + exports[\`properties 1 1\`] = \` 322 + { 323 + "length": 6, 324 + "reversed": "opopop", 325 + } 326 + \`; 327 + 328 + exports[\`properties 2 1\`] = \` 329 + { 330 + "length": toSatisfy<[Function lessThan10]>, 331 + "reversed": "epepep", 332 + } 333 + \`; 334 + " 335 + `) 336 + expect(readFileSync(rawSnapshotFile, 'utf-8')).toMatchInlineSnapshot(` 337 + "{ 338 + "length": 11, 339 + "reversed": "tide-ihihih", 340 + }" 341 + `) 342 + expect(extractInlineSnaphsots(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 343 + " 344 + expect(\`hehehe-edit\`).toMatchCustomInlineSnapshot(\` 345 + { 346 + "length": 11, 347 + "reversed": "tide-eheheh", 348 + } 349 + \`) 350 + 351 + expect(\`huhuhu-edit\`).toMatchCustomAsyncInlineSnapshot(\` 352 + { 353 + "length": 11, 354 + "reversed": "tide-uhuhuh", 355 + } 356 + \`) 357 + " 358 + `) 359 + expect(result.errorTree()).toMatchInlineSnapshot(` 360 + { 361 + "basic.test.ts": { 362 + "async inline": "passed", 363 + "file": "passed", 364 + "inline": "passed", 365 + "properties 1": [ 366 + "[custom error] Snapshot properties mismatched", 367 + ], 368 + "properties 2": [ 369 + "[custom error] Snapshot properties mismatched", 370 + ], 371 + "raw": "passed", 372 + }, 373 + } 374 + `) 375 + }) 376 + 377 + test('browser', async () => { 378 + const result = await runInlineTests({ 379 + 'basic.test.ts': ` 380 + import { test, expect, Snapshots } from 'vitest' 381 + 382 + const { 383 + toMatchFileSnapshot, 384 + toMatchInlineSnapshot, 385 + toMatchSnapshot, 386 + } = Snapshots 387 + 388 + expect.extend({ 389 + toMatchTrimmedSnapshot(received: string) { 390 + return toMatchSnapshot.call(this, received.slice(0, 10)) 391 + }, 392 + toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) { 393 + return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot) 394 + }, 395 + async toMatchTrimmedFileSnapshot(received: string, filepath: string) { 396 + return toMatchFileSnapshot.call(this, received.slice(0, 10), filepath) 397 + }, 398 + }) 399 + 400 + test('file snapshot', () => { 401 + expect('extra long string oh my gerd').toMatchTrimmedSnapshot() 402 + }) 403 + 404 + test('inline snapshot', () => { 405 + expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot() 406 + }) 407 + 408 + test('raw file snapshot', async () => { 409 + await expect('crazy long string oh my gerd').toMatchTrimmedFileSnapshot('./raw.txt') 410 + }) 411 + `, 412 + }, { 413 + update: 'all', 414 + browser: { 415 + enabled: true, 416 + headless: true, 417 + screenshotFailures: false, 418 + provider: playwright(), 419 + instances: [ 420 + { 421 + browser: 'chromium', 422 + }, 423 + ], 424 + }, 425 + }) 426 + expect(result.stderr).toMatchInlineSnapshot(`""`) 427 + expect(result.errorTree()).toMatchInlineSnapshot(` 428 + { 429 + "basic.test.ts": { 430 + "file snapshot": "passed", 431 + "inline snapshot": "passed", 432 + "raw file snapshot": "passed", 433 + }, 434 + } 435 + `) 436 + expect(result.fs.readFile('__snapshots__/basic.test.ts.snap')).toMatchInlineSnapshot(` 437 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 438 + 439 + exports[\`file snapshot 1\`] = \`"extra long"\`; 440 + " 441 + `) 442 + expect(extractInlineSnaphsots(result.fs.readFile('basic.test.ts'))).toMatchInlineSnapshot(` 443 + " 444 + expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot(\`"super long"\`) 445 + " 446 + `) 447 + expect(result.fs.readFile('raw.txt')).toMatchInlineSnapshot(`"crazy long"`) 448 + }) 449 + 450 + test('outer expect message is prefixed by jest-extend for Snapshots wrappers', async () => { 451 + const result = await runInlineTests({ 452 + 'basic.test.ts': ` 453 + import { test, expect, Snapshots } from 'vitest' 454 + 455 + const { 456 + toMatchInlineSnapshot, 457 + } = Snapshots 458 + 459 + expect.extend({ 460 + toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) { 461 + return toMatchInlineSnapshot.call(this, received.slice(0, 5), inlineSnapshot) 462 + }, 463 + }) 464 + 465 + test('custom snapshot matcher', () => { 466 + expect('abcdefghij', 'outer message').toMatchTrimmedInlineSnapshot(\`"wrong"\`) 467 + }) 468 + 469 + test('builtin', () => { 470 + expect('abcdefghij', 'outer message').toMatchInlineSnapshot(\`"wrong"\`) 471 + }) 472 + 473 + test('builtin properties mismatch', () => { 474 + expect({ value: 1 }, 'outer message').toMatchSnapshot({ 475 + value: expect.any(String), 476 + }) 477 + }) 478 + `, 479 + }, { 480 + update: 'none', 481 + }) 482 + expect(result.stderr).toMatchInlineSnapshot(` 483 + " 484 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 485 + 486 + FAIL basic.test.ts > custom snapshot matcher 487 + Error: outer message: Snapshot \`custom snapshot matcher 1\` mismatched 488 + 489 + Expected: ""wrong"" 490 + Received: ""abcde"" 491 + 492 + ❯ basic.test.ts:15:41 493 + 13| 494 + 14| test('custom snapshot matcher', () => { 495 + 15| expect('abcdefghij', 'outer message').toMatchTrimmedInlineSnapshot(\`… 496 + | ^ 497 + 16| }) 498 + 17| 499 + 500 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 501 + 502 + FAIL basic.test.ts > builtin 503 + Error: outer message: Snapshot \`builtin 1\` mismatched 504 + 505 + Expected: ""wrong"" 506 + Received: ""abcdefghij"" 507 + 508 + ❯ basic.test.ts:19:41 509 + 17| 510 + 18| test('builtin', () => { 511 + 19| expect('abcdefghij', 'outer message').toMatchInlineSnapshot(\`"wrong"… 512 + | ^ 513 + 20| }) 514 + 21| 515 + 516 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 517 + 518 + FAIL basic.test.ts > builtin properties mismatch 519 + Error: outer message: Snapshot properties mismatched 520 + 521 + - Expected 522 + + Received 523 + 524 + { 525 + - "value": Any<String>, 526 + + "value": 1, 527 + } 528 + 529 + ❯ basic.test.ts:23:41 530 + 21| 531 + 22| test('builtin properties mismatch', () => { 532 + 23| expect({ value: 1 }, 'outer message').toMatchSnapshot({ 533 + | ^ 534 + 24| value: expect.any(String), 535 + 25| }) 536 + 537 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 538 + 539 + " 540 + `) 541 + expect(result.errorTree()).toMatchInlineSnapshot(` 542 + { 543 + "basic.test.ts": { 544 + "builtin": [ 545 + "outer message: Snapshot \`builtin 1\` mismatched", 546 + ], 547 + "builtin properties mismatch": [ 548 + "outer message: Snapshot properties mismatched", 549 + ], 550 + "custom snapshot matcher": [ 551 + "outer message: Snapshot \`custom snapshot matcher 1\` mismatched", 552 + ], 553 + }, 554 + } 555 + `) 556 + })
+137
test/e2e/snapshots/custom-serializers.test.ts
··· 1 + import fs from 'node:fs' 2 + import path from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + import { readInlineSnapshots } from './utils' 6 + 7 + test('it should pass', async () => { 8 + const { stdout, stderr } = await runVitest({ 9 + root: path.join(import.meta.dirname, 'fixtures/custom-serializers'), 10 + }) 11 + 12 + expect(stdout).toContain('✓ custom-serializers.test.ts') 13 + expect(stderr).toBe('') 14 + }) 15 + 16 + test('empty serializer output', async () => { 17 + const root = path.join(import.meta.dirname, 'fixtures/custom-serializers-empty') 18 + const testFile = path.join(root, 'basic.test.ts') 19 + const snapshotFile = path.join(root, '__snapshots__/basic.test.ts.snap') 20 + 21 + // clean slate 22 + fs.rmSync(path.join(root, '__snapshots__'), { recursive: true, force: true }) 23 + editFile(testFile, s => s 24 + .replace(/toMatchInlineSnapshot\(`[^`]*`/g, 'toMatchInlineSnapshot(')) 25 + 26 + let result = await runVitest({ 27 + root, 28 + update: 'all', 29 + }) 30 + expect(result.stderr).toMatchInlineSnapshot(`""`) 31 + expect(result.errorTree()).toMatchInlineSnapshot(` 32 + { 33 + "basic.test.ts": { 34 + "file empty": "passed", 35 + "file whitespaces": "passed", 36 + "inline empty": "passed", 37 + "inline whitespaces": "passed", 38 + }, 39 + } 40 + `) 41 + expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 42 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 43 + 44 + exports[\`file empty 1\`] = \`\`; 45 + 46 + exports[\`file whitespaces 1\`] = \` \`; 47 + " 48 + `) 49 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 50 + " 51 + expect({ __unwrap__: "" }).toMatchInlineSnapshot(\`\`) 52 + 53 + expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(\`\`) 54 + " 55 + `) 56 + 57 + result = await runVitest({ 58 + root, 59 + update: 'none', 60 + }) 61 + expect(result.stderr).toMatchInlineSnapshot(`""`) 62 + expect(result.errorTree()).toMatchInlineSnapshot(` 63 + { 64 + "basic.test.ts": { 65 + "file empty": "passed", 66 + "file whitespaces": "passed", 67 + "inline empty": "passed", 68 + "inline whitespaces": "passed", 69 + }, 70 + } 71 + `) 72 + 73 + // TODO: snapshot comparison normalizes whitespaces. probably hard to fix. 74 + editFile(testFile, s => s 75 + .replace(`__unwrap__: " ".repeat(4)`, `__unwrap__: " ".repeat(8)`)) 76 + result = await runVitest({ 77 + root, 78 + update: 'none', 79 + }) 80 + expect(result.stderr).toMatchInlineSnapshot(`""`) 81 + expect(result.errorTree()).toMatchInlineSnapshot(` 82 + { 83 + "basic.test.ts": { 84 + "file empty": "passed", 85 + "file whitespaces": "passed", 86 + "inline empty": "passed", 87 + "inline whitespaces": "passed", 88 + }, 89 + } 90 + `) 91 + expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 92 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 93 + 94 + exports[\`file empty 1\`] = \`\`; 95 + 96 + exports[\`file whitespaces 1\`] = \` \`; 97 + " 98 + `) 99 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 100 + " 101 + expect({ __unwrap__: "" }).toMatchInlineSnapshot(\`\`) 102 + 103 + expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(\`\`) 104 + " 105 + `) 106 + 107 + result = await runVitest({ 108 + root, 109 + update: 'all', 110 + }) 111 + expect(result.stderr).toMatchInlineSnapshot(`""`) 112 + expect(result.errorTree()).toMatchInlineSnapshot(` 113 + { 114 + "basic.test.ts": { 115 + "file empty": "passed", 116 + "file whitespaces": "passed", 117 + "inline empty": "passed", 118 + "inline whitespaces": "passed", 119 + }, 120 + } 121 + `) 122 + expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 123 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 124 + 125 + exports[\`file empty 1\`] = \`\`; 126 + 127 + exports[\`file whitespaces 1\`] = \` \`; 128 + " 129 + `) 130 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 131 + " 132 + expect({ __unwrap__: "" }).toMatchInlineSnapshot(\`\`) 133 + 134 + expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(\`\`) 135 + " 136 + `) 137 + })
+331
test/e2e/snapshots/domain-aria-inline.test.ts
··· 1 + import { join } from 'node:path' 2 + import { playwright } from '@vitest/browser-playwright' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runInlineTests, runVitest } from '../../test-utils' 5 + import { readInlineSnapshots } from './utils' 6 + 7 + test('aria inline snapshot', async () => { 8 + const root = join(import.meta.dirname, 'fixtures/domain-aria-inline') 9 + const testFile = join(root, 'basic.test.ts') 10 + 11 + // purge inline snapshots to empty strings, restore test values 12 + editFile(testFile, s => s 13 + .replace(/toMatchAriaInlineSnapshot\(`[^`]*`/g, 'toMatchAriaInlineSnapshot(')) 14 + 15 + // create snapshots from scratch 16 + let result = await runVitest({ root, update: 'new' }) 17 + expect(result.stderr).toMatchInlineSnapshot(`""`) 18 + expect(result.errorTree()).toMatchInlineSnapshot(` 19 + { 20 + "basic.test.ts": { 21 + "empty": "passed", 22 + "semantic match with regex in snapshot": "passed", 23 + "simple heading": "passed", 24 + }, 25 + } 26 + `) 27 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 28 + " 29 + expect(document.body).toMatchAriaInlineSnapshot(\` 30 + - heading "Hello World" [level=1] 31 + - paragraph: Some description 32 + \`) 33 + 34 + expect(document.body).toMatchAriaInlineSnapshot(\` 35 + - paragraph: Original 36 + - button "1234": Pattern 37 + \`) 38 + 39 + expect(document.body).toMatchAriaInlineSnapshot(\`\`) 40 + " 41 + `) 42 + expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 43 + { 44 + "added": 3, 45 + "didUpdate": false, 46 + "failure": false, 47 + "filesAdded": 1, 48 + "filesRemoved": 0, 49 + "filesRemovedList": [], 50 + "filesUnmatched": 0, 51 + "filesUpdated": 0, 52 + "matched": 0, 53 + "total": 3, 54 + "unchecked": 0, 55 + "uncheckedKeysByFile": [], 56 + "unmatched": 0, 57 + "updated": 0, 58 + } 59 + `) 60 + 61 + // hand-edit inline snapshot to introduce regex pattern 62 + // "1234" -> /\\d+/ 63 + editFile(testFile, s => s 64 + .replace(`- button "1234"`, '- button /\\\\d+/')) 65 + 66 + // run without update — regex matches, all pass 67 + result = await runVitest({ root, update: 'none' }) 68 + expect(result.stderr).toMatchInlineSnapshot(`""`) 69 + expect(result.errorTree()).toMatchInlineSnapshot(` 70 + { 71 + "basic.test.ts": { 72 + "empty": "passed", 73 + "semantic match with regex in snapshot": "passed", 74 + "simple heading": "passed", 75 + }, 76 + } 77 + `) 78 + 79 + // edit test 80 + editFile(testFile, s => s 81 + .replace('<p>Original</p>', '<p>Changed</p>') 82 + .replace(`aria-label="1234"`, `aria-label="9999"`)) 83 + 84 + // run without update — literal mismatch causes failure 85 + result = await runVitest({ root, update: 'none' }) 86 + expect(result.stderr).toMatchInlineSnapshot(` 87 + " 88 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 89 + 90 + FAIL |chromium| basic.test.ts > semantic match with regex in snapshot 91 + Error: Snapshot \`semantic match with regex in snapshot 1\` mismatched 92 + 93 + Failure screenshot: 94 + - snapshots/fixtures/domain-aria-inline/__screenshots__/basic.test.ts/semantic-match-with-regex-in-snapshot-1.png 95 + 96 + - Expected 97 + + Received 98 + 99 + - - paragraph: Original 100 + + - paragraph: Changed 101 + - button /\\d+/: Pattern 102 + 103 + ❯ basic.test.ts:19:24 104 + 17| <button aria-label="9999">Pattern</button> 105 + 18| \` 106 + 19| expect(document.body).toMatchAriaInlineSnapshot(\` 107 + | ^ 108 + 20| - paragraph: Original 109 + 21| - button /\\\\d+/: Pattern 110 + 111 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 112 + 113 + " 114 + `) 115 + expect(result.errorTree()).toMatchInlineSnapshot(` 116 + { 117 + "basic.test.ts": { 118 + "empty": "passed", 119 + "semantic match with regex in snapshot": [ 120 + "Snapshot \`semantic match with regex in snapshot 1\` mismatched", 121 + ], 122 + "simple heading": "passed", 123 + }, 124 + } 125 + `) 126 + 127 + // run with update — should overwrite inline snapshot 128 + result = await runVitest({ root, update: 'all' }) 129 + expect(result.stderr).toMatchInlineSnapshot(`""`) 130 + expect(result.errorTree()).toMatchInlineSnapshot(` 131 + { 132 + "basic.test.ts": { 133 + "empty": "passed", 134 + "semantic match with regex in snapshot": "passed", 135 + "simple heading": "passed", 136 + }, 137 + } 138 + `) 139 + 140 + // verify inline snapshot in source was rewritten correctly 141 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 142 + " 143 + expect(document.body).toMatchAriaInlineSnapshot(\` 144 + - heading "Hello World" [level=1] 145 + - paragraph: Some description 146 + \`) 147 + 148 + expect(document.body).toMatchAriaInlineSnapshot(\` 149 + - paragraph: Changed 150 + - button /\\\\d+/: Pattern 151 + \`) 152 + 153 + expect(document.body).toMatchAriaInlineSnapshot(\`\`) 154 + " 155 + `) 156 + }) 157 + 158 + test('domain multiple inline at same location - success', async () => { 159 + const result = await runInlineTests({ 160 + 'basic.test.ts': ` 161 + import { expect, test } from 'vitest'; 162 + 163 + test('basic', () => { 164 + for (let i = 0; i < 3; i++) { 165 + document.body.innerHTML = "<p>OK</p>"; 166 + expect(document.body).toMatchAriaInlineSnapshot(); 167 + } 168 + }); 169 + `, 170 + }, { 171 + browser: { 172 + enabled: true, 173 + headless: true, 174 + provider: playwright(), 175 + instances: [ 176 + { 177 + browser: 'chromium', 178 + }, 179 + ], 180 + }, 181 + update: 'new', 182 + }) 183 + expect(result.stderr).toMatchInlineSnapshot(`""`) 184 + expect(result.errorTree()).toMatchInlineSnapshot(` 185 + { 186 + "basic.test.ts": { 187 + "basic": "passed", 188 + }, 189 + } 190 + `) 191 + expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 192 + " 193 + import { expect, test } from 'vitest'; 194 + 195 + test('basic', () => { 196 + for (let i = 0; i < 3; i++) { 197 + document.body.innerHTML = "<p>OK</p>"; 198 + expect(document.body).toMatchAriaInlineSnapshot(\`- paragraph: OK\`); 199 + } 200 + }); 201 + " 202 + `) 203 + }) 204 + 205 + test('domain multiple inline at same location - fail', async () => { 206 + const result = await runInlineTests({ 207 + 'basic.test.ts': ` 208 + import { expect, test } from 'vitest'; 209 + 210 + test('basic', () => { 211 + for (let i = 0; i < 3; i++) { 212 + document.body.innerHTML = "<p>count - " + i + "</p>"; 213 + expect(document.body).toMatchAriaInlineSnapshot(); 214 + } 215 + }); 216 + `, 217 + }, { 218 + browser: { 219 + enabled: true, 220 + headless: true, 221 + screenshotFailures: false, 222 + provider: playwright(), 223 + instances: [ 224 + { 225 + browser: 'chromium', 226 + }, 227 + ], 228 + }, 229 + update: 'new', 230 + }) 231 + expect(result.stderr).toMatchInlineSnapshot(` 232 + " 233 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 234 + 235 + FAIL |chromium| basic.test.ts > basic 236 + Error: toMatchAriaInlineSnapshot with different snapshots cannot be called at the same location 237 + 238 + - Expected 239 + + Received 240 + 241 + 242 + - - paragraph: count - 0 243 + + - paragraph: count - 1 244 + 245 + 246 + ❯ basic.test.ts:7:26 247 + 5| for (let i = 0; i < 3; i++) { 248 + 6| document.body.innerHTML = "<p>count - " + i + "</p>"; 249 + 7| expect(document.body).toMatchAriaInlineSnapshot(); 250 + | ^ 251 + 8| } 252 + 9| }); 253 + 254 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 255 + 256 + " 257 + `) 258 + expect(result.errorTree()).toMatchInlineSnapshot(` 259 + { 260 + "basic.test.ts": { 261 + "basic": [ 262 + "toMatchAriaInlineSnapshot with different snapshots cannot be called at the same location", 263 + ], 264 + }, 265 + } 266 + `) 267 + expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 268 + " 269 + import { expect, test } from 'vitest'; 270 + 271 + test('basic', () => { 272 + for (let i = 0; i < 3; i++) { 273 + document.body.innerHTML = "<p>count - " + i + "</p>"; 274 + expect(document.body).toMatchAriaInlineSnapshot(); 275 + } 276 + }); 277 + " 278 + `) 279 + }) 280 + 281 + test('template parse error', async () => { 282 + const result = await runInlineTests({ 283 + 'basic.test.ts': ` 284 + import { expect, test } from 'vitest'; 285 + 286 + test('basic', () => { 287 + expect(document.body).toMatchAriaInlineSnapshot(\`x: y\`); 288 + }); 289 + `, 290 + }, { 291 + browser: { 292 + enabled: true, 293 + headless: true, 294 + screenshotFailures: false, 295 + provider: playwright(), 296 + instances: [ 297 + { 298 + browser: 'chromium', 299 + }, 300 + ], 301 + }, 302 + update: 'none', 303 + }) 304 + expect(result.stderr).toMatchInlineSnapshot(` 305 + " 306 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 307 + 308 + FAIL |chromium| basic.test.ts > basic 309 + Error: Aria snapshot must be a YAML sequence, elements starting with " -" 310 + ❯ basic.test.ts:5:24 311 + 3| 312 + 4| test('basic', () => { 313 + 5| expect(document.body).toMatchAriaInlineSnapshot(\`x: y\`); 314 + | ^ 315 + 6| }); 316 + 7| 317 + 318 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 319 + 320 + " 321 + `) 322 + expect(result.errorTree()).toMatchInlineSnapshot(` 323 + { 324 + "basic.test.ts": { 325 + "basic": [ 326 + "Aria snapshot must be a YAML sequence, elements starting with " -"", 327 + ], 328 + }, 329 + } 330 + `) 331 + })
+176
test/e2e/snapshots/domain-aria.test.ts
··· 1 + import fs, { readFileSync } from 'node:fs' 2 + import { join } from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + 6 + test('aria snapshot', async () => { 7 + const root = join(import.meta.dirname, 'fixtures/domain-aria') 8 + const testFile = join(root, 'basic.test.ts') 9 + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 10 + 11 + // clean slate 12 + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 13 + 14 + // create snapshots from scratch — literal rendered values 15 + let result = await runVitest({ root, update: 'new' }) 16 + expect(result.stderr).toMatchInlineSnapshot(`""`) 17 + expect(result.errorTree()).toMatchInlineSnapshot(` 18 + { 19 + "basic.test.ts": { 20 + "empty": "passed", 21 + "semantic match with regex in snapshot": "passed", 22 + "simple heading and paragraph": "passed", 23 + }, 24 + } 25 + `) 26 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 27 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 28 + 29 + exports[\`empty 1\`] = \` 30 + 31 + \`; 32 + 33 + exports[\`semantic match with regex in snapshot 1\`] = \` 34 + - paragraph: Original 35 + - button "1234": Pattern 36 + \`; 37 + 38 + exports[\`simple heading and paragraph 1\`] = \` 39 + - heading "Hello World" [level=1] 40 + - paragraph: Some description 41 + \`; 42 + " 43 + `) 44 + expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 45 + { 46 + "added": 3, 47 + "didUpdate": false, 48 + "failure": false, 49 + "filesAdded": 1, 50 + "filesRemoved": 0, 51 + "filesRemovedList": [], 52 + "filesUnmatched": 0, 53 + "filesUpdated": 0, 54 + "matched": 0, 55 + "total": 3, 56 + "unchecked": 0, 57 + "uncheckedKeysByFile": [], 58 + "unmatched": 0, 59 + "updated": 0, 60 + } 61 + `) 62 + 63 + // hand-edit snapshot to introduce regex patterns for "semantic match" test 64 + editFile(snapshotFile, s => s 65 + .replace(`- button "1234"`, `- button /\\\\d+/`)) 66 + 67 + // re-run without update — regex pattern matches, all pass, snapshot unchanged 68 + result = await runVitest({ root, update: 'none' }) 69 + expect(result.stderr).toMatchInlineSnapshot(`""`) 70 + expect(result.errorTree()).toMatchInlineSnapshot(` 71 + { 72 + "basic.test.ts": { 73 + "empty": "passed", 74 + "semantic match with regex in snapshot": "passed", 75 + "simple heading and paragraph": "passed", 76 + }, 77 + } 78 + `) 79 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 80 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 81 + 82 + exports[\`empty 1\`] = \` 83 + 84 + \`; 85 + 86 + exports[\`semantic match with regex in snapshot 1\`] = \` 87 + - paragraph: Original 88 + - button /\\\\d+/: Pattern 89 + \`; 90 + 91 + exports[\`simple heading and paragraph 1\`] = \` 92 + - heading "Hello World" [level=1] 93 + - paragraph: Some description 94 + \`; 95 + " 96 + `) 97 + 98 + // edit test 99 + editFile(testFile, s => s 100 + .replace('<p>Original</p>', '<p>Changed</p>') 101 + .replace(`aria-label="1234"`, `aria-label="9999"`)) 102 + 103 + // run without update — literal mismatch causes failure 104 + result = await runVitest({ root, update: 'none' }) 105 + expect(result.stderr).toMatchInlineSnapshot(` 106 + " 107 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 108 + 109 + FAIL |chromium| basic.test.ts > semantic match with regex in snapshot 110 + Error: Snapshot \`semantic match with regex in snapshot 1\` mismatched 111 + 112 + Failure screenshot: 113 + - snapshots/fixtures/domain-aria/__screenshots__/basic.test.ts/semantic-match-with-regex-in-snapshot-1.png 114 + 115 + - Expected 116 + + Received 117 + 118 + - - paragraph: Original 119 + + - paragraph: Changed 120 + - button /\\d+/: Pattern 121 + 122 + ❯ basic.test.ts:20:24 123 + 18| <button aria-label="9999">Pattern</button> 124 + 19| \` 125 + 20| expect(document.body).toMatchAriaSnapshot() 126 + | ^ 127 + 21| }) 128 + 22| 129 + 130 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 131 + 132 + " 133 + `) 134 + expect(result.errorTree()).toMatchInlineSnapshot(` 135 + { 136 + "basic.test.ts": { 137 + "empty": "passed", 138 + "semantic match with regex in snapshot": [ 139 + "Snapshot \`semantic match with regex in snapshot 1\` mismatched", 140 + ], 141 + "simple heading and paragraph": "passed", 142 + }, 143 + } 144 + `) 145 + 146 + // run with update 147 + result = await runVitest({ root, update: 'all' }) 148 + expect(result.stderr).toMatchInlineSnapshot(`""`) 149 + expect(result.errorTree()).toMatchInlineSnapshot(` 150 + { 151 + "basic.test.ts": { 152 + "empty": "passed", 153 + "semantic match with regex in snapshot": "passed", 154 + "simple heading and paragraph": "passed", 155 + }, 156 + } 157 + `) 158 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 159 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 160 + 161 + exports[\`empty 1\`] = \` 162 + 163 + \`; 164 + 165 + exports[\`semantic match with regex in snapshot 1\`] = \` 166 + - paragraph: Changed 167 + - button /\\\\d+/: Pattern 168 + \`; 169 + 170 + exports[\`simple heading and paragraph 1\`] = \` 171 + - heading "Hello World" [level=1] 172 + - paragraph: Some description 173 + \`; 174 + " 175 + `) 176 + })
+159
test/e2e/snapshots/domain-inline.test.ts
··· 1 + import { join } from 'node:path' 2 + import { expect, test } from 'vitest' 3 + import { editFile, runVitest } from '../../test-utils' 4 + import { readInlineSnapshots } from './utils' 5 + 6 + test('domain inline snapshot', async () => { 7 + const root = join(import.meta.dirname, 'fixtures/domain-inline') 8 + const testFile = join(root, 'basic.test.ts') 9 + 10 + // purge inline snapshots to empty strings, restore test values 11 + editFile(testFile, s => s 12 + .replace(/toMatchKvInlineSnapshot\(`[^`]*`/g, 'toMatchKvInlineSnapshot(')) 13 + 14 + // create snapshots from scratch 15 + let result = await runVitest({ root, update: 'new' }) 16 + expect(result.stderr).toMatchInlineSnapshot(`""`) 17 + expect(result.errorTree()).toMatchInlineSnapshot(` 18 + { 19 + "basic.test.ts": { 20 + "all literal": "passed", 21 + "empty snapshot": "passed", 22 + "with regex": "passed", 23 + }, 24 + } 25 + `) 26 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 27 + " 28 + expect({ name: 'alice', age: '30' }).toMatchKvInlineSnapshot(\` 29 + name=alice 30 + age=30 31 + \`) 32 + 33 + expect({ name: 'bob', score: '999', status: 'active' }).toMatchKvInlineSnapshot(\` 34 + name=bob 35 + score=999 36 + status=active 37 + \`) 38 + 39 + expect({}).toMatchKvInlineSnapshot(\`\`) 40 + " 41 + `) 42 + 43 + // hand-edit inline snapshot to introduce regex pattern 44 + // score=999 -> score=/\\d+/ 45 + editFile(testFile, s => s 46 + .replace('score=999', 'score=/\\\\d+/')) 47 + 48 + // run without update — regex matches, all pass 49 + result = await runVitest({ root, update: 'none' }) 50 + expect(result.stderr).toMatchInlineSnapshot(`""`) 51 + expect(result.errorTree()).toMatchInlineSnapshot(` 52 + { 53 + "basic.test.ts": { 54 + "all literal": "passed", 55 + "empty snapshot": "passed", 56 + "with regex": "passed", 57 + }, 58 + } 59 + `) 60 + 61 + // edit test values: score '999' -> '42' (regex still matches), 62 + // status 'active' -> 'inactive' (literal mismatch) 63 + editFile(testFile, s => s 64 + .replace(`name: 'alice',`, ``) 65 + .replace(`score: '999'`, `score: '42'`) 66 + .replace(`status: 'active'`, `status: 'inactive'`)) 67 + 68 + // run without update — status mismatch causes failure 69 + result = await runVitest({ root, update: 'none' }) 70 + expect(result.stderr).toMatchInlineSnapshot(` 71 + " 72 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 73 + 74 + FAIL basic.test.ts > all literal 75 + Error: Snapshot \`all literal 1\` mismatched 76 + 77 + - Expected 78 + + Received 79 + 80 + - name=alice 81 + age=30 82 + 83 + ❯ basic.test.ts:5:26 84 + 3| 85 + 4| test('all literal', () => { 86 + 5| expect({ age: '30' }).toMatchKvInlineSnapshot(\` 87 + | ^ 88 + 6| name=alice 89 + 7| age=30 90 + 91 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 92 + 93 + FAIL basic.test.ts > with regex 94 + Error: Snapshot \`with regex 1\` mismatched 95 + 96 + - Expected 97 + + Received 98 + 99 + name=bob 100 + score=/\\d+/ 101 + - status=active 102 + + status=inactive 103 + 104 + ❯ basic.test.ts:12:60 105 + 10| 106 + 11| test('with regex', () => { 107 + 12| expect({ name: 'bob', score: '42', status: 'inactive' }).toMatchKvIn… 108 + | ^ 109 + 13| name=bob 110 + 14| score=/\\\\d+/ 111 + 112 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 113 + 114 + " 115 + `) 116 + expect(result.errorTree()).toMatchInlineSnapshot(` 117 + { 118 + "basic.test.ts": { 119 + "all literal": [ 120 + "Snapshot \`all literal 1\` mismatched", 121 + ], 122 + "empty snapshot": "passed", 123 + "with regex": [ 124 + "Snapshot \`with regex 1\` mismatched", 125 + ], 126 + }, 127 + } 128 + `) 129 + 130 + // run with update — should preserve score regex (matched), 131 + // overwrite status with literal (didn't match) 132 + result = await runVitest({ root, update: 'all' }) 133 + expect(result.stderr).toMatchInlineSnapshot(`""`) 134 + expect(result.errorTree()).toMatchInlineSnapshot(` 135 + { 136 + "basic.test.ts": { 137 + "all literal": "passed", 138 + "empty snapshot": "passed", 139 + "with regex": "passed", 140 + }, 141 + } 142 + `) 143 + 144 + // verify inline snapshot in source was rewritten correctly 145 + // score regex preserved, status updated to 'inactive' 146 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 147 + " 148 + expect({ age: '30' }).toMatchKvInlineSnapshot(\`age=30\`) 149 + 150 + expect({ name: 'bob', score: '42', status: 'inactive' }).toMatchKvInlineSnapshot(\` 151 + name=bob 152 + score=/\\\\d+/ 153 + status=inactive 154 + \`) 155 + 156 + expect({}).toMatchKvInlineSnapshot(\`\`) 157 + " 158 + `) 159 + })
+452
test/e2e/snapshots/domain-poll-inline.test.ts
··· 1 + import { join } from 'node:path' 2 + import { expect, test } from 'vitest' 3 + import { editFile, runInlineTests, runVitest } from '../../test-utils' 4 + import { readInlineSnapshots } from './utils' 5 + 6 + test('domain inline snapshot with poll', async () => { 7 + const root = join(import.meta.dirname, 'fixtures/domain-poll-inline') 8 + const testFile = join(root, 'basic.test.ts') 9 + 10 + // purge inline snapshots to empty strings 11 + editFile(testFile, s => s 12 + .replace(/toMatchKvInlineSnapshot\(`[^`]*`/g, 'toMatchKvInlineSnapshot(')) 13 + 14 + // --- create snapshots (update: new) --- 15 + let result = await runVitest({ root, update: 'new' }) 16 + expect(result.stderr).toMatchInlineSnapshot(`""`) 17 + expect(result.errorTree()).toMatchInlineSnapshot(` 18 + { 19 + "basic.test.ts": { 20 + "empty snapshot": "passed", 21 + "multiple poll snapshots": "passed", 22 + "non-poll alongside poll": "passed", 23 + "stable": "passed", 24 + "throw then stable": "passed", 25 + "unstable then stable": "passed", 26 + }, 27 + } 28 + `) 29 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 30 + " 31 + expect.poll(() => { 32 + trial++ 33 + return { name: 'a', age: '23' } 34 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 35 + name=a 36 + age=23 37 + \`) 38 + 39 + expect.poll(() => { 40 + trial++ 41 + if (trial <= 3) { 42 + throw new Error(\`Fail at \${trial}\`) 43 + } 44 + return { name: 'b', age: '23' } 45 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 46 + name=b 47 + age=23 48 + \`) 49 + 50 + expect.poll(() => { 51 + trial++ 52 + if (trial <= 3) return { status: 'loading', trial } // unstable 53 + return { status: 'done' } // then stable 54 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`status=done\`) 55 + 56 + expect.poll(() => { 57 + return { x: '1' } 58 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`x=1\`) 59 + 60 + expect.poll(() => { 61 + return { y: '2' } 62 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`y=2\`) 63 + 64 + expect({ static: 'value' }).toMatchKvInlineSnapshot(\`static=value\`) 65 + 66 + expect.poll(() => { 67 + return { polled: 'value' } 68 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`polled=value\`) 69 + 70 + expect({ another: 'static' }).toMatchKvInlineSnapshot(\`another=static\`) 71 + 72 + expect.poll(() => { 73 + return {} 74 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`\`) 75 + " 76 + `) 77 + 78 + // --- re-run unchanged (update: none) --- 79 + result = await runVitest({ root, update: 'none' }) 80 + expect(result.stderr).toMatchInlineSnapshot(`""`) 81 + expect(result.errorTree()).toMatchInlineSnapshot(` 82 + { 83 + "basic.test.ts": { 84 + "empty snapshot": "passed", 85 + "multiple poll snapshots": "passed", 86 + "non-poll alongside poll": "passed", 87 + "stable": "passed", 88 + "throw then stable": "passed", 89 + "unstable then stable": "passed", 90 + }, 91 + } 92 + `) 93 + 94 + // --- mismatch — stable on wrong value --- 95 + editFile(testFile, s => s 96 + .replace('name=a\n', 'name=a-changed\n')) 97 + 98 + result = await runVitest({ root, update: 'none' }) 99 + expect(result.stderr).toMatchInlineSnapshot(` 100 + " 101 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 102 + 103 + FAIL basic.test.ts > stable 104 + Error: Snapshot \`stable 1\` mismatched 105 + 106 + - Expected 107 + + Received 108 + 109 + - name=a-changed 110 + + name=a 111 + age=23 112 + 113 + ❯ basic.test.ts:9:24 114 + 7| trial++ 115 + 8| return { name: 'a', age: '23' } 116 + 9| }, { interval: 10 }).toMatchKvInlineSnapshot(\` 117 + | ^ 118 + 10| name=a-changed 119 + 11| age=23 120 + 121 + Caused by: Error: Matcher did not succeed in time. 122 + ❯ basic.test.ts:6:3 123 + 124 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 125 + 126 + " 127 + `) 128 + expect(result.errorTree()).toMatchInlineSnapshot(` 129 + { 130 + "basic.test.ts": { 131 + "empty snapshot": "passed", 132 + "multiple poll snapshots": "passed", 133 + "non-poll alongside poll": "passed", 134 + "stable": [ 135 + "Snapshot \`stable 1\` mismatched", 136 + ], 137 + "throw then stable": "passed", 138 + "unstable then stable": "passed", 139 + }, 140 + } 141 + `) 142 + 143 + // --- update mode (update: all) --- 144 + result = await runVitest({ root, update: 'all' }) 145 + expect(result.stderr).toMatchInlineSnapshot(`""`) 146 + expect(result.errorTree()).toMatchInlineSnapshot(` 147 + { 148 + "basic.test.ts": { 149 + "empty snapshot": "passed", 150 + "multiple poll snapshots": "passed", 151 + "non-poll alongside poll": "passed", 152 + "stable": "passed", 153 + "throw then stable": "passed", 154 + "unstable then stable": "passed", 155 + }, 156 + } 157 + `) 158 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 159 + " 160 + expect.poll(() => { 161 + trial++ 162 + return { name: 'a', age: '23' } 163 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 164 + name=a 165 + age=23 166 + \`) 167 + 168 + expect.poll(() => { 169 + trial++ 170 + if (trial <= 3) { 171 + throw new Error(\`Fail at \${trial}\`) 172 + } 173 + return { name: 'b', age: '23' } 174 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 175 + name=b 176 + age=23 177 + \`) 178 + 179 + expect.poll(() => { 180 + trial++ 181 + if (trial <= 3) return { status: 'loading', trial } // unstable 182 + return { status: 'done' } // then stable 183 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`status=done\`) 184 + 185 + expect.poll(() => { 186 + return { x: '1' } 187 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`x=1\`) 188 + 189 + expect.poll(() => { 190 + return { y: '2' } 191 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`y=2\`) 192 + 193 + expect({ static: 'value' }).toMatchKvInlineSnapshot(\`static=value\`) 194 + 195 + expect.poll(() => { 196 + return { polled: 'value' } 197 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`polled=value\`) 198 + 199 + expect({ another: 'static' }).toMatchKvInlineSnapshot(\`another=static\`) 200 + 201 + expect.poll(() => { 202 + return {} 203 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`\`) 204 + " 205 + `) 206 + 207 + // --- pattern-preserving update --- 208 + editFile(testFile, s => s 209 + .replace('name=a\n', 'name=/\\\\w/\n')) 210 + 211 + result = await runVitest({ root, update: 'all' }) 212 + expect(result.stderr).toMatchInlineSnapshot(`""`) 213 + expect(result.errorTree()).toMatchInlineSnapshot(` 214 + { 215 + "basic.test.ts": { 216 + "empty snapshot": "passed", 217 + "multiple poll snapshots": "passed", 218 + "non-poll alongside poll": "passed", 219 + "stable": "passed", 220 + "throw then stable": "passed", 221 + "unstable then stable": "passed", 222 + }, 223 + } 224 + `) 225 + expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 226 + " 227 + expect.poll(() => { 228 + trial++ 229 + return { name: 'a', age: '23' } 230 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 231 + name=/\\\\w/ 232 + age=23 233 + \`) 234 + 235 + expect.poll(() => { 236 + trial++ 237 + if (trial <= 3) { 238 + throw new Error(\`Fail at \${trial}\`) 239 + } 240 + return { name: 'b', age: '23' } 241 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 242 + name=b 243 + age=23 244 + \`) 245 + 246 + expect.poll(() => { 247 + trial++ 248 + if (trial <= 3) return { status: 'loading', trial } // unstable 249 + return { status: 'done' } // then stable 250 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`status=done\`) 251 + 252 + expect.poll(() => { 253 + return { x: '1' } 254 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`x=1\`) 255 + 256 + expect.poll(() => { 257 + return { y: '2' } 258 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`y=2\`) 259 + 260 + expect({ static: 'value' }).toMatchKvInlineSnapshot(\`static=value\`) 261 + 262 + expect.poll(() => { 263 + return { polled: 'value' } 264 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`polled=value\`) 265 + 266 + expect({ another: 'static' }).toMatchKvInlineSnapshot(\`another=static\`) 267 + 268 + expect.poll(() => { 269 + return {} 270 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`\`) 271 + " 272 + `) 273 + }) 274 + 275 + test('poll until stable match when "none"', async () => { 276 + const result = await runInlineTests({ 277 + 'basic.test.ts': ` 278 + import { expect, test } from 'vitest' 279 + import '../snapshots/fixtures/domain/basic-extend' 280 + 281 + test('stable wrong then right', async () => { 282 + let trial = 0 283 + await expect.poll(() => { 284 + trial++ 285 + if (trial <= 4) return { phase: 'pending' } 286 + return { phase: 'complete' } 287 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 288 + phase=complete 289 + \`) 290 + expect(trial).toBe(6) 291 + }) 292 + `, 293 + }, { 294 + update: 'none', 295 + }) 296 + expect(result.stderr).toMatchInlineSnapshot(`""`) 297 + expect(result.errorTree()).toMatchInlineSnapshot(` 298 + { 299 + "basic.test.ts": { 300 + "stable wrong then right": "passed", 301 + }, 302 + } 303 + `) 304 + }) 305 + 306 + test('poll until stable when "all"', async () => { 307 + const result = await runInlineTests({ 308 + 'basic.test.ts': ` 309 + import { expect, test } from 'vitest' 310 + import '../snapshots/fixtures/domain/basic-extend' 311 + 312 + test('stable wrong then right', async () => { 313 + let trial = 0 314 + await expect.poll(() => { 315 + trial++ 316 + if (trial <= 4) return { phase: 'pending' } 317 + return { phase: 'complete' } 318 + }, { interval: 10 }).toMatchKvInlineSnapshot(\` 319 + phase=complete 320 + \`) 321 + expect(trial).toBe(2) 322 + }) 323 + `, 324 + }, { 325 + update: 'all', 326 + }) 327 + expect(result.stderr).toMatchInlineSnapshot(`""`) 328 + expect(result.errorTree()).toMatchInlineSnapshot(` 329 + { 330 + "basic.test.ts": { 331 + "stable wrong then right": "passed", 332 + }, 333 + } 334 + `) 335 + expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 336 + " 337 + import { expect, test } from 'vitest' 338 + import '../snapshots/fixtures/domain/basic-extend' 339 + 340 + test('stable wrong then right', async () => { 341 + let trial = 0 342 + await expect.poll(() => { 343 + trial++ 344 + if (trial <= 4) return { phase: 'pending' } 345 + return { phase: 'complete' } 346 + }, { interval: 10 }).toMatchKvInlineSnapshot(\`phase=pending\`) 347 + expect(trial).toBe(2) 348 + }) 349 + " 350 + `) 351 + }) 352 + 353 + test('errors', async () => { 354 + const result = await runInlineTests({ 355 + 'basic.test.ts': ` 356 + import { expect, test } from 'vitest' 357 + import '../snapshots/fixtures/domain/basic-extend' 358 + 359 + test('unstable', async () => { 360 + let trial = 0 361 + await expect.poll(() => { 362 + trial++ 363 + return { name: 'x', counter: String(trial) } 364 + }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 365 + }) 366 + 367 + test('hanging', async () => { 368 + let trial = 0 369 + await expect.poll(() => { 370 + trial++ 371 + return new Promise(() => {}) 372 + }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 373 + }) 374 + 375 + test('throwing', async () => { 376 + let trial = 0 377 + await expect.poll(() => { 378 + trial++ 379 + throw new Error("ALWAYS_THROWS") 380 + }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 381 + }) 382 + `, 383 + }, { 384 + update: 'all', 385 + }) 386 + expect(result.stderr).toMatchInlineSnapshot(` 387 + " 388 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 389 + 390 + FAIL basic.test.ts > unstable 391 + Error: poll() did not produce a stable snapshot within the timeout 392 + ❯ basic.test.ts:10:38 393 + 8| trial++ 394 + 9| return { name: 'x', counter: String(trial) } 395 + 10| }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 396 + | ^ 397 + 11| }) 398 + 12| 399 + 400 + Caused by: Error: Matcher did not succeed in time. 401 + ❯ basic.test.ts:7:3 402 + 403 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 404 + 405 + FAIL basic.test.ts > hanging 406 + Error: poll() did not produce a stable snapshot within the timeout 407 + ❯ basic.test.ts:18:38 408 + 16| trial++ 409 + 17| return new Promise(() => {}) 410 + 18| }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 411 + | ^ 412 + 19| }) 413 + 20| 414 + 415 + Caused by: Error: Matcher did not succeed in time. 416 + ❯ basic.test.ts:15:3 417 + 418 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 419 + 420 + FAIL basic.test.ts > throwing 421 + Error: ALWAYS_THROWS 422 + ❯ basic.test.ts:26:38 423 + 24| trial++ 424 + 25| throw new Error("ALWAYS_THROWS") 425 + 26| }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 426 + | ^ 427 + 27| }) 428 + 28| 429 + 430 + Caused by: Error: Matcher did not succeed in time. 431 + ❯ basic.test.ts:23:3 432 + 433 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 434 + 435 + " 436 + `) 437 + expect(result.errorTree()).toMatchInlineSnapshot(` 438 + { 439 + "basic.test.ts": { 440 + "hanging": [ 441 + "poll() did not produce a stable snapshot within the timeout", 442 + ], 443 + "throwing": [ 444 + "ALWAYS_THROWS", 445 + ], 446 + "unstable": [ 447 + "poll() did not produce a stable snapshot within the timeout", 448 + ], 449 + }, 450 + } 451 + `) 452 + })
+496
test/e2e/snapshots/domain-poll.test.ts
··· 1 + /** 2 + * pollAssertDomain behavior matrix 3 + * 4 + * Stability requirement: poll must produce two consecutive identical renders. 5 + * When a reference exists (and not `update: all`), the stable value must also 6 + * pass `adapter.match` — otherwise the baseline resets and polling continues 7 + * through intermediate stable states. 8 + * 9 + * Poll behavior | no reference | has reference (match) | has reference (mismatch) 10 + * -----------------------|----------------------|------------------------|------------------------- 11 + * stable immediately | new: pass (creates) | none/new/all: pass | none/new: fail (diff) 12 + * | none: fail (missing) | | all: pass (rewrites) 13 + * | all: pass (creates) | | 14 + * throw then stable | same as above | pass (throw resets | same as above 15 + * | | baseline, re-polls) | 16 + * transitional → stable | same as above | pass (rides through | same as above 17 + * | | intermediate states) | 18 + * stable wrong → right | n/a (no ref to | pass (match rejects | n/a 19 + * | reject against) | wrong, rides through)| 20 + * never stabilizes | fail (unstable) | fail (unstable) | fail (unstable) 21 + * always throws | fail (unstable, | fail (unstable, | fail (unstable, 22 + * | cause: poll error) | cause: poll error) | cause: poll error) 23 + * poll hangs | fail (unstable) | fail (unstable) | fail (unstable) 24 + */ 25 + import fs, { readFileSync } from 'node:fs' 26 + import { join } from 'node:path' 27 + import { expect, test } from 'vitest' 28 + import { editFile, runInlineTests, runVitest } from '../../test-utils' 29 + 30 + test('domain snapshot with poll', async () => { 31 + const root = join(import.meta.dirname, 'fixtures/domain-poll') 32 + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 33 + 34 + // clean slate 35 + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 36 + 37 + // --- create snapshots (update: new) --- 38 + let result = await runVitest({ root, update: 'new' }) 39 + expect(result.stderr).toMatchInlineSnapshot(`""`) 40 + expect(result.errorTree()).toMatchInlineSnapshot(` 41 + { 42 + "basic.test.ts": { 43 + "empty snapshot": "passed", 44 + "multiple poll snapshots": "passed", 45 + "non-poll alongside poll": "passed", 46 + "stable": "passed", 47 + "throw then stable": "passed", 48 + "unstable then stable": "passed", 49 + }, 50 + } 51 + `) 52 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 53 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 54 + 55 + exports[\`empty snapshot 1\`] = \`\`; 56 + 57 + exports[\`multiple poll snapshots 1\`] = \` 58 + x=1 59 + \`; 60 + 61 + exports[\`multiple poll snapshots 2\`] = \` 62 + y=2 63 + \`; 64 + 65 + exports[\`non-poll alongside poll 1\`] = \` 66 + static=value 67 + \`; 68 + 69 + exports[\`non-poll alongside poll 2\`] = \` 70 + polled=value 71 + \`; 72 + 73 + exports[\`non-poll alongside poll 3\`] = \` 74 + another=static 75 + \`; 76 + 77 + exports[\`stable 1\`] = \` 78 + name=a 79 + age=23 80 + \`; 81 + 82 + exports[\`throw then stable 1\`] = \` 83 + name=b 84 + age=23 85 + \`; 86 + 87 + exports[\`unstable then stable 1\`] = \` 88 + status=done 89 + \`; 90 + " 91 + `) 92 + 93 + // --- re-run unchanged (update: none) --- 94 + const result2 = await runVitest({ root, update: 'none' }) 95 + expect(result2.stderr).toBe(result.stderr) 96 + expect(result2.errorTree()).toEqual(result.errorTree()) 97 + 98 + // --- mismatch — stable on wrong value --- 99 + // Edit reference so "stable" poll stabilizes but doesn't match 100 + // Should produce a mismatch error with diff, not "unstable" error 101 + editFile(snapshotFile, s => s 102 + .replace('name=a\n', 'name=a-changed\n')) 103 + 104 + result = await runVitest({ root, update: 'none' }) 105 + expect(result.stderr).toMatchInlineSnapshot(` 106 + " 107 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 108 + 109 + FAIL basic.test.ts > stable 110 + Error: Snapshot \`stable 1\` mismatched 111 + 112 + - Expected 113 + + Received 114 + 115 + - name=a-changed 116 + + name=a 117 + age=23 118 + 119 + ❯ basic.test.ts:9:24 120 + 7| trial++ 121 + 8| return { name: 'a', age: '23' } 122 + 9| }, { interval: 10 }).toMatchKvSnapshot() 123 + | ^ 124 + 10| expect(trial).toBe(2) 125 + 11| }) 126 + 127 + Caused by: Error: Matcher did not succeed in time. 128 + ❯ basic.test.ts:6:3 129 + 130 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 131 + 132 + " 133 + `) 134 + expect(result.errorTree()).toMatchInlineSnapshot(` 135 + { 136 + "basic.test.ts": { 137 + "empty snapshot": "passed", 138 + "multiple poll snapshots": "passed", 139 + "non-poll alongside poll": "passed", 140 + "stable": [ 141 + "Snapshot \`stable 1\` mismatched", 142 + ], 143 + "throw then stable": "passed", 144 + "unstable then stable": "passed", 145 + }, 146 + } 147 + `) 148 + 149 + // --- update mode (update: all) --- 150 + // Rewrite snapshots with current stable values 151 + result = await runVitest({ root, update: 'all' }) 152 + expect(result.stderr).toMatchInlineSnapshot(`""`) 153 + expect(result.errorTree()).toMatchInlineSnapshot(` 154 + { 155 + "basic.test.ts": { 156 + "empty snapshot": "passed", 157 + "multiple poll snapshots": "passed", 158 + "non-poll alongside poll": "passed", 159 + "stable": "passed", 160 + "throw then stable": "passed", 161 + "unstable then stable": "passed", 162 + }, 163 + } 164 + `) 165 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 166 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 167 + 168 + exports[\`empty snapshot 1\`] = \`\`; 169 + 170 + exports[\`multiple poll snapshots 1\`] = \` 171 + x=1 172 + \`; 173 + 174 + exports[\`multiple poll snapshots 2\`] = \` 175 + y=2 176 + \`; 177 + 178 + exports[\`non-poll alongside poll 1\`] = \` 179 + static=value 180 + \`; 181 + 182 + exports[\`non-poll alongside poll 2\`] = \` 183 + polled=value 184 + \`; 185 + 186 + exports[\`non-poll alongside poll 3\`] = \` 187 + another=static 188 + \`; 189 + 190 + exports[\`stable 1\`] = \` 191 + name=a 192 + age=23 193 + \`; 194 + 195 + exports[\`throw then stable 1\`] = \` 196 + name=b 197 + age=23 198 + \`; 199 + 200 + exports[\`unstable then stable 1\`] = \` 201 + status=done 202 + \`; 203 + " 204 + `) 205 + 206 + // --- pattern-preserving update --- 207 + // Inject regex pattern into snapshot, verify --update preserves it 208 + editFile(snapshotFile, s => s 209 + .replace('name=a\n', 'name=/\\\\w/\n')) 210 + 211 + result = await runVitest({ root, update: 'all' }) 212 + expect(result.stderr).toMatchInlineSnapshot(`""`) 213 + expect(result.errorTree()).toMatchInlineSnapshot(` 214 + { 215 + "basic.test.ts": { 216 + "empty snapshot": "passed", 217 + "multiple poll snapshots": "passed", 218 + "non-poll alongside poll": "passed", 219 + "stable": "passed", 220 + "throw then stable": "passed", 221 + "unstable then stable": "passed", 222 + }, 223 + } 224 + `) 225 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 226 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 227 + 228 + exports[\`empty snapshot 1\`] = \`\`; 229 + 230 + exports[\`multiple poll snapshots 1\`] = \` 231 + x=1 232 + \`; 233 + 234 + exports[\`multiple poll snapshots 2\`] = \` 235 + y=2 236 + \`; 237 + 238 + exports[\`non-poll alongside poll 1\`] = \` 239 + static=value 240 + \`; 241 + 242 + exports[\`non-poll alongside poll 2\`] = \` 243 + polled=value 244 + \`; 245 + 246 + exports[\`non-poll alongside poll 3\`] = \` 247 + another=static 248 + \`; 249 + 250 + exports[\`stable 1\`] = \` 251 + name=/\\\\w/ 252 + age=23 253 + \`; 254 + 255 + exports[\`throw then stable 1\`] = \` 256 + name=b 257 + age=23 258 + \`; 259 + 260 + exports[\`unstable then stable 1\`] = \` 261 + status=done 262 + \`; 263 + " 264 + `) 265 + }) 266 + 267 + test('poll until stable match when "none"', async () => { 268 + const result = await runInlineTests({ 269 + '__snapshots__/basic.test.ts.snap': `\ 270 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 271 + 272 + exports[\`stable wrong then right 1\`] = \` 273 + phase=complete 274 + \`; 275 + `, 276 + 'basic.test.ts': ` 277 + import { expect, test } from 'vitest' 278 + import '../snapshots/fixtures/domain/basic-extend' 279 + 280 + test('stable wrong then right', async () => { 281 + let trial = 0 282 + await expect.poll(() => { 283 + trial++ 284 + if (trial <= 4) return { phase: 'pending' } 285 + return { phase: 'complete' } 286 + }, { interval: 10 }).toMatchKvSnapshot() 287 + expect(trial).toBe(6) 288 + }) 289 + `, 290 + }, { 291 + update: 'none', 292 + }) 293 + expect(result.stderr).toMatchInlineSnapshot(`""`) 294 + expect(result.errorTree()).toMatchInlineSnapshot(` 295 + { 296 + "basic.test.ts": { 297 + "stable wrong then right": "passed", 298 + }, 299 + } 300 + `) 301 + }) 302 + 303 + test('poll until stable when "all"', async () => { 304 + const result = await runInlineTests({ 305 + '__snapshots__/basic.test.ts.snap': `\ 306 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 307 + 308 + exports[\`stable wrong then right 1\`] = \` 309 + phase=complete 310 + \`; 311 + `, 312 + 'basic.test.ts': ` 313 + import { expect, test } from 'vitest' 314 + import '../snapshots/fixtures/domain/basic-extend' 315 + 316 + test('stable wrong then right', async () => { 317 + let trial = 0 318 + await expect.poll(() => { 319 + trial++ 320 + if (trial <= 4) return { phase: 'pending' } 321 + return { phase: 'complete' } 322 + }, { interval: 10 }).toMatchKvSnapshot() 323 + expect(trial).toBe(2) 324 + }) 325 + `, 326 + }, { 327 + update: 'all', 328 + }) 329 + expect(result.stderr).toMatchInlineSnapshot(`""`) 330 + expect(result.errorTree()).toMatchInlineSnapshot(` 331 + { 332 + "basic.test.ts": { 333 + "stable wrong then right": "passed", 334 + }, 335 + } 336 + `) 337 + expect(result.fs.readFile('__snapshots__/basic.test.ts.snap')).toMatchInlineSnapshot(` 338 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 339 + 340 + exports[\`stable wrong then right 1\`] = \` 341 + phase=pending 342 + \`; 343 + " 344 + `) 345 + }) 346 + 347 + test('errors', async () => { 348 + const result = await runInlineTests({ 349 + 'basic.test.ts': ` 350 + import { expect, test } from 'vitest' 351 + import '../snapshots/fixtures/domain/basic-extend' 352 + 353 + test('unstable', async () => { 354 + let trial = 0 355 + await expect.poll(() => { 356 + trial++ 357 + return { name: 'x', counter: String(trial) } 358 + }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 359 + }) 360 + 361 + test('hanging', async () => { 362 + let trial = 0 363 + await expect.poll(() => { 364 + trial++ 365 + return new Promise(() => {}) 366 + }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 367 + }) 368 + 369 + test('throwing', async () => { 370 + let trial = 0 371 + await expect.poll(() => { 372 + trial++ 373 + throw new Error("ALWAYS_THROWS") 374 + }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 375 + }) 376 + `, 377 + }, { 378 + update: 'all', 379 + }) 380 + expect(result.stderr).toMatchInlineSnapshot(` 381 + " 382 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 383 + 384 + FAIL basic.test.ts > unstable 385 + Error: poll() did not produce a stable snapshot within the timeout 386 + ❯ basic.test.ts:10:38 387 + 8| trial++ 388 + 9| return { name: 'x', counter: String(trial) } 389 + 10| }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 390 + | ^ 391 + 11| }) 392 + 12| 393 + 394 + Caused by: Error: Matcher did not succeed in time. 395 + ❯ basic.test.ts:7:3 396 + 397 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 398 + 399 + FAIL basic.test.ts > hanging 400 + Error: poll() did not produce a stable snapshot within the timeout 401 + ❯ basic.test.ts:18:38 402 + 16| trial++ 403 + 17| return new Promise(() => {}) 404 + 18| }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 405 + | ^ 406 + 19| }) 407 + 20| 408 + 409 + Caused by: Error: Matcher did not succeed in time. 410 + ❯ basic.test.ts:15:3 411 + 412 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 413 + 414 + FAIL basic.test.ts > throwing 415 + Error: ALWAYS_THROWS 416 + ❯ basic.test.ts:26:38 417 + 24| trial++ 418 + 25| throw new Error("ALWAYS_THROWS") 419 + 26| }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 420 + | ^ 421 + 27| }) 422 + 28| 423 + 424 + Caused by: Error: Matcher did not succeed in time. 425 + ❯ basic.test.ts:23:3 426 + 427 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 428 + 429 + " 430 + `) 431 + expect(result.errorTree()).toMatchInlineSnapshot(` 432 + { 433 + "basic.test.ts": { 434 + "hanging": [ 435 + "poll() did not produce a stable snapshot within the timeout", 436 + ], 437 + "throwing": [ 438 + "ALWAYS_THROWS", 439 + ], 440 + "unstable": [ 441 + "poll() did not produce a stable snapshot within the timeout", 442 + ], 443 + }, 444 + } 445 + `) 446 + }) 447 + 448 + test('signal', async () => { 449 + const result = await runInlineTests({ 450 + 'basic.test.ts': ` 451 + import '../snapshots/fixtures/domain/basic-extend' 452 + 453 + test('signal', async () => { 454 + let aborted = false 455 + await expect( 456 + expect.poll(({ signal }) => { 457 + signal.addEventListener('abort', () => { 458 + aborted = true 459 + }) 460 + return new Promise(() => {}) 461 + }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 462 + ).rejects.toThrowErrorMatchingInlineSnapshot() 463 + expect(aborted).toMatchInlineSnapshot() 464 + }) 465 + `, 466 + }, { 467 + globals: true, 468 + update: 'all', 469 + }) 470 + expect(result.stderr).toMatchInlineSnapshot(`""`) 471 + expect(result.errorTree()).toMatchInlineSnapshot(` 472 + { 473 + "basic.test.ts": { 474 + "signal": "passed", 475 + }, 476 + } 477 + `) 478 + expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 479 + " 480 + import '../snapshots/fixtures/domain/basic-extend' 481 + 482 + test('signal', async () => { 483 + let aborted = false 484 + await expect( 485 + expect.poll(({ signal }) => { 486 + signal.addEventListener('abort', () => { 487 + aborted = true 488 + }) 489 + return new Promise(() => {}) 490 + }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 491 + ).rejects.toThrowErrorMatchingInlineSnapshot(\`[Error: poll() did not produce a stable snapshot within the timeout]\`) 492 + expect(aborted).toMatchInlineSnapshot(\`true\`) 493 + }) 494 + " 495 + `) 496 + })
+233
test/e2e/snapshots/domain.test.ts
··· 1 + import fs, { readFileSync } from 'node:fs' 2 + import { join } from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + 6 + test('domain snapshot', async () => { 7 + const root = join(import.meta.dirname, 'fixtures/domain') 8 + const testFile = join(root, 'basic.test.ts') 9 + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 10 + 11 + // clean slate 12 + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 13 + 14 + // create snapshots from scratch — literal rendered values 15 + let result = await runVitest({ root, update: 'new' }) 16 + expect(result.stderr).toMatchInlineSnapshot(`""`) 17 + expect(result.errorTree()).toMatchInlineSnapshot(` 18 + { 19 + "basic.test.ts": { 20 + "all literal": "passed", 21 + "empty snapshot": "passed", 22 + "with regex": "passed", 23 + }, 24 + } 25 + `) 26 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 27 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 28 + 29 + exports[\`all literal 1\`] = \` 30 + name=alice 31 + age=30 32 + \`; 33 + 34 + exports[\`empty snapshot 1\`] = \`\`; 35 + 36 + exports[\`with regex 1\`] = \` 37 + name=bob 38 + age=24 39 + score=999 40 + status=active 41 + \`; 42 + " 43 + `) 44 + 45 + // hand-edit snapshot 46 + editFile(snapshotFile, s => s 47 + // match any numbers match for score 48 + .replace('score=999', 'score=/\\\\d+/') 49 + .replace('age=24\n', '')) 50 + 51 + // re-run without update 52 + result = await runVitest({ root, update: 'none' }) 53 + expect(result.stderr).toMatchInlineSnapshot(`""`) 54 + expect(result.errorTree()).toMatchInlineSnapshot(` 55 + { 56 + "basic.test.ts": { 57 + "all literal": "passed", 58 + "empty snapshot": "passed", 59 + "with regex": "passed", 60 + }, 61 + } 62 + `) 63 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 64 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 65 + 66 + exports[\`all literal 1\`] = \` 67 + name=alice 68 + age=30 69 + \`; 70 + 71 + exports[\`empty snapshot 1\`] = \`\`; 72 + 73 + exports[\`with regex 1\`] = \` 74 + name=bob 75 + score=/\\\\d+/ 76 + status=active 77 + \`; 78 + " 79 + `) 80 + 81 + // edit test 82 + editFile(testFile, s => s 83 + .replace(`name: 'alice',`, ``) 84 + .replace(`score: '999'`, `score: '42'`) 85 + .replace(`status: 'active'`, `status: 'inactive'`)) 86 + 87 + // run without update 88 + // (note that `age` and `score` is not in diff) 89 + result = await runVitest({ root, update: 'none' }) 90 + expect(result.stderr).toMatchInlineSnapshot(` 91 + " 92 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 93 + 94 + FAIL basic.test.ts > all literal 95 + Error: Snapshot \`all literal 1\` mismatched 96 + 97 + - Expected 98 + + Received 99 + 100 + - name=alice 101 + age=30 102 + 103 + ❯ basic.test.ts:5:26 104 + 3| 105 + 4| test('all literal', () => { 106 + 5| expect({ age: '30' }).toMatchKvSnapshot() 107 + | ^ 108 + 6| }) 109 + 7| 110 + 111 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 112 + 113 + FAIL basic.test.ts > with regex 114 + Error: Snapshot \`with regex 1\` mismatched 115 + 116 + - Expected 117 + + Received 118 + 119 + name=bob 120 + score=/\\d+/ 121 + - status=active 122 + + status=inactive 123 + 124 + ❯ basic.test.ts:9:71 125 + 7| 126 + 8| test('with regex', () => { 127 + 9| expect({ name: 'bob', age: '24', score: '42', status: 'inactive' }).… 128 + | ^ 129 + 10| }) 130 + 11| 131 + 132 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 133 + 134 + " 135 + `) 136 + expect(result.errorTree()).toMatchInlineSnapshot(` 137 + { 138 + "basic.test.ts": { 139 + "all literal": [ 140 + "Snapshot \`all literal 1\` mismatched", 141 + ], 142 + "empty snapshot": "passed", 143 + "with regex": [ 144 + "Snapshot \`with regex 1\` mismatched", 145 + ], 146 + }, 147 + } 148 + `) 149 + 150 + // run with update — should preserve score regex (matched), 151 + // overwrite status with literal (didn't match) 152 + result = await runVitest({ root, update: 'all' }) 153 + expect(result.stderr).toMatchInlineSnapshot(`""`) 154 + expect(result.errorTree()).toMatchInlineSnapshot(` 155 + { 156 + "basic.test.ts": { 157 + "all literal": "passed", 158 + "empty snapshot": "passed", 159 + "with regex": "passed", 160 + }, 161 + } 162 + `) 163 + // NOTE 164 + // score regex matched '42' -> preserved as /\d+/ 165 + // status literal 'active' != 'inactive' -> overwritten with literal 166 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 167 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 168 + 169 + exports[\`all literal 1\`] = \` 170 + age=30 171 + \`; 172 + 173 + exports[\`empty snapshot 1\`] = \`\`; 174 + 175 + exports[\`with regex 1\`] = \` 176 + name=bob 177 + score=/\\\\d+/ 178 + status=inactive 179 + \`; 180 + " 181 + `) 182 + }) 183 + 184 + test('domain parseExpected error', async () => { 185 + const root = join(import.meta.dirname, 'fixtures/domain-error') 186 + const result = await runVitest({ root, update: 'none' }) 187 + expect(result.stderr).toMatchInlineSnapshot(` 188 + " 189 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 190 + 191 + FAIL basic.test.ts > file 192 + Error: Invalid KV Format: 'file-broken' 193 + ❯ ../domain/basic.ts:38:15 194 + 36| const eq = line.indexOf('=') 195 + 37| if (eq === -1) { 196 + 38| throw new Error(\`Invalid KV Format: '\${line}'\`) 197 + | ^ 198 + 39| } 199 + 40| const key = line.slice(0, eq) 200 + ❯ Object.parseExpected ../domain/basic.ts:35:46 201 + ❯ Object.toMatchKvSnapshot ../domain/basic-extend.ts:16:44 202 + 203 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 204 + 205 + FAIL basic.test.ts > inline 206 + Error: Invalid KV Format: 'inine-broken' 207 + ❯ ../domain/basic.ts:38:15 208 + 36| const eq = line.indexOf('=') 209 + 37| if (eq === -1) { 210 + 38| throw new Error(\`Invalid KV Format: '\${line}'\`) 211 + | ^ 212 + 39| } 213 + 40| const key = line.slice(0, eq) 214 + ❯ Object.parseExpected ../domain/basic.ts:35:46 215 + ❯ Object.toMatchKvInlineSnapshot ../domain/basic-extend.ts:22:50 216 + 217 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 218 + 219 + " 220 + `) 221 + expect(result.errorTree()).toMatchInlineSnapshot(` 222 + { 223 + "basic.test.ts": { 224 + "file": [ 225 + "Invalid KV Format: 'file-broken'", 226 + ], 227 + "inline": [ 228 + "Invalid KV Format: 'inine-broken'", 229 + ], 230 + }, 231 + } 232 + `) 233 + })
+28
test/e2e/snapshots/file.test.ts
··· 1 + import { join } from 'node:path' 2 + import { expect, test } from 'vitest' 3 + import { editFile, runVitest } from '../../test-utils' 4 + 5 + test('white space sensitive', async () => { 6 + const root = join(import.meta.dirname, 'fixtures/file') 7 + 8 + // check correct snapshot 9 + let vitest = await runVitest({ root }) 10 + expect(vitest.exitCode).toBe(0) 11 + 12 + // check diff of wrong snapshot 13 + editFile(join(root, 'snapshot-1.txt'), s => s.trim()) 14 + editFile(join(root, 'snapshot-2.txt'), s => s.replace('echo', 'ECHO')) 15 + vitest = await runVitest({ root }) 16 + expect(vitest.stderr).toContain(` 17 + - white space 18 + + 19 + + 20 + + white space 21 + + 22 + `) 23 + expect(vitest.stderr).toContain(` 24 + - ECHO "hello" 25 + + echo "hello" 26 + `) 27 + expect(vitest.exitCode).toBe(1) 28 + })
+28
test/e2e/snapshots/indent.test.ts
··· 1 + import { join } from 'node:path' 2 + import { expect, test } from 'vitest' 3 + import { editFile, runVitest } from '../../test-utils' 4 + 5 + test('white space sensitive', async () => { 6 + const root = join(import.meta.dirname, 'fixtures/indent') 7 + 8 + // ensure correct snapshot 9 + let vitest = await runVitest({ root, update: true }) 10 + expect(vitest.exitCode).toBe(0) 11 + 12 + // check diff of wrong snapshot 13 + editFile(join(root, 'basic.test.ts'), s => s.replace('1111', 'aaaa').replace('2222', 'bbbb')) 14 + vitest = await runVitest({ root }) 15 + expect(vitest.stderr).toContain(` 16 + - 1111 17 + + aaaa 18 + xxxx { 19 + } 20 + `) 21 + expect(vitest.stderr).toContain(` 22 + - 2222 23 + + bbbb 24 + yyyy { 25 + } 26 + `) 27 + expect(vitest.exitCode).toBe(1) 28 + })
+725
test/e2e/snapshots/inline-multiple-calls.test.ts
··· 1 + import fs, { readFileSync } from 'node:fs' 2 + import { join } from 'pathe' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + 6 + // pnpm -C test/snapshots test:snaps inline-multiple-calls 7 + 8 + test('same snapshots in single test', async () => { 9 + // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls same.test 10 + 11 + // reset snapshot 12 + const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 13 + const testFile = join(root, 'same.test.ts') 14 + editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 15 + 16 + // initial run (create snapshot) 17 + let vitest = await runVitest({ 18 + root, 19 + include: [testFile], 20 + update: true, 21 + }) 22 + expect(vitest.stderr).toBe('') 23 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 24 + { 25 + "added": 2, 26 + "didUpdate": true, 27 + "failure": false, 28 + "filesAdded": 1, 29 + "filesRemoved": 0, 30 + "filesRemovedList": [], 31 + "filesUnmatched": 0, 32 + "filesUpdated": 0, 33 + "matched": 0, 34 + "total": 2, 35 + "unchecked": 0, 36 + "uncheckedKeysByFile": [], 37 + "unmatched": 0, 38 + "updated": 0, 39 + } 40 + `) 41 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 42 + 43 + // no-update run 44 + vitest = await runVitest({ 45 + root, 46 + include: [testFile], 47 + update: false, 48 + }) 49 + expect(vitest.stderr).toBe('') 50 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 51 + { 52 + "added": 0, 53 + "didUpdate": false, 54 + "failure": false, 55 + "filesAdded": 0, 56 + "filesRemoved": 0, 57 + "filesRemovedList": [], 58 + "filesUnmatched": 0, 59 + "filesUpdated": 0, 60 + "matched": 2, 61 + "total": 2, 62 + "unchecked": 0, 63 + "uncheckedKeysByFile": [], 64 + "unmatched": 0, 65 + "updated": 0, 66 + } 67 + `) 68 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 69 + 70 + // update run 71 + vitest = await runVitest({ 72 + root, 73 + include: [testFile], 74 + update: true, 75 + }) 76 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 77 + { 78 + "added": 0, 79 + "didUpdate": true, 80 + "failure": false, 81 + "filesAdded": 0, 82 + "filesRemoved": 0, 83 + "filesRemovedList": [], 84 + "filesUnmatched": 0, 85 + "filesUpdated": 0, 86 + "matched": 2, 87 + "total": 2, 88 + "unchecked": 0, 89 + "uncheckedKeysByFile": [], 90 + "unmatched": 0, 91 + "updated": 0, 92 + } 93 + `) 94 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 95 + }) 96 + 97 + test('same snapshots in multiple tests', async () => { 98 + // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls same2.test 99 + 100 + // reset snapshot 101 + const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 102 + const testFile = join(root, 'same2.test.ts') 103 + editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 104 + 105 + // initial run (create snapshot) 106 + let vitest = await runVitest({ 107 + root, 108 + include: [testFile], 109 + update: true, 110 + }) 111 + expect(vitest.stderr).toBe('') 112 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 113 + { 114 + "added": 2, 115 + "didUpdate": true, 116 + "failure": false, 117 + "filesAdded": 1, 118 + "filesRemoved": 0, 119 + "filesRemovedList": [], 120 + "filesUnmatched": 0, 121 + "filesUpdated": 0, 122 + "matched": 0, 123 + "total": 2, 124 + "unchecked": 0, 125 + "uncheckedKeysByFile": [], 126 + "unmatched": 0, 127 + "updated": 0, 128 + } 129 + `) 130 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 131 + 132 + // no-update run 133 + vitest = await runVitest({ 134 + root, 135 + include: [testFile], 136 + update: false, 137 + }) 138 + expect(vitest.stderr).toBe('') 139 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 140 + { 141 + "added": 0, 142 + "didUpdate": false, 143 + "failure": false, 144 + "filesAdded": 0, 145 + "filesRemoved": 0, 146 + "filesRemovedList": [], 147 + "filesUnmatched": 0, 148 + "filesUpdated": 0, 149 + "matched": 2, 150 + "total": 2, 151 + "unchecked": 0, 152 + "uncheckedKeysByFile": [], 153 + "unmatched": 0, 154 + "updated": 0, 155 + } 156 + `) 157 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 158 + 159 + // update run 160 + vitest = await runVitest({ 161 + root, 162 + include: [testFile], 163 + update: true, 164 + }) 165 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 166 + { 167 + "added": 0, 168 + "didUpdate": true, 169 + "failure": false, 170 + "filesAdded": 0, 171 + "filesRemoved": 0, 172 + "filesRemovedList": [], 173 + "filesUnmatched": 0, 174 + "filesUpdated": 0, 175 + "matched": 2, 176 + "total": 2, 177 + "unchecked": 0, 178 + "uncheckedKeysByFile": [], 179 + "unmatched": 0, 180 + "updated": 0, 181 + } 182 + `) 183 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 184 + }) 185 + 186 + test('different snapshots in single test', async () => { 187 + // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls different.test 188 + 189 + // reset snapshot 190 + const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 191 + const testFile = join(root, 'different.test.ts') 192 + editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 193 + 194 + // update run should fail 195 + let vitest = await runVitest({ 196 + root, 197 + include: [testFile], 198 + update: true, 199 + }) 200 + expect(vitest.stderr).toContain(` 201 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 202 + 203 + Expected: ""test1"" 204 + Received: ""test2"" 205 + `) 206 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 207 + expect(vitest.exitCode).not.toBe(0) 208 + 209 + // no-update run should fail 210 + vitest = await runVitest({ 211 + root, 212 + include: [testFile], 213 + update: false, 214 + }) 215 + if (process.env.CI) { 216 + expect(vitest.stderr).toContain(` 217 + Error: Snapshot \`single 1\` mismatched 218 + `) 219 + } 220 + else { 221 + expect(vitest.stderr).toContain(` 222 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 223 + 224 + Expected: ""test1"" 225 + Received: ""test2"" 226 + `) 227 + } 228 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 229 + 230 + // current snapshot is "test1" 231 + editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot()', 'expect(value).toMatchInlineSnapshot(`"test1"`)')) 232 + vitest = await runVitest({ 233 + root, 234 + include: [testFile], 235 + update: true, 236 + }) 237 + expect(vitest.stderr).toContain(` 238 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 239 + 240 + Expected: ""test1"" 241 + Received: ""test2"" 242 + `) 243 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 244 + 245 + vitest = await runVitest({ 246 + root, 247 + include: [testFile], 248 + update: false, 249 + }) 250 + expect(vitest.stderr).toContain(` 251 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 252 + 253 + Expected: ""test1"" 254 + Received: ""test2"" 255 + `) 256 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 257 + 258 + // current snapshot is "test2" 259 + editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot(`"test1"`)', 'expect(value).toMatchInlineSnapshot(`"test2"`)')) 260 + vitest = await runVitest({ 261 + root, 262 + include: [testFile], 263 + update: true, 264 + }) 265 + expect(vitest.stderr).toContain(` 266 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 267 + 268 + Expected: ""test1"" 269 + Received: ""test2"" 270 + `) 271 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 272 + 273 + vitest = await runVitest({ 274 + root, 275 + include: [testFile], 276 + update: false, 277 + }) 278 + expect(vitest.stderr).toContain(` 279 + Error: Snapshot \`single 1\` mismatched 280 + 281 + Expected: ""test2"" 282 + Received: ""test1"" 283 + `) 284 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 285 + }) 286 + 287 + test('different snapshots in multiple tests', async () => { 288 + // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls different2.test 289 + 290 + // reset snapshot 291 + const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 292 + const testFile = join(root, 'different2.test.ts') 293 + editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 294 + 295 + // update run should fail 296 + let vitest = await runVitest({ 297 + root, 298 + include: [testFile], 299 + update: true, 300 + }) 301 + expect(vitest.stderr).toContain(` 302 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 303 + 304 + Expected: ""test1"" 305 + Received: ""test2"" 306 + `) 307 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 308 + expect(vitest.exitCode).not.toBe(0) 309 + 310 + // no-update run should fail 311 + vitest = await runVitest({ 312 + root, 313 + include: [testFile], 314 + update: false, 315 + }) 316 + if (process.env.CI) { 317 + expect(vitest.stderr).toContain(` 318 + Error: Snapshot \`a 1\` mismatched 319 + `) 320 + } 321 + else { 322 + expect(vitest.stderr).toContain(` 323 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 324 + 325 + Expected: ""test1"" 326 + Received: ""test2"" 327 + `) 328 + } 329 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 330 + 331 + // current snapshot is "test1" 332 + editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot()', 'expect(value).toMatchInlineSnapshot(`"test1"`)')) 333 + vitest = await runVitest({ 334 + root, 335 + include: [testFile], 336 + update: true, 337 + }) 338 + expect(vitest.stderr).toContain(` 339 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 340 + 341 + Expected: ""test1"" 342 + Received: ""test2"" 343 + `) 344 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 345 + 346 + vitest = await runVitest({ 347 + root, 348 + include: [testFile], 349 + update: false, 350 + }) 351 + expect(vitest.stderr).toContain(` 352 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 353 + 354 + Expected: ""test1"" 355 + Received: ""test2"" 356 + `) 357 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 358 + 359 + // current snapshot is "test2" 360 + editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot(`"test1"`)', 'expect(value).toMatchInlineSnapshot(`"test2"`)')) 361 + vitest = await runVitest({ 362 + root, 363 + include: [testFile], 364 + update: true, 365 + }) 366 + expect(vitest.stderr).toContain(` 367 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 368 + 369 + Expected: ""test1"" 370 + Received: ""test2"" 371 + `) 372 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 373 + 374 + vitest = await runVitest({ 375 + root, 376 + include: [testFile], 377 + update: false, 378 + }) 379 + expect(vitest.stderr).toContain(` 380 + Error: Snapshot \`a 1\` mismatched 381 + 382 + Expected: ""test2"" 383 + Received: ""test1"" 384 + `) 385 + expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 386 + }) 387 + 388 + test('test.each/for', async () => { 389 + const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 390 + const testFile = join(root, 'each.test.ts') 391 + 392 + // remove inline snapshots 393 + editFile(testFile, s => s 394 + .replace(/toMatchInlineSnapshot\(`[^`]*`\)/g, 'toMatchInlineSnapshot()') 395 + .replace(/toThrowErrorMatchingInlineSnapshot\(`[^`]*`\)/g, 'toThrowErrorMatchingInlineSnapshot()')) 396 + 397 + // create snapshots from scratch 398 + let result = await runVitest({ root, include: [testFile], update: 'new' }) 399 + expect(result.stderr).toMatchInlineSnapshot(`""`) 400 + expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 401 + "import { expect, test, describe } from "vitest"; 402 + 403 + test.for(["hello", "world"])("test %s", (arg) => { 404 + expect(arg.length).toMatchInlineSnapshot(\`5\`); 405 + }); 406 + 407 + describe.for(["hello", "world"])("suite %s", (arg) => { 408 + test("length", () => { 409 + expect(arg.length).toMatchInlineSnapshot(\`5\`); 410 + }); 411 + }); 412 + 413 + test.for(["hello", "world"])("toThrowErrorMatchingInlineSnapshot %s", (arg) => { 414 + expect(() => { 415 + throw new Error(\`length = \${arg.length}\`); 416 + }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 417 + }); 418 + " 419 + `) 420 + expect(result.errorTree()).toMatchInlineSnapshot(` 421 + { 422 + "each.test.ts": { 423 + "suite hello": { 424 + "length": "passed", 425 + }, 426 + "suite world": { 427 + "length": "passed", 428 + }, 429 + "test hello": "passed", 430 + "test world": "passed", 431 + "toThrowErrorMatchingInlineSnapshot hello": "passed", 432 + "toThrowErrorMatchingInlineSnapshot world": "passed", 433 + }, 434 + } 435 + `) 436 + expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 437 + { 438 + "added": 6, 439 + "didUpdate": false, 440 + "failure": false, 441 + "filesAdded": 1, 442 + "filesRemoved": 0, 443 + "filesRemovedList": [], 444 + "filesUnmatched": 0, 445 + "filesUpdated": 0, 446 + "matched": 0, 447 + "total": 6, 448 + "unchecked": 0, 449 + "uncheckedKeysByFile": [], 450 + "unmatched": 0, 451 + "updated": 0, 452 + } 453 + `) 454 + 455 + // edit tests to introduce errors 456 + editFile(testFile, s => s.replaceAll(`"hello"`, `"hey"`)) 457 + 458 + // fails with update=false 459 + result = await runVitest({ root, include: [testFile], update: false }) 460 + expect(result.stderr).toMatchInlineSnapshot(` 461 + " 462 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯ 463 + 464 + FAIL each.test.ts > test hey 465 + Error: Snapshot \`test hey 1\` mismatched 466 + 467 + Expected: "5" 468 + Received: "3" 469 + 470 + ❯ each.test.ts:4:22 471 + 2| 472 + 3| test.for(["hey", "world"])("test %s", (arg) => { 473 + 4| expect(arg.length).toMatchInlineSnapshot(\`5\`); 474 + | ^ 475 + 5| }); 476 + 6| 477 + 478 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ 479 + 480 + FAIL each.test.ts > test world 481 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 482 + 483 + Expected: "3" 484 + Received: "5" 485 + 486 + ❯ each.test.ts:4:22 487 + 2| 488 + 3| test.for(["hey", "world"])("test %s", (arg) => { 489 + 4| expect(arg.length).toMatchInlineSnapshot(\`5\`); 490 + | ^ 491 + 5| }); 492 + 6| 493 + 494 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ 495 + 496 + FAIL each.test.ts > suite hey > length 497 + Error: Snapshot \`suite hey > length 1\` mismatched 498 + 499 + Expected: "5" 500 + Received: "3" 501 + 502 + ❯ each.test.ts:9:24 503 + 7| describe.for(["hey", "world"])("suite %s", (arg) => { 504 + 8| test("length", () => { 505 + 9| expect(arg.length).toMatchInlineSnapshot(\`5\`); 506 + | ^ 507 + 10| }); 508 + 11| }); 509 + 510 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ 511 + 512 + FAIL each.test.ts > suite world > length 513 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 514 + 515 + Expected: "3" 516 + Received: "5" 517 + 518 + ❯ each.test.ts:9:24 519 + 7| describe.for(["hey", "world"])("suite %s", (arg) => { 520 + 8| test("length", () => { 521 + 9| expect(arg.length).toMatchInlineSnapshot(\`5\`); 522 + | ^ 523 + 10| }); 524 + 11| }); 525 + 526 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ 527 + 528 + FAIL each.test.ts > toThrowErrorMatchingInlineSnapshot hey 529 + Error: Snapshot \`toThrowErrorMatchingInlineSnapshot hey 1\` mismatched 530 + 531 + Expected: "[Error: length = 5]" 532 + Received: "[Error: length = 3]" 533 + 534 + ❯ each.test.ts:16:6 535 + 14| expect(() => { 536 + 15| throw new Error(\`length = \${arg.length}\`); 537 + 16| }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 538 + | ^ 539 + 17| }); 540 + 18| 541 + 542 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ 543 + 544 + FAIL each.test.ts > toThrowErrorMatchingInlineSnapshot world 545 + Error: toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location 546 + 547 + Expected: "[Error: length = 3]" 548 + Received: "[Error: length = 5]" 549 + 550 + ❯ each.test.ts:16:6 551 + 14| expect(() => { 552 + 15| throw new Error(\`length = \${arg.length}\`); 553 + 16| }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 554 + | ^ 555 + 17| }); 556 + 18| 557 + 558 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯ 559 + 560 + " 561 + `) 562 + expect(result.errorTree()).toMatchInlineSnapshot(` 563 + { 564 + "each.test.ts": { 565 + "suite hey": { 566 + "length": [ 567 + "Snapshot \`suite hey > length 1\` mismatched", 568 + ], 569 + }, 570 + "suite world": { 571 + "length": [ 572 + "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 573 + ], 574 + }, 575 + "test hey": [ 576 + "Snapshot \`test hey 1\` mismatched", 577 + ], 578 + "test world": [ 579 + "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 580 + ], 581 + "toThrowErrorMatchingInlineSnapshot hey": [ 582 + "Snapshot \`toThrowErrorMatchingInlineSnapshot hey 1\` mismatched", 583 + ], 584 + "toThrowErrorMatchingInlineSnapshot world": [ 585 + "toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location", 586 + ], 587 + }, 588 + } 589 + `) 590 + expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 591 + { 592 + "added": 0, 593 + "didUpdate": false, 594 + "failure": false, 595 + "filesAdded": 0, 596 + "filesRemoved": 0, 597 + "filesRemovedList": [], 598 + "filesUnmatched": 1, 599 + "filesUpdated": 0, 600 + "matched": 0, 601 + "total": 3, 602 + "unchecked": 0, 603 + "uncheckedKeysByFile": [], 604 + "unmatched": 3, 605 + "updated": 0, 606 + } 607 + `) 608 + 609 + // fails with update=all 610 + result = await runVitest({ root, include: [testFile], update: 'all' }) 611 + expect(result.stderr).toMatchInlineSnapshot(` 612 + " 613 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 614 + 615 + FAIL each.test.ts > test world 616 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 617 + 618 + Expected: "3" 619 + Received: "5" 620 + 621 + ❯ each.test.ts:4:22 622 + 2| 623 + 3| test.for(["hey", "world"])("test %s", (arg) => { 624 + 4| expect(arg.length).toMatchInlineSnapshot(\`5\`); 625 + | ^ 626 + 5| }); 627 + 6| 628 + 629 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 630 + 631 + FAIL each.test.ts > suite world > length 632 + Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 633 + 634 + Expected: "3" 635 + Received: "5" 636 + 637 + ❯ each.test.ts:9:24 638 + 7| describe.for(["hey", "world"])("suite %s", (arg) => { 639 + 8| test("length", () => { 640 + 9| expect(arg.length).toMatchInlineSnapshot(\`5\`); 641 + | ^ 642 + 10| }); 643 + 11| }); 644 + 645 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 646 + 647 + FAIL each.test.ts > toThrowErrorMatchingInlineSnapshot world 648 + Error: toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location 649 + 650 + Expected: "[Error: length = 3]" 651 + Received: "[Error: length = 5]" 652 + 653 + ❯ each.test.ts:16:6 654 + 14| expect(() => { 655 + 15| throw new Error(\`length = \${arg.length}\`); 656 + 16| }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 657 + | ^ 658 + 17| }); 659 + 18| 660 + 661 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 662 + 663 + " 664 + `) 665 + expect(result.errorTree()).toMatchInlineSnapshot(` 666 + { 667 + "each.test.ts": { 668 + "suite hey": { 669 + "length": "passed", 670 + }, 671 + "suite world": { 672 + "length": [ 673 + "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 674 + ], 675 + }, 676 + "test hey": "passed", 677 + "test world": [ 678 + "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 679 + ], 680 + "toThrowErrorMatchingInlineSnapshot hey": "passed", 681 + "toThrowErrorMatchingInlineSnapshot world": [ 682 + "toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location", 683 + ], 684 + }, 685 + } 686 + `) 687 + expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 688 + "import { expect, test, describe } from "vitest"; 689 + 690 + test.for(["hey", "world"])("test %s", (arg) => { 691 + expect(arg.length).toMatchInlineSnapshot(\`5\`); 692 + }); 693 + 694 + describe.for(["hey", "world"])("suite %s", (arg) => { 695 + test("length", () => { 696 + expect(arg.length).toMatchInlineSnapshot(\`5\`); 697 + }); 698 + }); 699 + 700 + test.for(["hey", "world"])("toThrowErrorMatchingInlineSnapshot %s", (arg) => { 701 + expect(() => { 702 + throw new Error(\`length = \${arg.length}\`); 703 + }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 704 + }); 705 + " 706 + `) 707 + expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 708 + { 709 + "added": 0, 710 + "didUpdate": true, 711 + "failure": false, 712 + "filesAdded": 0, 713 + "filesRemoved": 0, 714 + "filesRemovedList": [], 715 + "filesUnmatched": 0, 716 + "filesUpdated": 1, 717 + "matched": 0, 718 + "total": 3, 719 + "unchecked": 0, 720 + "uncheckedKeysByFile": [], 721 + "unmatched": 0, 722 + "updated": 3, 723 + } 724 + `) 725 + })
+62
test/e2e/snapshots/jest-image-snapshot.test.ts
··· 1 + import fs from 'node:fs' 2 + import { join } from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { runVitest } from '../../test-utils' 5 + 6 + test('jest-image-snapshot', async () => { 7 + // cleanup snapshot 8 + const root = join(import.meta.dirname, 'fixtures/jest-image-snapshot') 9 + fs.rmSync(join(root, '__image_snapshots__'), { recursive: true, force: true }) 10 + 11 + // write snapshot 12 + let vitest = await runVitest({ 13 + root, 14 + update: true, 15 + }) 16 + expect(vitest.stderr).toBe('') 17 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 18 + { 19 + "added": 1, 20 + "didUpdate": true, 21 + "failure": false, 22 + "filesAdded": 1, 23 + "filesRemoved": 0, 24 + "filesRemovedList": [], 25 + "filesUnmatched": 0, 26 + "filesUpdated": 0, 27 + "matched": 0, 28 + "total": 1, 29 + "unchecked": 0, 30 + "uncheckedKeysByFile": [], 31 + "unmatched": 0, 32 + "updated": 0, 33 + } 34 + `) 35 + expect(fs.existsSync(join(root, '__image_snapshots__/basic-test-ts-to-match-image-snapshot-1-snap.png'))).toBe(true) 36 + 37 + // match existing snapshot 38 + vitest = await runVitest({ 39 + root, 40 + update: false, 41 + }) 42 + expect(vitest.stderr).toBe('') 43 + expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 44 + { 45 + "added": 0, 46 + "didUpdate": false, 47 + "failure": false, 48 + "filesAdded": 0, 49 + "filesRemoved": 0, 50 + "filesRemovedList": [], 51 + "filesUnmatched": 0, 52 + "filesUpdated": 0, 53 + "matched": 1, 54 + "total": 1, 55 + "unchecked": 0, 56 + "uncheckedKeysByFile": [], 57 + "unmatched": 0, 58 + "updated": 0, 59 + } 60 + `) 61 + expect(fs.existsSync(join(root, '__image_snapshots__/basic-test-ts-to-match-image-snapshot-1-snap.png'))).toBe(true) 62 + })
+68
test/e2e/snapshots/obsolete.test.ts
··· 1 + import fs from 'node:fs' 2 + import path from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { runVitest } from '../../test-utils' 5 + 6 + test('obsolete snapshot fails with update:none', async () => { 7 + // cleanup snapshot 8 + const root = path.join(import.meta.dirname, 'fixtures/obsolete') 9 + fs.rmSync(path.join(root, 'src/__snapshots__'), { recursive: true, force: true }) 10 + 11 + // initial run to write snapshot 12 + let result = await runVitest({ root, update: true }) 13 + expect(result.stderr).toBe('') 14 + expect(result.errorTree()).toMatchInlineSnapshot(` 15 + { 16 + "src/test1.test.ts": { 17 + "bar": "passed", 18 + "foo": "passed", 19 + "fuu": "passed", 20 + }, 21 + "src/test2.test.ts": { 22 + "bar": "passed", 23 + "foo": "passed", 24 + }, 25 + } 26 + `) 27 + 28 + // test fails with obsolete snapshots 29 + result = await runVitest({ 30 + root, 31 + update: 'none', 32 + env: { 33 + TEST_OBSOLETE: 'true', 34 + }, 35 + }) 36 + expect(result.stderr).toMatchInlineSnapshot(` 37 + " 38 + ⎯⎯⎯⎯⎯⎯ Failed Suites 1 ⎯⎯⎯⎯⎯⎯⎯ 39 + 40 + FAIL src/test1.test.ts [ src/test1.test.ts ] 41 + Error: Obsolete snapshots found when no snapshot update is expected. 42 + · foo 1 43 + · fuu 1 44 + 45 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 46 + 47 + " 48 + `) 49 + expect(result.errorTree()).toMatchInlineSnapshot(` 50 + { 51 + "src/test1.test.ts": { 52 + "__module_errors__": [ 53 + "Obsolete snapshots found when no snapshot update is expected. 54 + · foo 1 55 + · fuu 1 56 + ", 57 + ], 58 + "bar": "passed", 59 + "foo": "passed", 60 + "fuu": "passed", 61 + }, 62 + "src/test2.test.ts": { 63 + "bar": "passed", 64 + "foo": "passed", 65 + }, 66 + } 67 + `) 68 + })
+80
test/e2e/snapshots/options.test.ts
··· 1 + import { describe, expect, test } from 'vitest' 2 + import { runInlineTests } from '../../test-utils' 3 + 4 + describe('maxOutputLength', () => { 5 + test('default', async () => { 6 + const result = await runInlineTests( 7 + { 8 + 'basic.test.ts': ` 9 + import { expect, test } from 'vitest' 10 + 11 + test('large snapshot', () => { 12 + expect(Array.from({ length: 500_000 }, (_, i) => ({ i }))).toMatchSnapshot() 13 + }) 14 + `, 15 + }, 16 + { 17 + update: 'all', 18 + }, 19 + ) 20 + 21 + expect(result.stderr).toMatchInlineSnapshot(`""`) 22 + const snapshot = result.fs.readFile('__snapshots__/basic.test.ts.snap') 23 + expect(snapshot.slice(-50)).toMatchInlineSnapshot(` 24 + " "i": 499998, 25 + }, 26 + { 27 + "i": 499999, 28 + }, 29 + ] 30 + \`; 31 + " 32 + `) 33 + expect(snapshot.length).toMatchInlineSnapshot(`12888992`) 34 + }) 35 + 36 + test('override', async () => { 37 + const result = await runInlineTests( 38 + { 39 + 'basic.test.ts': ` 40 + import { expect, test } from 'vitest' 41 + 42 + test('large snapshot', () => { 43 + expect(Array.from({ length: 8 }, (_, i) => ({ i }))).toMatchSnapshot() 44 + }) 45 + `, 46 + }, 47 + { 48 + update: 'all', 49 + snapshotFormat: { 50 + maxOutputLength: 50, 51 + }, 52 + }, 53 + ) 54 + 55 + expect(result.stderr).toMatchInlineSnapshot(`""`) 56 + expect(result.fs.readFile('__snapshots__/basic.test.ts.snap')).toMatchInlineSnapshot(` 57 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 58 + 59 + exports[\`large snapshot 1\`] = \` 60 + [ 61 + { 62 + "i": 0, 63 + }, 64 + { 65 + "i": 1, 66 + }, 67 + { 68 + "i": 2, 69 + }, 70 + [Object], 71 + [Object], 72 + [Object], 73 + [Object], 74 + [Object], 75 + ] 76 + \`; 77 + " 78 + `) 79 + }) 80 + })
+324
test/e2e/snapshots/properties.test.ts
··· 1 + import fs, { readFileSync } from 'node:fs' 2 + import { join } from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + 6 + const INLINE_BLOCK_RE = /\/\/ -- TEST INLINE START --\n([\s\S]*?)\/\/ -- TEST INLINE END --/g 7 + 8 + function extractInlineBlocks(content: string): string { 9 + return [...content.matchAll(INLINE_BLOCK_RE)].map(m => m[1].trim()).join('\n\n') 10 + } 11 + 12 + test('toMatchSnapshot and toMatchInlineSnapshot with properties', async () => { 13 + const root = join(import.meta.dirname, 'fixtures/properties') 14 + const testFile = join(root, 'basic.test.ts') 15 + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 16 + 17 + // remove snapshots 18 + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 19 + editFile(testFile, s => 20 + s.replace(/toMatchInlineSnapshot\((\{[^}]*\}),\s*`[^`]*`\)/g, 'toMatchInlineSnapshot($1)')) 21 + 22 + // create snapshots from scratch 23 + let result = await runVitest({ root, update: 'new' }) 24 + expect(result.stderr).toMatchInlineSnapshot(`""`) 25 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 26 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 27 + 28 + exports[\`file 1\`] = \` 29 + { 30 + "age": Any<Number>, 31 + "name": "alice", 32 + } 33 + \`; 34 + 35 + exports[\`file asymmetric 1\`] = \` 36 + { 37 + "name": "bob", 38 + "score": toSatisfy<[Function lessThan100]>, 39 + } 40 + \`; 41 + 42 + exports[\`file snapshot-only 1\`] = \` 43 + { 44 + "age": Any<Number>, 45 + "name": "dave", 46 + } 47 + \`; 48 + " 49 + `) 50 + expect(extractInlineBlocks(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 51 + "test("inline", () => { 52 + expect({ name: "carol", age: 25 }).toMatchInlineSnapshot({ age: expect.any(Number) }, \` 53 + { 54 + "age": Any<Number>, 55 + "name": "carol", 56 + } 57 + \`); 58 + });" 59 + `) 60 + expect(result.errorTree()).toMatchInlineSnapshot(` 61 + { 62 + "basic.test.ts": { 63 + "file": "passed", 64 + "file asymmetric": "passed", 65 + "file snapshot-only": "passed", 66 + "inline": "passed", 67 + }, 68 + } 69 + `) 70 + 71 + // verify idempotency — re-run without update passes cleanly 72 + const result2 = await runVitest({ root, update: 'none' }) 73 + expect(result2.stderr).toMatchInlineSnapshot(`""`) 74 + expect(result2.errorTree()).toEqual(result.errorTree()) 75 + 76 + // edit tests to break properties check 77 + editFile(testFile, s => 78 + s 79 + .replace('age: 30', 'age: \'thirty\'') 80 + .replace('score: 95', 'score: 999') 81 + .replace('name: "dave"', 'name: "dave-edit"') 82 + .replace('age: 25', 'age: \'twenty-five\'')) 83 + 84 + // properties mismatch should NOT cause false-positive obsolete snapshot 85 + result = await runVitest({ root, update: 'none' }) 86 + expect(result.stderr).toMatchInlineSnapshot(` 87 + " 88 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 4 ⎯⎯⎯⎯⎯⎯⎯ 89 + 90 + FAIL basic.test.ts > file 91 + Error: Snapshot properties mismatched 92 + 93 + - Expected 94 + + Received 95 + 96 + { 97 + - "age": Any<Number>, 98 + + "age": "thirty", 99 + + "name": "alice", 100 + } 101 + 102 + ❯ basic.test.ts:4:44 103 + 2| 104 + 3| test("file", () => { 105 + 4| expect({ name: "alice", age: 'thirty' }).toMatchSnapshot({ age: expe… 106 + | ^ 107 + 5| }); 108 + 6| 109 + 110 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯ 111 + 112 + FAIL basic.test.ts > file asymmetric 113 + Error: Snapshot properties mismatched 114 + 115 + - Expected 116 + + Received 117 + 118 + { 119 + - "score": toSatisfy<[Function lessThan100]>, 120 + + "name": "bob", 121 + + "score": 999, 122 + } 123 + 124 + ❯ basic.test.ts:8:39 125 + 6| 126 + 7| test("file asymmetric", () => { 127 + 8| expect({ name: "bob", score: 999 }).toMatchSnapshot({ 128 + | ^ 129 + 9| score: expect.toSatisfy(function lessThan100(n) { 130 + 10| return n < 100; 131 + 132 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/4]⎯ 133 + 134 + FAIL basic.test.ts > file snapshot-only 135 + Error: Snapshot \`file snapshot-only 1\` mismatched 136 + 137 + - Expected 138 + + Received 139 + 140 + { 141 + "age": Any<Number>, 142 + - "name": "dave", 143 + + "name": "dave-edit", 144 + } 145 + 146 + ❯ basic.test.ts:16:42 147 + 14| 148 + 15| test("file snapshot-only", () => { 149 + 16| expect({ name: "dave-edit", age: 42 }).toMatchSnapshot({ age: expect… 150 + | ^ 151 + 17| }); 152 + 18| 153 + 154 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/4]⎯ 155 + 156 + FAIL basic.test.ts > inline 157 + Error: Snapshot properties mismatched 158 + 159 + - Expected 160 + + Received 161 + 162 + { 163 + - "age": Any<Number>, 164 + + "age": "twenty-five", 165 + + "name": "carol", 166 + } 167 + 168 + ❯ basic.test.ts:21:49 169 + 19| // -- TEST INLINE START -- 170 + 20| test("inline", () => { 171 + 21| expect({ name: "carol", age: 'twenty-five' }).toMatchInlineSnapshot(… 172 + | ^ 173 + 22| { 174 + 23| "age": Any<Number>, 175 + 176 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/4]⎯ 177 + 178 + " 179 + `) 180 + expect(result.errorTree()).toMatchInlineSnapshot(` 181 + { 182 + "basic.test.ts": { 183 + "file": [ 184 + "Snapshot properties mismatched", 185 + ], 186 + "file asymmetric": [ 187 + "Snapshot properties mismatched", 188 + ], 189 + "file snapshot-only": [ 190 + "Snapshot \`file snapshot-only 1\` mismatched", 191 + ], 192 + "inline": [ 193 + "Snapshot properties mismatched", 194 + ], 195 + }, 196 + } 197 + `) 198 + 199 + // run with update — properties errors persist 200 + result = await runVitest({ root, update: 'all' }) 201 + expect(result.stderr).toMatchInlineSnapshot(` 202 + " 203 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 204 + 205 + FAIL basic.test.ts > file 206 + Error: Snapshot properties mismatched 207 + 208 + - Expected 209 + + Received 210 + 211 + { 212 + - "age": Any<Number>, 213 + + "age": "thirty", 214 + + "name": "alice", 215 + } 216 + 217 + ❯ basic.test.ts:4:44 218 + 2| 219 + 3| test("file", () => { 220 + 4| expect({ name: "alice", age: 'thirty' }).toMatchSnapshot({ age: expe… 221 + | ^ 222 + 5| }); 223 + 6| 224 + 225 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 226 + 227 + FAIL basic.test.ts > file asymmetric 228 + Error: Snapshot properties mismatched 229 + 230 + - Expected 231 + + Received 232 + 233 + { 234 + - "score": toSatisfy<[Function lessThan100]>, 235 + + "name": "bob", 236 + + "score": 999, 237 + } 238 + 239 + ❯ basic.test.ts:8:39 240 + 6| 241 + 7| test("file asymmetric", () => { 242 + 8| expect({ name: "bob", score: 999 }).toMatchSnapshot({ 243 + | ^ 244 + 9| score: expect.toSatisfy(function lessThan100(n) { 245 + 10| return n < 100; 246 + 247 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 248 + 249 + FAIL basic.test.ts > inline 250 + Error: Snapshot properties mismatched 251 + 252 + - Expected 253 + + Received 254 + 255 + { 256 + - "age": Any<Number>, 257 + + "age": "twenty-five", 258 + + "name": "carol", 259 + } 260 + 261 + ❯ basic.test.ts:21:49 262 + 19| // -- TEST INLINE START -- 263 + 20| test("inline", () => { 264 + 21| expect({ name: "carol", age: 'twenty-five' }).toMatchInlineSnapshot(… 265 + | ^ 266 + 22| { 267 + 23| "age": Any<Number>, 268 + 269 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 270 + 271 + " 272 + `) 273 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 274 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 275 + 276 + exports[\`file 1\`] = \` 277 + { 278 + "age": Any<Number>, 279 + "name": "alice", 280 + } 281 + \`; 282 + 283 + exports[\`file asymmetric 1\`] = \` 284 + { 285 + "name": "bob", 286 + "score": toSatisfy<[Function lessThan100]>, 287 + } 288 + \`; 289 + 290 + exports[\`file snapshot-only 1\`] = \` 291 + { 292 + "age": Any<Number>, 293 + "name": "dave-edit", 294 + } 295 + \`; 296 + " 297 + `) 298 + expect(extractInlineBlocks(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 299 + "test("inline", () => { 300 + expect({ name: "carol", age: 'twenty-five' }).toMatchInlineSnapshot({ age: expect.any(Number) }, \` 301 + { 302 + "age": Any<Number>, 303 + "name": "carol", 304 + } 305 + \`); 306 + });" 307 + `) 308 + expect(result.errorTree()).toMatchInlineSnapshot(` 309 + { 310 + "basic.test.ts": { 311 + "file": [ 312 + "Snapshot properties mismatched", 313 + ], 314 + "file asymmetric": [ 315 + "Snapshot properties mismatched", 316 + ], 317 + "file snapshot-only": "passed", 318 + "inline": [ 319 + "Snapshot properties mismatched", 320 + ], 321 + }, 322 + } 323 + `) 324 + })
+116
test/e2e/snapshots/skip-test.test.ts
··· 1 + import fs from 'node:fs' 2 + import path from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { runVitest } from '../../test-utils' 5 + 6 + test('snapshots in skipped test/suite is not obsolete', async () => { 7 + // create snapshot on first run 8 + const root = path.join(import.meta.dirname, 'fixtures/skip-test') 9 + 10 + fs.rmSync(path.join(root, '__snapshots__'), { recursive: true, force: true }) 11 + let vitest = await runVitest({ 12 + root, 13 + update: true, 14 + }) 15 + expect(vitest.stdout).toContain('Snapshots 2 written') 16 + expect(fs.readFileSync(path.join(root, '__snapshots__/repro.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 17 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 18 + 19 + exports[\`repro suite > inner case 1\`] = \`"hi-1"\`; 20 + 21 + exports[\`top-level case 1\`] = \`"hi-2"\`; 22 + " 23 + `) 24 + 25 + // running with `skipIf` enabled should not show "obsolete" 26 + vitest = await runVitest({ 27 + root, 28 + env: { 29 + ENABLE_SKIP: '1', 30 + }, 31 + }) 32 + expect(vitest.stdout).toContain('2 skipped') 33 + expect(vitest.stdout).not.toContain('obsolete') 34 + 35 + // running with `skipIf` and `update` should keep snapshots 36 + vitest = await runVitest({ 37 + root, 38 + update: true, 39 + env: { 40 + ENABLE_SKIP: '1', 41 + }, 42 + }) 43 + expect(fs.readFileSync(path.join(root, '__snapshots__/repro.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 44 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 45 + 46 + exports[\`repro suite > inner case 1\`] = \`"hi-1"\`; 47 + 48 + exports[\`top-level case 1\`] = \`"hi-2"\`; 49 + " 50 + `) 51 + }) 52 + 53 + test('handle obsoleteness of toMatchSnapshot("custom message")', async () => { 54 + const root = path.join(import.meta.dirname, './fixtures/skip-test-custom') 55 + 56 + // clear snapshots 57 + fs.rmSync(path.join(root, '__snapshots__'), { recursive: true, force: true }) 58 + 59 + // create snapshot on first run 60 + let vitest = await runVitest({ 61 + root, 62 + update: true, 63 + }) 64 + expect(vitest.stdout).toContain('Snapshots 4 written') 65 + expect(fs.readFileSync(path.join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 66 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 67 + 68 + exports[\`custom a > x 1\`] = \`0\`; 69 + 70 + exports[\`custom a > y 1\`] = \`0\`; 71 + 72 + exports[\`custom b > w 1\`] = \`0\`; 73 + 74 + exports[\`custom b > z 1\`] = \`0\`; 75 + " 76 + `) 77 + 78 + // Skipped tests' `toMatchSnapshot("...")` is not considered obsolete 79 + vitest = await runVitest({ 80 + root, 81 + testNamePattern: 'custom a', 82 + }) 83 + expect(vitest.stdout).toContain('1 passed') 84 + expect(vitest.stdout).toContain('1 skipped') 85 + expect(vitest.stdout).not.toContain('obsolete') 86 + 87 + vitest = await runVitest({ 88 + root, 89 + testNamePattern: 'custom b', 90 + }) 91 + expect(vitest.stdout).toContain('1 passed') 92 + expect(vitest.stdout).toContain('1 skipped') 93 + expect(vitest.stdout).not.toContain('obsolete') 94 + 95 + // check snapshot doesn't change when skip + update 96 + vitest = await runVitest({ 97 + root, 98 + update: true, 99 + testNamePattern: 'custom a', 100 + }) 101 + expect(vitest.stdout).toContain('1 passed') 102 + expect(vitest.stdout).toContain('1 skipped') 103 + expect(vitest.stdout).not.toContain('obsolete') 104 + expect(fs.readFileSync(path.join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 105 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 106 + 107 + exports[\`custom a > x 1\`] = \`0\`; 108 + 109 + exports[\`custom a > y 1\`] = \`0\`; 110 + 111 + exports[\`custom b > w 1\`] = \`0\`; 112 + 113 + exports[\`custom b > z 1\`] = \`0\`; 114 + " 115 + `) 116 + })
+121
test/e2e/snapshots/snapshots.test.ts
··· 1 + import { join } from 'node:path' 2 + import { expect, test } from 'vitest' 3 + 4 + import { editFile, runInlineTests, runVitest } from '../../test-utils' 5 + 6 + test('non default snapshot format', () => { 7 + expect({ foo: ['bar'] }).toMatchInlineSnapshot(` 8 + { 9 + "foo": [ 10 + "bar", 11 + ], 12 + } 13 + `) 14 + }) 15 + 16 + test('--update works for workspace project', async () => { 17 + // setup wrong snapshot value 18 + editFile( 19 + join(import.meta.dirname, 'fixtures/workspace/packages/space/test/__snapshots__/basic.test.ts.snap'), 20 + data => data.replace('`1`', '`2`'), 21 + ) 22 + 23 + // run with --update 24 + const { stdout, exitCode } = await runVitest({ 25 + update: true, 26 + root: join(import.meta.dirname, 'fixtures/workspace'), 27 + }) 28 + expect.soft(stdout).include('Snapshots 1 updated') 29 + expect.soft(exitCode).toBe(0) 30 + }) 31 + 32 + test('test.fails fails snapshot', async () => { 33 + const result = await runInlineTests({ 34 + 'basic.test.ts': ` 35 + import { expect, test } from 'vitest' 36 + 37 + test.fails('file', () => { 38 + expect('a').toMatchSnapshot() 39 + }) 40 + 41 + test.fails('inline', () => { 42 + expect('b').toMatchInlineSnapshot() 43 + }) 44 + 45 + test.fails('soft', () => { 46 + expect.soft('c').toMatchSnapshot() 47 + expect.soft('d').toMatchInlineSnapshot() 48 + }) 49 + `, 50 + }) 51 + expect(result.stderr).toMatchInlineSnapshot(` 52 + " 53 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 54 + 55 + FAIL basic.test.ts > file 56 + TestSyntaxError: 'toMatchSnapshot' cannot be used with 'test.fails' 57 + ❯ basic.test.ts:5:15 58 + 3| 59 + 4| test.fails('file', () => { 60 + 5| expect('a').toMatchSnapshot() 61 + | ^ 62 + 6| }) 63 + 7| 64 + 65 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯ 66 + 67 + FAIL basic.test.ts > inline 68 + TestSyntaxError: 'toMatchInlineSnapshot' cannot be used with 'test.fails' 69 + ❯ basic.test.ts:9:15 70 + 7| 71 + 8| test.fails('inline', () => { 72 + 9| expect('b').toMatchInlineSnapshot() 73 + | ^ 74 + 10| }) 75 + 11| 76 + 77 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/4]⎯ 78 + 79 + FAIL basic.test.ts > soft 80 + TestSyntaxError: 'toMatchSnapshot' cannot be used with 'test.fails' 81 + ❯ basic.test.ts:13:20 82 + 11| 83 + 12| test.fails('soft', () => { 84 + 13| expect.soft('c').toMatchSnapshot() 85 + | ^ 86 + 14| expect.soft('d').toMatchInlineSnapshot() 87 + 15| }) 88 + 89 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/4]⎯ 90 + 91 + FAIL basic.test.ts > soft 92 + TestSyntaxError: 'toMatchInlineSnapshot' cannot be used with 'test.fails' 93 + ❯ basic.test.ts:14:20 94 + 12| test.fails('soft', () => { 95 + 13| expect.soft('c').toMatchSnapshot() 96 + 14| expect.soft('d').toMatchInlineSnapshot() 97 + | ^ 98 + 15| }) 99 + 16| 100 + 101 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/4]⎯ 102 + 103 + " 104 + `) 105 + expect(result.errorTree()).toMatchInlineSnapshot(` 106 + { 107 + "basic.test.ts": { 108 + "file": [ 109 + "'toMatchSnapshot' cannot be used with 'test.fails'", 110 + ], 111 + "inline": [ 112 + "'toMatchInlineSnapshot' cannot be used with 'test.fails'", 113 + ], 114 + "soft": [ 115 + "'toMatchSnapshot' cannot be used with 'test.fails'", 116 + "'toMatchInlineSnapshot' cannot be used with 'test.fails'", 117 + ], 118 + }, 119 + } 120 + `) 121 + })
+89
test/e2e/snapshots/soft-inline.test.ts
··· 1 + import { readFileSync } from 'node:fs' 2 + import { join } from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + 6 + test('soft inline', async () => { 7 + const root = join(import.meta.dirname, 'fixtures/soft-inline') 8 + const testFile = join(root, 'basic.test.ts') 9 + 10 + // remove inline snapshots 11 + editFile(testFile, s => s 12 + .replace(/toMatchInlineSnapshot\(`[^`]*`\)/g, 'toMatchInlineSnapshot()') 13 + .replace(/toThrowErrorMatchingInlineSnapshot\(`[^`]*`\)/g, 'toThrowErrorMatchingInlineSnapshot()')) 14 + 15 + // create snapshots from scratch 16 + let result = await runVitest({ root, update: 'new' }) 17 + expect(result.stderr).toMatchInlineSnapshot(`""`) 18 + expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 19 + "import { expect, test } from 'vitest' 20 + 21 + test('toMatchInlineSnapshot', () => { 22 + expect.soft('--snap-1--').toMatchInlineSnapshot(\`"--snap-1--"\`) 23 + expect.soft('--snap-2--').toMatchInlineSnapshot(\`"--snap-2--"\`) 24 + }) 25 + 26 + test('toThrowErrorMatchingInlineSnapshot', () => { 27 + expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-1--]\`) 28 + expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-2--]\`) 29 + }) 30 + " 31 + `) 32 + expect(result.errorTree()).toMatchInlineSnapshot(` 33 + { 34 + "basic.test.ts": { 35 + "toMatchInlineSnapshot": "passed", 36 + "toThrowErrorMatchingInlineSnapshot": "passed", 37 + }, 38 + } 39 + `) 40 + 41 + // edit tests to introduce snapshot errors 42 + editFile(testFile, s => s 43 + .replace('expect.soft(\'--snap-1--\')', 'expect.soft(\'--snap-1-edit--\')') 44 + .replace('expect.soft(\'--snap-2--\')', 'expect.soft(\'--snap-2-edit--\')') 45 + .replace('new Error(\'--error-1--\')', 'new Error(\'--error-1-edit--\')') 46 + .replace('new Error(\'--error-2--\')', 'new Error(\'--error-2-edit--\')')) 47 + 48 + result = await runVitest({ root, update: false }) 49 + expect(result.errorTree()).toMatchInlineSnapshot(` 50 + { 51 + "basic.test.ts": { 52 + "toMatchInlineSnapshot": [ 53 + "Snapshot \`toMatchInlineSnapshot 1\` mismatched", 54 + "Snapshot \`toMatchInlineSnapshot 2\` mismatched", 55 + ], 56 + "toThrowErrorMatchingInlineSnapshot": [ 57 + "Snapshot \`toThrowErrorMatchingInlineSnapshot 1\` mismatched", 58 + "Snapshot \`toThrowErrorMatchingInlineSnapshot 2\` mismatched", 59 + ], 60 + }, 61 + } 62 + `) 63 + 64 + // run with update 65 + result = await runVitest({ root, update: 'all' }) 66 + expect(result.stderr).toMatchInlineSnapshot(`""`) 67 + expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 68 + "import { expect, test } from 'vitest' 69 + 70 + test('toMatchInlineSnapshot', () => { 71 + expect.soft('--snap-1-edit--').toMatchInlineSnapshot(\`"--snap-1-edit--"\`) 72 + expect.soft('--snap-2-edit--').toMatchInlineSnapshot(\`"--snap-2-edit--"\`) 73 + }) 74 + 75 + test('toThrowErrorMatchingInlineSnapshot', () => { 76 + expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-1-edit--]\`) 77 + expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-2-edit--]\`) 78 + }) 79 + " 80 + `) 81 + expect(result.errorTree()).toMatchInlineSnapshot(` 82 + { 83 + "basic.test.ts": { 84 + "toMatchInlineSnapshot": "passed", 85 + "toThrowErrorMatchingInlineSnapshot": "passed", 86 + }, 87 + } 88 + `) 89 + })
+200
test/e2e/snapshots/soft.test.ts
··· 1 + import fs, { readFileSync } from 'node:fs' 2 + import { join } from 'node:path' 3 + import { expect, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + 6 + test('soft', async () => { 7 + const root = join(import.meta.dirname, 'fixtures/soft') 8 + const testFile = join(root, 'basic.test.ts') 9 + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 10 + const customFile1 = join(root, '__snapshots__/custom1.txt') 11 + const customFile2 = join(root, '__snapshots__/custom2.txt') 12 + 13 + // remove snapshots 14 + fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 15 + 16 + // create snapshots from scratch 17 + let result = await runVitest({ root, update: 'new' }) 18 + expect(result.stderr).toMatchInlineSnapshot(`""`) 19 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 20 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 21 + 22 + exports[\`toMatchSnapshot 1\`] = \`"--snap-1--"\`; 23 + 24 + exports[\`toMatchSnapshot 2\`] = \`"--snap-2--"\`; 25 + 26 + exports[\`toThrowErrorMatchingSnapshot 1\`] = \`[Error: --error-1--]\`; 27 + 28 + exports[\`toThrowErrorMatchingSnapshot 2\`] = \`[Error: --error-2--]\`; 29 + " 30 + `) 31 + expect(readFileSync(customFile1, 'utf-8')).toMatchInlineSnapshot(`"--file-1--"`) 32 + expect(readFileSync(customFile2, 'utf-8')).toMatchInlineSnapshot(`"--file-2--"`) 33 + expect(result.errorTree()).toMatchInlineSnapshot(` 34 + { 35 + "basic.test.ts": { 36 + "toMatchFileSnapshot": "passed", 37 + "toMatchSnapshot": "passed", 38 + "toThrowErrorMatchingSnapshot": "passed", 39 + }, 40 + } 41 + `) 42 + 43 + // edit tests to introduce snapshot errors 44 + editFile(testFile, s => s 45 + .replace(`--snap-1--`, `--snap-1-edit--`) 46 + .replace(`--snap-2--`, `--snap-2-edit--`) 47 + .replace(`--file-1--`, `--file-1-edit--`) 48 + .replace(`--file-2--`, `--file-2-edit--`) 49 + .replace(`--error-1--`, `--error-1-edit--`) 50 + .replace(`--error-2--`, `--error-2-edit--`)) 51 + 52 + result = await runVitest({ root, update: false }) 53 + expect(result.stderr).toMatchInlineSnapshot(` 54 + " 55 + ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 56 + 57 + FAIL basic.test.ts > toMatchSnapshot 58 + Error: Snapshot \`toMatchSnapshot 1\` mismatched 59 + 60 + Expected: ""--snap-1--"" 61 + Received: ""--snap-1-edit--"" 62 + 63 + ❯ basic.test.ts:4:34 64 + 2| 65 + 3| test('toMatchSnapshot', () => { 66 + 4| expect.soft('--snap-1-edit--').toMatchSnapshot() 67 + | ^ 68 + 5| expect.soft('--snap-2-edit--').toMatchSnapshot() 69 + 6| }) 70 + 71 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ 72 + 73 + FAIL basic.test.ts > toMatchSnapshot 74 + Error: Snapshot \`toMatchSnapshot 2\` mismatched 75 + 76 + Expected: ""--snap-2--"" 77 + Received: ""--snap-2-edit--"" 78 + 79 + ❯ basic.test.ts:5:34 80 + 3| test('toMatchSnapshot', () => { 81 + 4| expect.soft('--snap-1-edit--').toMatchSnapshot() 82 + 5| expect.soft('--snap-2-edit--').toMatchSnapshot() 83 + | ^ 84 + 6| }) 85 + 7| 86 + 87 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ 88 + 89 + FAIL basic.test.ts > toMatchFileSnapshot 90 + Error: Snapshot \`toMatchFileSnapshot 1\` mismatched 91 + 92 + Expected: "--file-1--" 93 + Received: "--file-1-edit--" 94 + 95 + ❯ basic.test.ts:9:3 96 + 7| 97 + 8| test('toMatchFileSnapshot', async () => { 98 + 9| await expect.soft('--file-1-edit--').toMatchFileSnapshot('./__snapsh… 99 + | ^ 100 + 10| await expect.soft('--file-2-edit--').toMatchFileSnapshot('./__snapsh… 101 + 11| }) 102 + 103 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ 104 + 105 + FAIL basic.test.ts > toMatchFileSnapshot 106 + Error: Snapshot \`toMatchFileSnapshot 2\` mismatched 107 + 108 + Expected: "--file-2--" 109 + Received: "--file-2-edit--" 110 + 111 + ❯ basic.test.ts:10:3 112 + 8| test('toMatchFileSnapshot', async () => { 113 + 9| await expect.soft('--file-1-edit--').toMatchFileSnapshot('./__snapsh… 114 + 10| await expect.soft('--file-2-edit--').toMatchFileSnapshot('./__snapsh… 115 + | ^ 116 + 11| }) 117 + 12| 118 + 119 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ 120 + 121 + FAIL basic.test.ts > toThrowErrorMatchingSnapshot 122 + Error: Snapshot \`toThrowErrorMatchingSnapshot 1\` mismatched 123 + 124 + Expected: "[Error: --error-1--]" 125 + Received: "[Error: --error-1-edit--]" 126 + 127 + ❯ basic.test.ts:14:62 128 + 12| 129 + 13| test('toThrowErrorMatchingSnapshot', () => { 130 + 14| expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowEr… 131 + | ^ 132 + 15| expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowEr… 133 + 16| }) 134 + 135 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ 136 + 137 + FAIL basic.test.ts > toThrowErrorMatchingSnapshot 138 + Error: Snapshot \`toThrowErrorMatchingSnapshot 2\` mismatched 139 + 140 + Expected: "[Error: --error-2--]" 141 + Received: "[Error: --error-2-edit--]" 142 + 143 + ❯ basic.test.ts:15:62 144 + 13| test('toThrowErrorMatchingSnapshot', () => { 145 + 14| expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowEr… 146 + 15| expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowEr… 147 + | ^ 148 + 16| }) 149 + 17| 150 + 151 + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯ 152 + 153 + " 154 + `) 155 + expect(result.errorTree()).toMatchInlineSnapshot(` 156 + { 157 + "basic.test.ts": { 158 + "toMatchFileSnapshot": [ 159 + "Snapshot \`toMatchFileSnapshot 1\` mismatched", 160 + "Snapshot \`toMatchFileSnapshot 2\` mismatched", 161 + ], 162 + "toMatchSnapshot": [ 163 + "Snapshot \`toMatchSnapshot 1\` mismatched", 164 + "Snapshot \`toMatchSnapshot 2\` mismatched", 165 + ], 166 + "toThrowErrorMatchingSnapshot": [ 167 + "Snapshot \`toThrowErrorMatchingSnapshot 1\` mismatched", 168 + "Snapshot \`toThrowErrorMatchingSnapshot 2\` mismatched", 169 + ], 170 + }, 171 + } 172 + `) 173 + 174 + // run with update 175 + result = await runVitest({ root, update: 'all' }) 176 + expect(result.stderr).toMatchInlineSnapshot(`""`) 177 + expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 178 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 179 + 180 + exports[\`toMatchSnapshot 1\`] = \`"--snap-1-edit--"\`; 181 + 182 + exports[\`toMatchSnapshot 2\`] = \`"--snap-2-edit--"\`; 183 + 184 + exports[\`toThrowErrorMatchingSnapshot 1\`] = \`[Error: --error-1-edit--]\`; 185 + 186 + exports[\`toThrowErrorMatchingSnapshot 2\`] = \`[Error: --error-2-edit--]\`; 187 + " 188 + `) 189 + expect(readFileSync(customFile1, 'utf-8')).toMatchInlineSnapshot(`"--file-1-edit--"`) 190 + expect(readFileSync(customFile2, 'utf-8')).toMatchInlineSnapshot(`"--file-2-edit--"`) 191 + expect(result.errorTree()).toMatchInlineSnapshot(` 192 + { 193 + "basic.test.ts": { 194 + "toMatchFileSnapshot": "passed", 195 + "toMatchSnapshot": "passed", 196 + "toThrowErrorMatchingSnapshot": "passed", 197 + }, 198 + } 199 + `) 200 + })
+93
test/e2e/snapshots/summary.test.ts
··· 1 + import fs from 'node:fs' 2 + import { join } from 'node:path' 3 + import { assert, expect, onTestFailed, onTestFinished, test } from 'vitest' 4 + import { editFile, runVitest } from '../../test-utils' 5 + 6 + function fsUpdate(file: string, updateFn: (data: string) => string) { 7 + fs.writeFileSync(file, updateFn(fs.readFileSync(file, 'utf-8'))) 8 + } 9 + 10 + test('summary', async () => { 11 + // cleanup snapshot 12 + const dir = join(import.meta.dirname, 'fixtures/summary') 13 + const testFile = join(dir, 'basic.test.ts') 14 + const snapshotFile = join(dir, '__snapshots__/basic.test.ts.snap') 15 + fsUpdate(testFile, s => s.replace(/`"@SNAP\d"`/g, '')) 16 + fs.rmSync(snapshotFile, { recursive: true, force: true }) 17 + 18 + // write everything 19 + let vitest = await runVitest({ 20 + root: dir, 21 + update: true, 22 + }) 23 + expect(vitest.stdout).toContain('Snapshots 12 written') 24 + 25 + // write partially 26 + fsUpdate(testFile, s => s.replace('`"@SNAP2"`', '')) 27 + fsUpdate(snapshotFile, s => s.replace('exports[`file repeats 1`] = `"@SNAP5"`;', '')) 28 + vitest = await runVitest({ 29 + root: dir, 30 + update: true, 31 + }) 32 + expect(vitest.stdout).toContain('Snapshots 2 written') 33 + 34 + // update partially 35 + fsUpdate(testFile, s => s.replace('`"@SNAP2"`', '`"@WRONG"`')) 36 + fsUpdate(snapshotFile, s => s.replace('`"@SNAP5"`', '`"@WRONG"`')) 37 + vitest = await runVitest({ 38 + root: dir, 39 + update: true, 40 + }) 41 + expect(vitest.stdout).toContain('Snapshots 2 updated') 42 + }) 43 + 44 + test('first obsolete then remove', async () => { 45 + const root = join(import.meta.dirname, 'fixtures/summary-removed') 46 + const testFile = join(root, 'basic.test.ts') 47 + const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 48 + 49 + // reset snapshot 50 + fs.rmSync(snapshotFile, { recursive: true, force: true }) 51 + await runVitest({ 52 + root, 53 + update: true, 54 + }) 55 + expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 56 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 57 + 58 + exports[\`x 1\`] = \`0\`; 59 + 60 + exports[\`y 1\`] = \`0\`; 61 + " 62 + `) 63 + 64 + // watch run 65 + const { ctx, ...result } = await runVitest( 66 + { 67 + watch: true, 68 + root, 69 + }, 70 + ) 71 + assert(ctx) 72 + onTestFinished(() => { 73 + ctx.close() 74 + }) 75 + onTestFailed(() => { 76 + console.error(result.vitest.stdout) 77 + console.error(result.vitest.stderr) 78 + }) 79 + 80 + // remove `toMatchSnapshot()` and rerun -> obsolete snapshot 81 + editFile(testFile, s => s.replace(/REMOVE-START.*REMOVE-END/s, '')) 82 + await result.vitest.waitForStdout('1 obsolete') 83 + 84 + // rerun with update -> remove snapshot 85 + await ctx.updateSnapshot() 86 + await result.vitest.waitForStdout('1 removed') 87 + expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 88 + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 89 + 90 + exports[\`x 1\`] = \`0\`; 91 + " 92 + `) 93 + })
+87
test/e2e/snapshots/test-update.test.ts
··· 1 + import fs, { rmSync } from 'node:fs' 2 + import { join } from 'node:path' 3 + import { globSync } from 'tinyglobby' 4 + import { expect, test } from 'vitest' 5 + import { runVitest } from '../../test-utils' 6 + 7 + test('test update', async () => { 8 + // copy fixtures/test-update to fixtures/test-update-result 9 + const srcDir = join(import.meta.dirname, 'fixtures/test-update') 10 + const dstDir = join(import.meta.dirname, 'fixtures/test-update-result') 11 + rmSync(dstDir, { recursive: true }) 12 + fs.cpSync(srcDir, dstDir, { recursive: true }) 13 + 14 + // run and update snapshots 15 + const result = await runVitest({ root: dstDir, update: true }) 16 + expect(result.stderr).toMatchInlineSnapshot(`""`) 17 + expect(result.errorTree()).toMatchInlineSnapshot(` 18 + { 19 + "inline-concurrent.test.js": { 20 + "1st": "passed", 21 + "2nd": "passed", 22 + "3rd": "passed", 23 + }, 24 + "inline.test.js": { 25 + "snapshots are generated in correct order": { 26 + "first snapshot": "passed", 27 + "second snapshot": "passed", 28 + }, 29 + "snapshots with properties": { 30 + "mixed with and without snapshot": "passed", 31 + "with snapshot": "passed", 32 + "without snapshot": "passed", 33 + }, 34 + }, 35 + "retry-file.test.ts": { 36 + "file repeats": "passed", 37 + "file repeats many": "passed", 38 + "file retry": "passed", 39 + "file retry many": "passed", 40 + "file retry partial": "passed", 41 + }, 42 + "retry-inline.test.ts": { 43 + "inline repeats": "passed", 44 + "inline retry": "passed", 45 + }, 46 + "same-title-file.test.js": { 47 + "same title exist": "passed", 48 + "same title new": "passed", 49 + }, 50 + "same-title-inline.test.js": { 51 + "same title": "passed", 52 + }, 53 + } 54 + `) 55 + const resultFiles = readFiles(dstDir) 56 + expect(Object.keys(resultFiles)).toMatchInlineSnapshot(` 57 + [ 58 + "__snapshots__/retry-file.test.ts.snap", 59 + "__snapshots__/same-title-file.test.js.snap", 60 + "inline-concurrent.test.js", 61 + "inline.test.js", 62 + "retry-file.test.ts", 63 + "retry-inline.test.ts", 64 + "same-title-file.test.js", 65 + "same-title-inline.test.js", 66 + "vitest.config.ts", 67 + ] 68 + `) 69 + 70 + // re-run without update and files are unchanged 71 + const result2 = await runVitest({ root: dstDir, update: 'none' }) 72 + expect(result2.stderr).toMatchInlineSnapshot(`""`) 73 + expect(result2.errorTree()).toEqual(result.errorTree()) 74 + expect(readFiles(dstDir)).toEqual(resultFiles) 75 + 76 + const result3 = await runVitest({ root: dstDir, update: 'new' }) 77 + expect(result3.stderr).toMatchInlineSnapshot(`""`) 78 + expect(result3.errorTree()).toEqual(result.errorTree()) 79 + expect(readFiles(dstDir)).toEqual(resultFiles) 80 + }) 81 + 82 + function readFiles(dir: string) { 83 + const files = globSync('**', { cwd: dir, ignore: ['**/node_modules/**'] }) 84 + return Object.fromEntries( 85 + files.sort().map(file => [file, fs.readFileSync(join(dir, file), 'utf-8')]), 86 + ) 87 + }
+20
test/e2e/snapshots/utils.ts
··· 1 + import fs from 'node:fs' 2 + 3 + export function readInlineSnapshots(file: string) { 4 + return extractInlineSnaphsots(fs.readFileSync(file, 'utf-8')) 5 + } 6 + 7 + export function extractInlineSnaphsots(code: string) { 8 + const matches = Array.from( 9 + code.matchAll(/\.toMatch(\w*)InlineSnapshot\(\s*`[\s\S]*?`\s*\)/g), 10 + ) 11 + const snapshots = matches.map((match) => { 12 + const end = match.index! + match[0].length 13 + const start = code.lastIndexOf('expect', match.index) 14 + if (start === -1) { 15 + throw new Error(`Failed to extract inline snapshot: no expect found for match ${match[0]}`) 16 + } 17 + return code.slice(start, end) 18 + }) 19 + return `\n${snapshots.join('\n\n')}\n` 20 + }
+1
test/e2e/test/projects.test.ts
··· 120 120 121 121 it('fails if workspace is empty', async () => { 122 122 const { stderr } = await runVitest({ 123 + config: false, 123 124 projects: [], 124 125 }, [], { fails: true }) 125 126 expect(stderr).toContain('No projects were found. Make sure your configuration is correct. The projects definition: [].')
-54
test/snapshots/test/ci.test.ts
··· 1 - import fs from 'node:fs' 2 - import path from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { runVitestCli } from '../../test-utils' 5 - 6 - test('CI behavior', async () => { 7 - // cleanup snapshot 8 - const root = path.join(import.meta.dirname, 'fixtures/ci') 9 - fs.rmSync(path.join(root, '__snapshots__'), { recursive: true, force: true }) 10 - 11 - // snapshot fails with CI 12 - let result = await runVitestCli({ 13 - nodeOptions: { 14 - env: { 15 - CI: 'true', 16 - GITHUB_ACTIONS: 'true', 17 - }, 18 - }, 19 - }, '--root', root) 20 - expect(result.stderr).toMatchInlineSnapshot(` 21 - " 22 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 23 - 24 - FAIL basic.test.ts > basic 25 - Error: Snapshot \`basic 1\` mismatched 26 - ❯ basic.test.ts:4:16 27 - 2| 28 - 3| test("basic", () => { 29 - 4| expect("ok").toMatchSnapshot() 30 - | ^ 31 - 5| }) 32 - 6| 33 - 34 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 35 - 36 - " 37 - `) 38 - 39 - // snapshot created without CI 40 - result = await runVitestCli( 41 - { 42 - nodeOptions: { 43 - env: { 44 - CI: '', 45 - GITHUB_ACTIONS: '', 46 - }, 47 - }, 48 - }, 49 - '--root', 50 - root, 51 - ) 52 - expect(result.stderr).toMatchInlineSnapshot(`""`) 53 - expect(result.stdout).toContain('Snapshots 1 written') 54 - })
-85
test/snapshots/test/compare-keys.test.ts
··· 1 - import fs from 'node:fs' 2 - import { join } from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { runVitest } from '../../test-utils' 5 - 6 - test('compareKeys', async () => { 7 - const root = join(import.meta.dirname, 'fixtures/compare-keys') 8 - fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 9 - 10 - // compareKeys null 11 - let vitest = await runVitest({ 12 - root, 13 - update: true, 14 - snapshotFormat: { 15 - compareKeys: null, 16 - }, 17 - }) 18 - expect(vitest.stderr).toBe('') 19 - expect(fs.readFileSync(join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 20 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 21 - 22 - exports[\`compareKeys 1\`] = \` 23 - { 24 - "a": 1, 25 - "b": 2, 26 - "c": 3, 27 - } 28 - \`; 29 - 30 - exports[\`compareKeys 2\`] = \` 31 - { 32 - "c": 1, 33 - "b": 2, 34 - "a": 3, 35 - } 36 - \`; 37 - 38 - exports[\`compareKeys 3\`] = \` 39 - { 40 - "b": 1, 41 - "a": 2, 42 - "c": 3, 43 - } 44 - \`; 45 - " 46 - `) 47 - 48 - // compareKeys undefined 49 - vitest = await runVitest({ 50 - root, 51 - update: true, 52 - snapshotFormat: { 53 - compareKeys: undefined, 54 - }, 55 - }) 56 - expect(vitest.stderr).toBe('') 57 - expect(fs.readFileSync(join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 58 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 59 - 60 - exports[\`compareKeys 1\`] = \` 61 - { 62 - "a": 1, 63 - "b": 2, 64 - "c": 3, 65 - } 66 - \`; 67 - 68 - exports[\`compareKeys 2\`] = \` 69 - { 70 - "a": 3, 71 - "b": 2, 72 - "c": 1, 73 - } 74 - \`; 75 - 76 - exports[\`compareKeys 3\`] = \` 77 - { 78 - "a": 2, 79 - "b": 1, 80 - "c": 3, 81 - } 82 - \`; 83 - " 84 - `) 85 - })
-33
test/snapshots/test/custom-environment.test.ts
··· 1 - import { readFileSync, rmSync, writeFileSync } from 'node:fs' 2 - import { dirname, resolve } from 'pathe' 3 - import { afterEach, expect, test } from 'vitest' 4 - import { runVitest } from '../../test-utils' 5 - 6 - const testFileName = resolve(import.meta.dirname, './fixtures/custom-snapshot-environment/test/snapshots.test.ts') 7 - const snapshotFile = resolve(dirname(testFileName), './__snapshots__/snapshots.test.ts.snap') 8 - const testFile = readFileSync(testFileName, 'utf-8') 9 - 10 - afterEach(() => { 11 - writeFileSync(testFileName, testFile) 12 - rmSync(snapshotFile) 13 - }) 14 - 15 - test('custom environment resolved correctly', async () => { 16 - const { stdout, stderr } = await runVitest({ 17 - root: 'test/fixtures/custom-snapshot-environment', 18 - update: true, 19 - }) 20 - 21 - const snapshotLogs = stdout.split('\n').filter(i => i.startsWith('## ')).join('\n') 22 - expect(stderr).toBe('') 23 - expect(snapshotLogs).toMatchInlineSnapshot(` 24 - "## resolvePath test/fixtures/custom-snapshot-environment/test/snapshots.test.ts 25 - ## readSnapshotFile test/fixtures/custom-snapshot-environment/test/__snapshots__/snapshots.test.ts.snap 26 - ## getHeader 27 - ## getVersion 28 - ## readSnapshotFile test/fixtures/custom-snapshot-environment/test/__snapshots__/snapshots.test.ts.snap 29 - ## saveSnapshotFile test/fixtures/custom-snapshot-environment/test/__snapshots__/snapshots.test.ts.snap 30 - ## readSnapshotFile test/fixtures/custom-snapshot-environment/test/snapshots.test.ts 31 - ## saveSnapshotFile test/fixtures/custom-snapshot-environment/test/snapshots.test.ts" 32 - `) 33 - })
-556
test/snapshots/test/custom-matcher.test.ts
··· 1 - import fs, { readFileSync } from 'node:fs' 2 - import { join } from 'node:path' 3 - import { playwright } from '@vitest/browser-playwright' 4 - import { expect, test } from 'vitest' 5 - import { editFile, runInlineTests, runVitest } from '../../test-utils' 6 - import { extractInlineSnaphsots } from './utils' 7 - 8 - test('custom snapshot matcher', async () => { 9 - const root = join(import.meta.dirname, 'fixtures/custom-matcher') 10 - const testFile = join(root, 'basic.test.ts') 11 - const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 12 - const rawSnapshotFile = join(root, '__snapshots__/raw.txt') 13 - 14 - // remove snapshots 15 - fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 16 - editFile(testFile, s => s.replace(/toMatchCustomInlineSnapshot\(`[^`]*`\)/g, 'toMatchCustomInlineSnapshot()')) 17 - 18 - // create snapshots from scratch 19 - let result = await runVitest({ root, update: 'new' }) 20 - expect(result.stderr).toMatchInlineSnapshot(`""`) 21 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 22 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 23 - 24 - exports[\`file 1\`] = \` 25 - Object { 26 - "length": 6, 27 - "reversed": "ahahah", 28 - } 29 - \`; 30 - 31 - exports[\`properties 1 1\`] = \` 32 - Object { 33 - "length": 6, 34 - "reversed": "opopop", 35 - } 36 - \`; 37 - 38 - exports[\`properties 2 1\`] = \` 39 - Object { 40 - "length": toSatisfy<[Function lessThan10]>, 41 - "reversed": "epepep", 42 - } 43 - \`; 44 - " 45 - `) 46 - expect(readFileSync(rawSnapshotFile, 'utf-8')).toMatchInlineSnapshot(` 47 - "Object { 48 - "length": 6, 49 - "reversed": "ihihih", 50 - }" 51 - `) 52 - expect(extractInlineSnaphsots(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 53 - " 54 - expect(\`hehehe\`).toMatchCustomInlineSnapshot(\` 55 - Object { 56 - "length": 6, 57 - "reversed": "eheheh", 58 - } 59 - \`) 60 - 61 - expect(\`huhuhu\`).toMatchCustomAsyncInlineSnapshot(\` 62 - Object { 63 - "length": 6, 64 - "reversed": "uhuhuh", 65 - } 66 - \`) 67 - " 68 - `) 69 - expect(result.errorTree()).toMatchInlineSnapshot(` 70 - Object { 71 - "basic.test.ts": Object { 72 - "async inline": "passed", 73 - "file": "passed", 74 - "inline": "passed", 75 - "properties 1": "passed", 76 - "properties 2": "passed", 77 - "raw": "passed", 78 - }, 79 - } 80 - `) 81 - 82 - // edit tests to introduce snapshot errors 83 - editFile(testFile, s => s 84 - .replace('`hahaha`', '`hahaha-edit`') 85 - .replace('`popopo`', '`popopo-edit`') 86 - .replace('`pepepe`', '`pepepe-edit`') 87 - .replace('`hihihi`', '`hihihi-edit`') 88 - .replace('`huhuhu`', '`huhuhu-edit`') 89 - .replace('`hehehe`', '`hehehe-edit`')) 90 - 91 - result = await runVitest({ root, update: 'none' }) 92 - expect(result.stderr).toMatchInlineSnapshot(` 93 - " 94 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯ 95 - 96 - FAIL basic.test.ts > file 97 - Error: [custom error] Snapshot \`file 1\` mismatched 98 - 99 - - Expected 100 - + Received 101 - 102 - Object { 103 - - "length": 6, 104 - + "length": 11, 105 - - "reversed": "ahahah", 106 - + "reversed": "tide-ahahah", 107 - } 108 - 109 - ❯ basic.test.ts:66:25 110 - 64| 111 - 65| test('file', () => { 112 - 66| expect(\`hahaha-edit\`).toMatchCustomSnapshot() 113 - | ^ 114 - 67| }) 115 - 68| 116 - 117 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ 118 - 119 - FAIL basic.test.ts > properties 1 120 - Error: [custom error] Snapshot properties mismatched 121 - 122 - - Expected 123 - + Received 124 - 125 - { 126 - - "length": 6, 127 - + "length": 11, 128 - + "reversed": "tide-opopop", 129 - } 130 - 131 - ❯ basic.test.ts:70:25 132 - 68| 133 - 69| test('properties 1', () => { 134 - 70| expect(\`popopo-edit\`).toMatchCustomSnapshot({ length: 6 }) 135 - | ^ 136 - 71| }) 137 - 72| 138 - 139 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ 140 - 141 - FAIL basic.test.ts > properties 2 142 - Error: [custom error] Snapshot properties mismatched 143 - 144 - - Expected 145 - + Received 146 - 147 - { 148 - - "length": toSatisfy<[Function lessThan10]>, 149 - + "length": 11, 150 - + "reversed": "tide-epepep", 151 - } 152 - 153 - ❯ basic.test.ts:74:25 154 - 72| 155 - 73| test('properties 2', () => { 156 - 74| expect(\`pepepe-edit\`).toMatchCustomSnapshot({ length: expect.toSatis… 157 - | ^ 158 - 75| }) 159 - 76| 160 - 161 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ 162 - 163 - FAIL basic.test.ts > raw 164 - Error: [custom error] Snapshot \`raw 1\` mismatched 165 - 166 - - Expected 167 - + Received 168 - 169 - Object { 170 - - "length": 6, 171 - + "length": 11, 172 - - "reversed": "ihihih", 173 - + "reversed": "tide-ihihih", 174 - } 175 - 176 - ❯ basic.test.ts:78:3 177 - 76| 178 - 77| test('raw', async () => { 179 - 78| await expect(\`hihihi-edit\`).toMatchCustomFileSnapshot('./__snapshots… 180 - | ^ 181 - 79| }) 182 - 80| 183 - 184 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ 185 - 186 - FAIL basic.test.ts > inline 187 - Error: [custom error] Snapshot \`inline 1\` mismatched 188 - 189 - - Expected 190 - + Received 191 - 192 - Object { 193 - - "length": 6, 194 - + "length": 11, 195 - - "reversed": "eheheh", 196 - + "reversed": "tide-eheheh", 197 - } 198 - 199 - ❯ basic.test.ts:82:25 200 - 80| 201 - 81| test('inline', () => { 202 - 82| expect(\`hehehe-edit\`).toMatchCustomInlineSnapshot(\` 203 - | ^ 204 - 83| Object { 205 - 84| "length": 6, 206 - 207 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ 208 - 209 - FAIL basic.test.ts > async inline 210 - Error: [custom error] Snapshot \`async inline 1\` mismatched 211 - 212 - - Expected 213 - + Received 214 - 215 - Object { 216 - - "length": 6, 217 - + "length": 11, 218 - - "reversed": "uhuhuh", 219 - + "reversed": "tide-uhuhuh", 220 - } 221 - 222 - ❯ basic.test.ts:91:3 223 - 89| 224 - 90| test('async inline', async () => { 225 - 91| await expect(\`huhuhu-edit\`).toMatchCustomAsyncInlineSnapshot(\` 226 - | ^ 227 - 92| Object { 228 - 93| "length": 6, 229 - 230 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯ 231 - 232 - " 233 - `) 234 - expect(result.errorTree()).toMatchInlineSnapshot(` 235 - Object { 236 - "basic.test.ts": Object { 237 - "async inline": Array [ 238 - "[custom error] Snapshot \`async inline 1\` mismatched", 239 - ], 240 - "file": Array [ 241 - "[custom error] Snapshot \`file 1\` mismatched", 242 - ], 243 - "inline": Array [ 244 - "[custom error] Snapshot \`inline 1\` mismatched", 245 - ], 246 - "properties 1": Array [ 247 - "[custom error] Snapshot properties mismatched", 248 - ], 249 - "properties 2": Array [ 250 - "[custom error] Snapshot properties mismatched", 251 - ], 252 - "raw": Array [ 253 - "[custom error] Snapshot \`raw 1\` mismatched", 254 - ], 255 - }, 256 - } 257 - `) 258 - 259 - // run with update 260 - result = await runVitest({ root, update: 'all' }) 261 - expect(result.stderr).toMatchInlineSnapshot(` 262 - " 263 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 264 - 265 - FAIL basic.test.ts > properties 1 266 - Error: [custom error] Snapshot properties mismatched 267 - 268 - - Expected 269 - + Received 270 - 271 - { 272 - - "length": 6, 273 - + "length": 11, 274 - + "reversed": "tide-opopop", 275 - } 276 - 277 - ❯ basic.test.ts:70:25 278 - 68| 279 - 69| test('properties 1', () => { 280 - 70| expect(\`popopo-edit\`).toMatchCustomSnapshot({ length: 6 }) 281 - | ^ 282 - 71| }) 283 - 72| 284 - 285 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 286 - 287 - FAIL basic.test.ts > properties 2 288 - Error: [custom error] Snapshot properties mismatched 289 - 290 - - Expected 291 - + Received 292 - 293 - { 294 - - "length": toSatisfy<[Function lessThan10]>, 295 - + "length": 11, 296 - + "reversed": "tide-epepep", 297 - } 298 - 299 - ❯ basic.test.ts:74:25 300 - 72| 301 - 73| test('properties 2', () => { 302 - 74| expect(\`pepepe-edit\`).toMatchCustomSnapshot({ length: expect.toSatis… 303 - | ^ 304 - 75| }) 305 - 76| 306 - 307 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 308 - 309 - " 310 - `) 311 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 312 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 313 - 314 - exports[\`file 1\`] = \` 315 - Object { 316 - "length": 11, 317 - "reversed": "tide-ahahah", 318 - } 319 - \`; 320 - 321 - exports[\`properties 1 1\`] = \` 322 - Object { 323 - "length": 6, 324 - "reversed": "opopop", 325 - } 326 - \`; 327 - 328 - exports[\`properties 2 1\`] = \` 329 - Object { 330 - "length": toSatisfy<[Function lessThan10]>, 331 - "reversed": "epepep", 332 - } 333 - \`; 334 - " 335 - `) 336 - expect(readFileSync(rawSnapshotFile, 'utf-8')).toMatchInlineSnapshot(` 337 - "Object { 338 - "length": 11, 339 - "reversed": "tide-ihihih", 340 - }" 341 - `) 342 - expect(extractInlineSnaphsots(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 343 - " 344 - expect(\`hehehe-edit\`).toMatchCustomInlineSnapshot(\` 345 - Object { 346 - "length": 11, 347 - "reversed": "tide-eheheh", 348 - } 349 - \`) 350 - 351 - expect(\`huhuhu-edit\`).toMatchCustomAsyncInlineSnapshot(\` 352 - Object { 353 - "length": 11, 354 - "reversed": "tide-uhuhuh", 355 - } 356 - \`) 357 - " 358 - `) 359 - expect(result.errorTree()).toMatchInlineSnapshot(` 360 - Object { 361 - "basic.test.ts": Object { 362 - "async inline": "passed", 363 - "file": "passed", 364 - "inline": "passed", 365 - "properties 1": Array [ 366 - "[custom error] Snapshot properties mismatched", 367 - ], 368 - "properties 2": Array [ 369 - "[custom error] Snapshot properties mismatched", 370 - ], 371 - "raw": "passed", 372 - }, 373 - } 374 - `) 375 - }) 376 - 377 - test('browser', async () => { 378 - const result = await runInlineTests({ 379 - 'basic.test.ts': ` 380 - import { test, expect, Snapshots } from 'vitest' 381 - 382 - const { 383 - toMatchFileSnapshot, 384 - toMatchInlineSnapshot, 385 - toMatchSnapshot, 386 - } = Snapshots 387 - 388 - expect.extend({ 389 - toMatchTrimmedSnapshot(received: string) { 390 - return toMatchSnapshot.call(this, received.slice(0, 10)) 391 - }, 392 - toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) { 393 - return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot) 394 - }, 395 - async toMatchTrimmedFileSnapshot(received: string, filepath: string) { 396 - return toMatchFileSnapshot.call(this, received.slice(0, 10), filepath) 397 - }, 398 - }) 399 - 400 - test('file snapshot', () => { 401 - expect('extra long string oh my gerd').toMatchTrimmedSnapshot() 402 - }) 403 - 404 - test('inline snapshot', () => { 405 - expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot() 406 - }) 407 - 408 - test('raw file snapshot', async () => { 409 - await expect('crazy long string oh my gerd').toMatchTrimmedFileSnapshot('./raw.txt') 410 - }) 411 - `, 412 - }, { 413 - update: 'all', 414 - browser: { 415 - enabled: true, 416 - headless: true, 417 - screenshotFailures: false, 418 - provider: playwright(), 419 - instances: [ 420 - { 421 - browser: 'chromium', 422 - }, 423 - ], 424 - }, 425 - }) 426 - expect(result.stderr).toMatchInlineSnapshot(`""`) 427 - expect(result.errorTree()).toMatchInlineSnapshot(` 428 - Object { 429 - "basic.test.ts": Object { 430 - "file snapshot": "passed", 431 - "inline snapshot": "passed", 432 - "raw file snapshot": "passed", 433 - }, 434 - } 435 - `) 436 - expect(result.fs.readFile('__snapshots__/basic.test.ts.snap')).toMatchInlineSnapshot(` 437 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 438 - 439 - exports[\`file snapshot 1\`] = \`"extra long"\`; 440 - " 441 - `) 442 - expect(extractInlineSnaphsots(result.fs.readFile('basic.test.ts'))).toMatchInlineSnapshot(` 443 - " 444 - expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot(\`"super long"\`) 445 - " 446 - `) 447 - expect(result.fs.readFile('raw.txt')).toMatchInlineSnapshot(`"crazy long"`) 448 - }) 449 - 450 - test('outer expect message is prefixed by jest-extend for Snapshots wrappers', async () => { 451 - const result = await runInlineTests({ 452 - 'basic.test.ts': ` 453 - import { test, expect, Snapshots } from 'vitest' 454 - 455 - const { 456 - toMatchInlineSnapshot, 457 - } = Snapshots 458 - 459 - expect.extend({ 460 - toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) { 461 - return toMatchInlineSnapshot.call(this, received.slice(0, 5), inlineSnapshot) 462 - }, 463 - }) 464 - 465 - test('custom snapshot matcher', () => { 466 - expect('abcdefghij', 'outer message').toMatchTrimmedInlineSnapshot(\`"wrong"\`) 467 - }) 468 - 469 - test('builtin', () => { 470 - expect('abcdefghij', 'outer message').toMatchInlineSnapshot(\`"wrong"\`) 471 - }) 472 - 473 - test('builtin properties mismatch', () => { 474 - expect({ value: 1 }, 'outer message').toMatchSnapshot({ 475 - value: expect.any(String), 476 - }) 477 - }) 478 - `, 479 - }, { 480 - update: 'none', 481 - }) 482 - expect(result.stderr).toMatchInlineSnapshot(` 483 - " 484 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 485 - 486 - FAIL basic.test.ts > custom snapshot matcher 487 - Error: outer message: Snapshot \`custom snapshot matcher 1\` mismatched 488 - 489 - Expected: ""wrong"" 490 - Received: ""abcde"" 491 - 492 - ❯ basic.test.ts:15:41 493 - 13| 494 - 14| test('custom snapshot matcher', () => { 495 - 15| expect('abcdefghij', 'outer message').toMatchTrimmedInlineSnapshot(\`… 496 - | ^ 497 - 16| }) 498 - 17| 499 - 500 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 501 - 502 - FAIL basic.test.ts > builtin 503 - Error: outer message: Snapshot \`builtin 1\` mismatched 504 - 505 - Expected: ""wrong"" 506 - Received: ""abcdefghij"" 507 - 508 - ❯ basic.test.ts:19:41 509 - 17| 510 - 18| test('builtin', () => { 511 - 19| expect('abcdefghij', 'outer message').toMatchInlineSnapshot(\`"wrong"… 512 - | ^ 513 - 20| }) 514 - 21| 515 - 516 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 517 - 518 - FAIL basic.test.ts > builtin properties mismatch 519 - Error: outer message: Snapshot properties mismatched 520 - 521 - - Expected 522 - + Received 523 - 524 - { 525 - - "value": Any<String>, 526 - + "value": 1, 527 - } 528 - 529 - ❯ basic.test.ts:23:41 530 - 21| 531 - 22| test('builtin properties mismatch', () => { 532 - 23| expect({ value: 1 }, 'outer message').toMatchSnapshot({ 533 - | ^ 534 - 24| value: expect.any(String), 535 - 25| }) 536 - 537 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 538 - 539 - " 540 - `) 541 - expect(result.errorTree()).toMatchInlineSnapshot(` 542 - Object { 543 - "basic.test.ts": Object { 544 - "builtin": Array [ 545 - "outer message: Snapshot \`builtin 1\` mismatched", 546 - ], 547 - "builtin properties mismatch": Array [ 548 - "outer message: Snapshot properties mismatched", 549 - ], 550 - "custom snapshot matcher": Array [ 551 - "outer message: Snapshot \`custom snapshot matcher 1\` mismatched", 552 - ], 553 - }, 554 - } 555 - `) 556 - })
-137
test/snapshots/test/custom-serializers.test.ts
··· 1 - import fs from 'node:fs' 2 - import path from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - import { readInlineSnapshots } from './utils' 6 - 7 - test('it should pass', async () => { 8 - const { stdout, stderr } = await runVitest({ 9 - root: 'test/fixtures/custom-serializers', 10 - }) 11 - 12 - expect(stdout).toContain('✓ custom-serializers.test.ts') 13 - expect(stderr).toBe('') 14 - }) 15 - 16 - test('empty serializer output', async () => { 17 - const root = path.join(import.meta.dirname, 'fixtures/custom-serializers-empty') 18 - const testFile = path.join(root, 'basic.test.ts') 19 - const snapshotFile = path.join(root, '__snapshots__/basic.test.ts.snap') 20 - 21 - // clean slate 22 - fs.rmSync(path.join(root, '__snapshots__'), { recursive: true, force: true }) 23 - editFile(testFile, s => s 24 - .replace(/toMatchInlineSnapshot\(`[^`]*`/g, 'toMatchInlineSnapshot(')) 25 - 26 - let result = await runVitest({ 27 - root, 28 - update: 'all', 29 - }) 30 - expect(result.stderr).toMatchInlineSnapshot(`""`) 31 - expect(result.errorTree()).toMatchInlineSnapshot(` 32 - Object { 33 - "basic.test.ts": Object { 34 - "file empty": "passed", 35 - "file whitespaces": "passed", 36 - "inline empty": "passed", 37 - "inline whitespaces": "passed", 38 - }, 39 - } 40 - `) 41 - expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 42 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 43 - 44 - exports[\`file empty 1\`] = \`\`; 45 - 46 - exports[\`file whitespaces 1\`] = \` \`; 47 - " 48 - `) 49 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 50 - " 51 - expect({ __unwrap__: "" }).toMatchInlineSnapshot(\`\`) 52 - 53 - expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(\`\`) 54 - " 55 - `) 56 - 57 - result = await runVitest({ 58 - root, 59 - update: 'none', 60 - }) 61 - expect(result.stderr).toMatchInlineSnapshot(`""`) 62 - expect(result.errorTree()).toMatchInlineSnapshot(` 63 - Object { 64 - "basic.test.ts": Object { 65 - "file empty": "passed", 66 - "file whitespaces": "passed", 67 - "inline empty": "passed", 68 - "inline whitespaces": "passed", 69 - }, 70 - } 71 - `) 72 - 73 - // TODO: snapshot comparison normalizes whitespaces. probably hard to fix. 74 - editFile(testFile, s => s 75 - .replace(`__unwrap__: " ".repeat(4)`, `__unwrap__: " ".repeat(8)`)) 76 - result = await runVitest({ 77 - root, 78 - update: 'none', 79 - }) 80 - expect(result.stderr).toMatchInlineSnapshot(`""`) 81 - expect(result.errorTree()).toMatchInlineSnapshot(` 82 - Object { 83 - "basic.test.ts": Object { 84 - "file empty": "passed", 85 - "file whitespaces": "passed", 86 - "inline empty": "passed", 87 - "inline whitespaces": "passed", 88 - }, 89 - } 90 - `) 91 - expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 92 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 93 - 94 - exports[\`file empty 1\`] = \`\`; 95 - 96 - exports[\`file whitespaces 1\`] = \` \`; 97 - " 98 - `) 99 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 100 - " 101 - expect({ __unwrap__: "" }).toMatchInlineSnapshot(\`\`) 102 - 103 - expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(\`\`) 104 - " 105 - `) 106 - 107 - result = await runVitest({ 108 - root, 109 - update: 'all', 110 - }) 111 - expect(result.stderr).toMatchInlineSnapshot(`""`) 112 - expect(result.errorTree()).toMatchInlineSnapshot(` 113 - Object { 114 - "basic.test.ts": Object { 115 - "file empty": "passed", 116 - "file whitespaces": "passed", 117 - "inline empty": "passed", 118 - "inline whitespaces": "passed", 119 - }, 120 - } 121 - `) 122 - expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 123 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 124 - 125 - exports[\`file empty 1\`] = \`\`; 126 - 127 - exports[\`file whitespaces 1\`] = \` \`; 128 - " 129 - `) 130 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 131 - " 132 - expect({ __unwrap__: "" }).toMatchInlineSnapshot(\`\`) 133 - 134 - expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(\`\`) 135 - " 136 - `) 137 - })
-331
test/snapshots/test/domain-aria-inline.test.ts
··· 1 - import { join } from 'node:path' 2 - import { playwright } from '@vitest/browser-playwright' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runInlineTests, runVitest } from '../../test-utils' 5 - import { readInlineSnapshots } from './utils' 6 - 7 - test('aria inline snapshot', async () => { 8 - const root = join(import.meta.dirname, 'fixtures/domain-aria-inline') 9 - const testFile = join(root, 'basic.test.ts') 10 - 11 - // purge inline snapshots to empty strings, restore test values 12 - editFile(testFile, s => s 13 - .replace(/toMatchAriaInlineSnapshot\(`[^`]*`/g, 'toMatchAriaInlineSnapshot(')) 14 - 15 - // create snapshots from scratch 16 - let result = await runVitest({ root, update: 'new' }) 17 - expect(result.stderr).toMatchInlineSnapshot(`""`) 18 - expect(result.errorTree()).toMatchInlineSnapshot(` 19 - Object { 20 - "basic.test.ts": Object { 21 - "empty": "passed", 22 - "semantic match with regex in snapshot": "passed", 23 - "simple heading": "passed", 24 - }, 25 - } 26 - `) 27 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 28 - " 29 - expect(document.body).toMatchAriaInlineSnapshot(\` 30 - - heading "Hello World" [level=1] 31 - - paragraph: Some description 32 - \`) 33 - 34 - expect(document.body).toMatchAriaInlineSnapshot(\` 35 - - paragraph: Original 36 - - button "1234": Pattern 37 - \`) 38 - 39 - expect(document.body).toMatchAriaInlineSnapshot(\`\`) 40 - " 41 - `) 42 - expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 43 - Object { 44 - "added": 3, 45 - "didUpdate": false, 46 - "failure": false, 47 - "filesAdded": 1, 48 - "filesRemoved": 0, 49 - "filesRemovedList": Array [], 50 - "filesUnmatched": 0, 51 - "filesUpdated": 0, 52 - "matched": 0, 53 - "total": 3, 54 - "unchecked": 0, 55 - "uncheckedKeysByFile": Array [], 56 - "unmatched": 0, 57 - "updated": 0, 58 - } 59 - `) 60 - 61 - // hand-edit inline snapshot to introduce regex pattern 62 - // "1234" -> /\\d+/ 63 - editFile(testFile, s => s 64 - .replace(`- button "1234"`, '- button /\\\\d+/')) 65 - 66 - // run without update — regex matches, all pass 67 - result = await runVitest({ root, update: 'none' }) 68 - expect(result.stderr).toMatchInlineSnapshot(`""`) 69 - expect(result.errorTree()).toMatchInlineSnapshot(` 70 - Object { 71 - "basic.test.ts": Object { 72 - "empty": "passed", 73 - "semantic match with regex in snapshot": "passed", 74 - "simple heading": "passed", 75 - }, 76 - } 77 - `) 78 - 79 - // edit test 80 - editFile(testFile, s => s 81 - .replace('<p>Original</p>', '<p>Changed</p>') 82 - .replace(`aria-label="1234"`, `aria-label="9999"`)) 83 - 84 - // run without update — literal mismatch causes failure 85 - result = await runVitest({ root, update: 'none' }) 86 - expect(result.stderr).toMatchInlineSnapshot(` 87 - " 88 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 89 - 90 - FAIL |chromium| basic.test.ts > semantic match with regex in snapshot 91 - Error: Snapshot \`semantic match with regex in snapshot 1\` mismatched 92 - 93 - Failure screenshot: 94 - - test/fixtures/domain-aria-inline/__screenshots__/basic.test.ts/semantic-match-with-regex-in-snapshot-1.png 95 - 96 - - Expected 97 - + Received 98 - 99 - - - paragraph: Original 100 - + - paragraph: Changed 101 - - button /\\d+/: Pattern 102 - 103 - ❯ basic.test.ts:19:24 104 - 17| <button aria-label="9999">Pattern</button> 105 - 18| \` 106 - 19| expect(document.body).toMatchAriaInlineSnapshot(\` 107 - | ^ 108 - 20| - paragraph: Original 109 - 21| - button /\\\\d+/: Pattern 110 - 111 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 112 - 113 - " 114 - `) 115 - expect(result.errorTree()).toMatchInlineSnapshot(` 116 - Object { 117 - "basic.test.ts": Object { 118 - "empty": "passed", 119 - "semantic match with regex in snapshot": Array [ 120 - "Snapshot \`semantic match with regex in snapshot 1\` mismatched", 121 - ], 122 - "simple heading": "passed", 123 - }, 124 - } 125 - `) 126 - 127 - // run with update — should overwrite inline snapshot 128 - result = await runVitest({ root, update: 'all' }) 129 - expect(result.stderr).toMatchInlineSnapshot(`""`) 130 - expect(result.errorTree()).toMatchInlineSnapshot(` 131 - Object { 132 - "basic.test.ts": Object { 133 - "empty": "passed", 134 - "semantic match with regex in snapshot": "passed", 135 - "simple heading": "passed", 136 - }, 137 - } 138 - `) 139 - 140 - // verify inline snapshot in source was rewritten correctly 141 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 142 - " 143 - expect(document.body).toMatchAriaInlineSnapshot(\` 144 - - heading "Hello World" [level=1] 145 - - paragraph: Some description 146 - \`) 147 - 148 - expect(document.body).toMatchAriaInlineSnapshot(\` 149 - - paragraph: Changed 150 - - button /\\\\d+/: Pattern 151 - \`) 152 - 153 - expect(document.body).toMatchAriaInlineSnapshot(\`\`) 154 - " 155 - `) 156 - }) 157 - 158 - test('domain multiple inline at same location - success', async () => { 159 - const result = await runInlineTests({ 160 - 'basic.test.ts': ` 161 - import { expect, test } from 'vitest'; 162 - 163 - test('basic', () => { 164 - for (let i = 0; i < 3; i++) { 165 - document.body.innerHTML = "<p>OK</p>"; 166 - expect(document.body).toMatchAriaInlineSnapshot(); 167 - } 168 - }); 169 - `, 170 - }, { 171 - browser: { 172 - enabled: true, 173 - headless: true, 174 - provider: playwright(), 175 - instances: [ 176 - { 177 - browser: 'chromium', 178 - }, 179 - ], 180 - }, 181 - update: 'new', 182 - }) 183 - expect(result.stderr).toMatchInlineSnapshot(`""`) 184 - expect(result.errorTree()).toMatchInlineSnapshot(` 185 - Object { 186 - "basic.test.ts": Object { 187 - "basic": "passed", 188 - }, 189 - } 190 - `) 191 - expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 192 - " 193 - import { expect, test } from 'vitest'; 194 - 195 - test('basic', () => { 196 - for (let i = 0; i < 3; i++) { 197 - document.body.innerHTML = "<p>OK</p>"; 198 - expect(document.body).toMatchAriaInlineSnapshot(\`- paragraph: OK\`); 199 - } 200 - }); 201 - " 202 - `) 203 - }) 204 - 205 - test('domain multiple inline at same location - fail', async () => { 206 - const result = await runInlineTests({ 207 - 'basic.test.ts': ` 208 - import { expect, test } from 'vitest'; 209 - 210 - test('basic', () => { 211 - for (let i = 0; i < 3; i++) { 212 - document.body.innerHTML = "<p>count - " + i + "</p>"; 213 - expect(document.body).toMatchAriaInlineSnapshot(); 214 - } 215 - }); 216 - `, 217 - }, { 218 - browser: { 219 - enabled: true, 220 - headless: true, 221 - screenshotFailures: false, 222 - provider: playwright(), 223 - instances: [ 224 - { 225 - browser: 'chromium', 226 - }, 227 - ], 228 - }, 229 - update: 'new', 230 - }) 231 - expect(result.stderr).toMatchInlineSnapshot(` 232 - " 233 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 234 - 235 - FAIL |chromium| basic.test.ts > basic 236 - Error: toMatchAriaInlineSnapshot with different snapshots cannot be called at the same location 237 - 238 - - Expected 239 - + Received 240 - 241 - 242 - - - paragraph: count - 0 243 - + - paragraph: count - 1 244 - 245 - 246 - ❯ basic.test.ts:7:26 247 - 5| for (let i = 0; i < 3; i++) { 248 - 6| document.body.innerHTML = "<p>count - " + i + "</p>"; 249 - 7| expect(document.body).toMatchAriaInlineSnapshot(); 250 - | ^ 251 - 8| } 252 - 9| }); 253 - 254 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 255 - 256 - " 257 - `) 258 - expect(result.errorTree()).toMatchInlineSnapshot(` 259 - Object { 260 - "basic.test.ts": Object { 261 - "basic": Array [ 262 - "toMatchAriaInlineSnapshot with different snapshots cannot be called at the same location", 263 - ], 264 - }, 265 - } 266 - `) 267 - expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 268 - " 269 - import { expect, test } from 'vitest'; 270 - 271 - test('basic', () => { 272 - for (let i = 0; i < 3; i++) { 273 - document.body.innerHTML = "<p>count - " + i + "</p>"; 274 - expect(document.body).toMatchAriaInlineSnapshot(); 275 - } 276 - }); 277 - " 278 - `) 279 - }) 280 - 281 - test('template parse error', async () => { 282 - const result = await runInlineTests({ 283 - 'basic.test.ts': ` 284 - import { expect, test } from 'vitest'; 285 - 286 - test('basic', () => { 287 - expect(document.body).toMatchAriaInlineSnapshot(\`x: y\`); 288 - }); 289 - `, 290 - }, { 291 - browser: { 292 - enabled: true, 293 - headless: true, 294 - screenshotFailures: false, 295 - provider: playwright(), 296 - instances: [ 297 - { 298 - browser: 'chromium', 299 - }, 300 - ], 301 - }, 302 - update: 'none', 303 - }) 304 - expect(result.stderr).toMatchInlineSnapshot(` 305 - " 306 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 307 - 308 - FAIL |chromium| basic.test.ts > basic 309 - Error: Aria snapshot must be a YAML sequence, elements starting with " -" 310 - ❯ basic.test.ts:5:24 311 - 3| 312 - 4| test('basic', () => { 313 - 5| expect(document.body).toMatchAriaInlineSnapshot(\`x: y\`); 314 - | ^ 315 - 6| }); 316 - 7| 317 - 318 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 319 - 320 - " 321 - `) 322 - expect(result.errorTree()).toMatchInlineSnapshot(` 323 - Object { 324 - "basic.test.ts": Object { 325 - "basic": Array [ 326 - "Aria snapshot must be a YAML sequence, elements starting with " -"", 327 - ], 328 - }, 329 - } 330 - `) 331 - })
-176
test/snapshots/test/domain-aria.test.ts
··· 1 - import fs, { readFileSync } from 'node:fs' 2 - import { join } from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - 6 - test('aria snapshot', async () => { 7 - const root = join(import.meta.dirname, 'fixtures/domain-aria') 8 - const testFile = join(root, 'basic.test.ts') 9 - const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 10 - 11 - // clean slate 12 - fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 13 - 14 - // create snapshots from scratch — literal rendered values 15 - let result = await runVitest({ root, update: 'new' }) 16 - expect(result.stderr).toMatchInlineSnapshot(`""`) 17 - expect(result.errorTree()).toMatchInlineSnapshot(` 18 - Object { 19 - "basic.test.ts": Object { 20 - "empty": "passed", 21 - "semantic match with regex in snapshot": "passed", 22 - "simple heading and paragraph": "passed", 23 - }, 24 - } 25 - `) 26 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 27 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 28 - 29 - exports[\`empty 1\`] = \` 30 - 31 - \`; 32 - 33 - exports[\`semantic match with regex in snapshot 1\`] = \` 34 - - paragraph: Original 35 - - button "1234": Pattern 36 - \`; 37 - 38 - exports[\`simple heading and paragraph 1\`] = \` 39 - - heading "Hello World" [level=1] 40 - - paragraph: Some description 41 - \`; 42 - " 43 - `) 44 - expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 45 - Object { 46 - "added": 3, 47 - "didUpdate": false, 48 - "failure": false, 49 - "filesAdded": 1, 50 - "filesRemoved": 0, 51 - "filesRemovedList": Array [], 52 - "filesUnmatched": 0, 53 - "filesUpdated": 0, 54 - "matched": 0, 55 - "total": 3, 56 - "unchecked": 0, 57 - "uncheckedKeysByFile": Array [], 58 - "unmatched": 0, 59 - "updated": 0, 60 - } 61 - `) 62 - 63 - // hand-edit snapshot to introduce regex patterns for "semantic match" test 64 - editFile(snapshotFile, s => s 65 - .replace(`- button "1234"`, `- button /\\\\d+/`)) 66 - 67 - // re-run without update — regex pattern matches, all pass, snapshot unchanged 68 - result = await runVitest({ root, update: 'none' }) 69 - expect(result.stderr).toMatchInlineSnapshot(`""`) 70 - expect(result.errorTree()).toMatchInlineSnapshot(` 71 - Object { 72 - "basic.test.ts": Object { 73 - "empty": "passed", 74 - "semantic match with regex in snapshot": "passed", 75 - "simple heading and paragraph": "passed", 76 - }, 77 - } 78 - `) 79 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 80 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 81 - 82 - exports[\`empty 1\`] = \` 83 - 84 - \`; 85 - 86 - exports[\`semantic match with regex in snapshot 1\`] = \` 87 - - paragraph: Original 88 - - button /\\\\d+/: Pattern 89 - \`; 90 - 91 - exports[\`simple heading and paragraph 1\`] = \` 92 - - heading "Hello World" [level=1] 93 - - paragraph: Some description 94 - \`; 95 - " 96 - `) 97 - 98 - // edit test 99 - editFile(testFile, s => s 100 - .replace('<p>Original</p>', '<p>Changed</p>') 101 - .replace(`aria-label="1234"`, `aria-label="9999"`)) 102 - 103 - // run without update — literal mismatch causes failure 104 - result = await runVitest({ root, update: 'none' }) 105 - expect(result.stderr).toMatchInlineSnapshot(` 106 - " 107 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 108 - 109 - FAIL |chromium| basic.test.ts > semantic match with regex in snapshot 110 - Error: Snapshot \`semantic match with regex in snapshot 1\` mismatched 111 - 112 - Failure screenshot: 113 - - test/fixtures/domain-aria/__screenshots__/basic.test.ts/semantic-match-with-regex-in-snapshot-1.png 114 - 115 - - Expected 116 - + Received 117 - 118 - - - paragraph: Original 119 - + - paragraph: Changed 120 - - button /\\d+/: Pattern 121 - 122 - ❯ basic.test.ts:20:24 123 - 18| <button aria-label="9999">Pattern</button> 124 - 19| \` 125 - 20| expect(document.body).toMatchAriaSnapshot() 126 - | ^ 127 - 21| }) 128 - 22| 129 - 130 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 131 - 132 - " 133 - `) 134 - expect(result.errorTree()).toMatchInlineSnapshot(` 135 - Object { 136 - "basic.test.ts": Object { 137 - "empty": "passed", 138 - "semantic match with regex in snapshot": Array [ 139 - "Snapshot \`semantic match with regex in snapshot 1\` mismatched", 140 - ], 141 - "simple heading and paragraph": "passed", 142 - }, 143 - } 144 - `) 145 - 146 - // run with update 147 - result = await runVitest({ root, update: 'all' }) 148 - expect(result.stderr).toMatchInlineSnapshot(`""`) 149 - expect(result.errorTree()).toMatchInlineSnapshot(` 150 - Object { 151 - "basic.test.ts": Object { 152 - "empty": "passed", 153 - "semantic match with regex in snapshot": "passed", 154 - "simple heading and paragraph": "passed", 155 - }, 156 - } 157 - `) 158 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 159 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 160 - 161 - exports[\`empty 1\`] = \` 162 - 163 - \`; 164 - 165 - exports[\`semantic match with regex in snapshot 1\`] = \` 166 - - paragraph: Changed 167 - - button /\\\\d+/: Pattern 168 - \`; 169 - 170 - exports[\`simple heading and paragraph 1\`] = \` 171 - - heading "Hello World" [level=1] 172 - - paragraph: Some description 173 - \`; 174 - " 175 - `) 176 - })
-159
test/snapshots/test/domain-inline.test.ts
··· 1 - import { join } from 'node:path' 2 - import { expect, test } from 'vitest' 3 - import { editFile, runVitest } from '../../test-utils' 4 - import { readInlineSnapshots } from './utils' 5 - 6 - test('domain inline snapshot', async () => { 7 - const root = join(import.meta.dirname, 'fixtures/domain-inline') 8 - const testFile = join(root, 'basic.test.ts') 9 - 10 - // purge inline snapshots to empty strings, restore test values 11 - editFile(testFile, s => s 12 - .replace(/toMatchKvInlineSnapshot\(`[^`]*`/g, 'toMatchKvInlineSnapshot(')) 13 - 14 - // create snapshots from scratch 15 - let result = await runVitest({ root, update: 'new' }) 16 - expect(result.stderr).toMatchInlineSnapshot(`""`) 17 - expect(result.errorTree()).toMatchInlineSnapshot(` 18 - Object { 19 - "basic.test.ts": Object { 20 - "all literal": "passed", 21 - "empty snapshot": "passed", 22 - "with regex": "passed", 23 - }, 24 - } 25 - `) 26 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 27 - " 28 - expect({ name: 'alice', age: '30' }).toMatchKvInlineSnapshot(\` 29 - name=alice 30 - age=30 31 - \`) 32 - 33 - expect({ name: 'bob', score: '999', status: 'active' }).toMatchKvInlineSnapshot(\` 34 - name=bob 35 - score=999 36 - status=active 37 - \`) 38 - 39 - expect({}).toMatchKvInlineSnapshot(\`\`) 40 - " 41 - `) 42 - 43 - // hand-edit inline snapshot to introduce regex pattern 44 - // score=999 -> score=/\\d+/ 45 - editFile(testFile, s => s 46 - .replace('score=999', 'score=/\\\\d+/')) 47 - 48 - // run without update — regex matches, all pass 49 - result = await runVitest({ root, update: 'none' }) 50 - expect(result.stderr).toMatchInlineSnapshot(`""`) 51 - expect(result.errorTree()).toMatchInlineSnapshot(` 52 - Object { 53 - "basic.test.ts": Object { 54 - "all literal": "passed", 55 - "empty snapshot": "passed", 56 - "with regex": "passed", 57 - }, 58 - } 59 - `) 60 - 61 - // edit test values: score '999' -> '42' (regex still matches), 62 - // status 'active' -> 'inactive' (literal mismatch) 63 - editFile(testFile, s => s 64 - .replace(`name: 'alice',`, ``) 65 - .replace(`score: '999'`, `score: '42'`) 66 - .replace(`status: 'active'`, `status: 'inactive'`)) 67 - 68 - // run without update — status mismatch causes failure 69 - result = await runVitest({ root, update: 'none' }) 70 - expect(result.stderr).toMatchInlineSnapshot(` 71 - " 72 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 73 - 74 - FAIL basic.test.ts > all literal 75 - Error: Snapshot \`all literal 1\` mismatched 76 - 77 - - Expected 78 - + Received 79 - 80 - - name=alice 81 - age=30 82 - 83 - ❯ basic.test.ts:5:26 84 - 3| 85 - 4| test('all literal', () => { 86 - 5| expect({ age: '30' }).toMatchKvInlineSnapshot(\` 87 - | ^ 88 - 6| name=alice 89 - 7| age=30 90 - 91 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 92 - 93 - FAIL basic.test.ts > with regex 94 - Error: Snapshot \`with regex 1\` mismatched 95 - 96 - - Expected 97 - + Received 98 - 99 - name=bob 100 - score=/\\d+/ 101 - - status=active 102 - + status=inactive 103 - 104 - ❯ basic.test.ts:12:60 105 - 10| 106 - 11| test('with regex', () => { 107 - 12| expect({ name: 'bob', score: '42', status: 'inactive' }).toMatchKvIn… 108 - | ^ 109 - 13| name=bob 110 - 14| score=/\\\\d+/ 111 - 112 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 113 - 114 - " 115 - `) 116 - expect(result.errorTree()).toMatchInlineSnapshot(` 117 - Object { 118 - "basic.test.ts": Object { 119 - "all literal": Array [ 120 - "Snapshot \`all literal 1\` mismatched", 121 - ], 122 - "empty snapshot": "passed", 123 - "with regex": Array [ 124 - "Snapshot \`with regex 1\` mismatched", 125 - ], 126 - }, 127 - } 128 - `) 129 - 130 - // run with update — should preserve score regex (matched), 131 - // overwrite status with literal (didn't match) 132 - result = await runVitest({ root, update: 'all' }) 133 - expect(result.stderr).toMatchInlineSnapshot(`""`) 134 - expect(result.errorTree()).toMatchInlineSnapshot(` 135 - Object { 136 - "basic.test.ts": Object { 137 - "all literal": "passed", 138 - "empty snapshot": "passed", 139 - "with regex": "passed", 140 - }, 141 - } 142 - `) 143 - 144 - // verify inline snapshot in source was rewritten correctly 145 - // score regex preserved, status updated to 'inactive' 146 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 147 - " 148 - expect({ age: '30' }).toMatchKvInlineSnapshot(\`age=30\`) 149 - 150 - expect({ name: 'bob', score: '42', status: 'inactive' }).toMatchKvInlineSnapshot(\` 151 - name=bob 152 - score=/\\\\d+/ 153 - status=inactive 154 - \`) 155 - 156 - expect({}).toMatchKvInlineSnapshot(\`\`) 157 - " 158 - `) 159 - })
-452
test/snapshots/test/domain-poll-inline.test.ts
··· 1 - import { join } from 'node:path' 2 - import { expect, test } from 'vitest' 3 - import { editFile, runInlineTests, runVitest } from '../../test-utils' 4 - import { readInlineSnapshots } from './utils' 5 - 6 - test('domain inline snapshot with poll', async () => { 7 - const root = join(import.meta.dirname, 'fixtures/domain-poll-inline') 8 - const testFile = join(root, 'basic.test.ts') 9 - 10 - // purge inline snapshots to empty strings 11 - editFile(testFile, s => s 12 - .replace(/toMatchKvInlineSnapshot\(`[^`]*`/g, 'toMatchKvInlineSnapshot(')) 13 - 14 - // --- create snapshots (update: new) --- 15 - let result = await runVitest({ root, update: 'new' }) 16 - expect(result.stderr).toMatchInlineSnapshot(`""`) 17 - expect(result.errorTree()).toMatchInlineSnapshot(` 18 - Object { 19 - "basic.test.ts": Object { 20 - "empty snapshot": "passed", 21 - "multiple poll snapshots": "passed", 22 - "non-poll alongside poll": "passed", 23 - "stable": "passed", 24 - "throw then stable": "passed", 25 - "unstable then stable": "passed", 26 - }, 27 - } 28 - `) 29 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 30 - " 31 - expect.poll(() => { 32 - trial++ 33 - return { name: 'a', age: '23' } 34 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 35 - name=a 36 - age=23 37 - \`) 38 - 39 - expect.poll(() => { 40 - trial++ 41 - if (trial <= 3) { 42 - throw new Error(\`Fail at \${trial}\`) 43 - } 44 - return { name: 'b', age: '23' } 45 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 46 - name=b 47 - age=23 48 - \`) 49 - 50 - expect.poll(() => { 51 - trial++ 52 - if (trial <= 3) return { status: 'loading', trial } // unstable 53 - return { status: 'done' } // then stable 54 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`status=done\`) 55 - 56 - expect.poll(() => { 57 - return { x: '1' } 58 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`x=1\`) 59 - 60 - expect.poll(() => { 61 - return { y: '2' } 62 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`y=2\`) 63 - 64 - expect({ static: 'value' }).toMatchKvInlineSnapshot(\`static=value\`) 65 - 66 - expect.poll(() => { 67 - return { polled: 'value' } 68 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`polled=value\`) 69 - 70 - expect({ another: 'static' }).toMatchKvInlineSnapshot(\`another=static\`) 71 - 72 - expect.poll(() => { 73 - return {} 74 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`\`) 75 - " 76 - `) 77 - 78 - // --- re-run unchanged (update: none) --- 79 - result = await runVitest({ root, update: 'none' }) 80 - expect(result.stderr).toMatchInlineSnapshot(`""`) 81 - expect(result.errorTree()).toMatchInlineSnapshot(` 82 - Object { 83 - "basic.test.ts": Object { 84 - "empty snapshot": "passed", 85 - "multiple poll snapshots": "passed", 86 - "non-poll alongside poll": "passed", 87 - "stable": "passed", 88 - "throw then stable": "passed", 89 - "unstable then stable": "passed", 90 - }, 91 - } 92 - `) 93 - 94 - // --- mismatch — stable on wrong value --- 95 - editFile(testFile, s => s 96 - .replace('name=a\n', 'name=a-changed\n')) 97 - 98 - result = await runVitest({ root, update: 'none' }) 99 - expect(result.stderr).toMatchInlineSnapshot(` 100 - " 101 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 102 - 103 - FAIL basic.test.ts > stable 104 - Error: Snapshot \`stable 1\` mismatched 105 - 106 - - Expected 107 - + Received 108 - 109 - - name=a-changed 110 - + name=a 111 - age=23 112 - 113 - ❯ basic.test.ts:9:24 114 - 7| trial++ 115 - 8| return { name: 'a', age: '23' } 116 - 9| }, { interval: 10 }).toMatchKvInlineSnapshot(\` 117 - | ^ 118 - 10| name=a-changed 119 - 11| age=23 120 - 121 - Caused by: Error: Matcher did not succeed in time. 122 - ❯ basic.test.ts:6:3 123 - 124 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 125 - 126 - " 127 - `) 128 - expect(result.errorTree()).toMatchInlineSnapshot(` 129 - Object { 130 - "basic.test.ts": Object { 131 - "empty snapshot": "passed", 132 - "multiple poll snapshots": "passed", 133 - "non-poll alongside poll": "passed", 134 - "stable": Array [ 135 - "Snapshot \`stable 1\` mismatched", 136 - ], 137 - "throw then stable": "passed", 138 - "unstable then stable": "passed", 139 - }, 140 - } 141 - `) 142 - 143 - // --- update mode (update: all) --- 144 - result = await runVitest({ root, update: 'all' }) 145 - expect(result.stderr).toMatchInlineSnapshot(`""`) 146 - expect(result.errorTree()).toMatchInlineSnapshot(` 147 - Object { 148 - "basic.test.ts": Object { 149 - "empty snapshot": "passed", 150 - "multiple poll snapshots": "passed", 151 - "non-poll alongside poll": "passed", 152 - "stable": "passed", 153 - "throw then stable": "passed", 154 - "unstable then stable": "passed", 155 - }, 156 - } 157 - `) 158 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 159 - " 160 - expect.poll(() => { 161 - trial++ 162 - return { name: 'a', age: '23' } 163 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 164 - name=a 165 - age=23 166 - \`) 167 - 168 - expect.poll(() => { 169 - trial++ 170 - if (trial <= 3) { 171 - throw new Error(\`Fail at \${trial}\`) 172 - } 173 - return { name: 'b', age: '23' } 174 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 175 - name=b 176 - age=23 177 - \`) 178 - 179 - expect.poll(() => { 180 - trial++ 181 - if (trial <= 3) return { status: 'loading', trial } // unstable 182 - return { status: 'done' } // then stable 183 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`status=done\`) 184 - 185 - expect.poll(() => { 186 - return { x: '1' } 187 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`x=1\`) 188 - 189 - expect.poll(() => { 190 - return { y: '2' } 191 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`y=2\`) 192 - 193 - expect({ static: 'value' }).toMatchKvInlineSnapshot(\`static=value\`) 194 - 195 - expect.poll(() => { 196 - return { polled: 'value' } 197 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`polled=value\`) 198 - 199 - expect({ another: 'static' }).toMatchKvInlineSnapshot(\`another=static\`) 200 - 201 - expect.poll(() => { 202 - return {} 203 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`\`) 204 - " 205 - `) 206 - 207 - // --- pattern-preserving update --- 208 - editFile(testFile, s => s 209 - .replace('name=a\n', 'name=/\\\\w/\n')) 210 - 211 - result = await runVitest({ root, update: 'all' }) 212 - expect(result.stderr).toMatchInlineSnapshot(`""`) 213 - expect(result.errorTree()).toMatchInlineSnapshot(` 214 - Object { 215 - "basic.test.ts": Object { 216 - "empty snapshot": "passed", 217 - "multiple poll snapshots": "passed", 218 - "non-poll alongside poll": "passed", 219 - "stable": "passed", 220 - "throw then stable": "passed", 221 - "unstable then stable": "passed", 222 - }, 223 - } 224 - `) 225 - expect(readInlineSnapshots(testFile)).toMatchInlineSnapshot(` 226 - " 227 - expect.poll(() => { 228 - trial++ 229 - return { name: 'a', age: '23' } 230 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 231 - name=/\\\\w/ 232 - age=23 233 - \`) 234 - 235 - expect.poll(() => { 236 - trial++ 237 - if (trial <= 3) { 238 - throw new Error(\`Fail at \${trial}\`) 239 - } 240 - return { name: 'b', age: '23' } 241 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 242 - name=b 243 - age=23 244 - \`) 245 - 246 - expect.poll(() => { 247 - trial++ 248 - if (trial <= 3) return { status: 'loading', trial } // unstable 249 - return { status: 'done' } // then stable 250 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`status=done\`) 251 - 252 - expect.poll(() => { 253 - return { x: '1' } 254 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`x=1\`) 255 - 256 - expect.poll(() => { 257 - return { y: '2' } 258 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`y=2\`) 259 - 260 - expect({ static: 'value' }).toMatchKvInlineSnapshot(\`static=value\`) 261 - 262 - expect.poll(() => { 263 - return { polled: 'value' } 264 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`polled=value\`) 265 - 266 - expect({ another: 'static' }).toMatchKvInlineSnapshot(\`another=static\`) 267 - 268 - expect.poll(() => { 269 - return {} 270 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`\`) 271 - " 272 - `) 273 - }) 274 - 275 - test('poll until stable match when "none"', async () => { 276 - const result = await runInlineTests({ 277 - 'basic.test.ts': ` 278 - import { expect, test } from 'vitest' 279 - import '../test/fixtures/domain/basic-extend' 280 - 281 - test('stable wrong then right', async () => { 282 - let trial = 0 283 - await expect.poll(() => { 284 - trial++ 285 - if (trial <= 4) return { phase: 'pending' } 286 - return { phase: 'complete' } 287 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 288 - phase=complete 289 - \`) 290 - expect(trial).toBe(6) 291 - }) 292 - `, 293 - }, { 294 - update: 'none', 295 - }) 296 - expect(result.stderr).toMatchInlineSnapshot(`""`) 297 - expect(result.errorTree()).toMatchInlineSnapshot(` 298 - Object { 299 - "basic.test.ts": Object { 300 - "stable wrong then right": "passed", 301 - }, 302 - } 303 - `) 304 - }) 305 - 306 - test('poll until stable when "all"', async () => { 307 - const result = await runInlineTests({ 308 - 'basic.test.ts': ` 309 - import { expect, test } from 'vitest' 310 - import '../test/fixtures/domain/basic-extend' 311 - 312 - test('stable wrong then right', async () => { 313 - let trial = 0 314 - await expect.poll(() => { 315 - trial++ 316 - if (trial <= 4) return { phase: 'pending' } 317 - return { phase: 'complete' } 318 - }, { interval: 10 }).toMatchKvInlineSnapshot(\` 319 - phase=complete 320 - \`) 321 - expect(trial).toBe(2) 322 - }) 323 - `, 324 - }, { 325 - update: 'all', 326 - }) 327 - expect(result.stderr).toMatchInlineSnapshot(`""`) 328 - expect(result.errorTree()).toMatchInlineSnapshot(` 329 - Object { 330 - "basic.test.ts": Object { 331 - "stable wrong then right": "passed", 332 - }, 333 - } 334 - `) 335 - expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 336 - " 337 - import { expect, test } from 'vitest' 338 - import '../test/fixtures/domain/basic-extend' 339 - 340 - test('stable wrong then right', async () => { 341 - let trial = 0 342 - await expect.poll(() => { 343 - trial++ 344 - if (trial <= 4) return { phase: 'pending' } 345 - return { phase: 'complete' } 346 - }, { interval: 10 }).toMatchKvInlineSnapshot(\`phase=pending\`) 347 - expect(trial).toBe(2) 348 - }) 349 - " 350 - `) 351 - }) 352 - 353 - test('errors', async () => { 354 - const result = await runInlineTests({ 355 - 'basic.test.ts': ` 356 - import { expect, test } from 'vitest' 357 - import '../test/fixtures/domain/basic-extend' 358 - 359 - test('unstable', async () => { 360 - let trial = 0 361 - await expect.poll(() => { 362 - trial++ 363 - return { name: 'x', counter: String(trial) } 364 - }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 365 - }) 366 - 367 - test('hanging', async () => { 368 - let trial = 0 369 - await expect.poll(() => { 370 - trial++ 371 - return new Promise(() => {}) 372 - }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 373 - }) 374 - 375 - test('throwing', async () => { 376 - let trial = 0 377 - await expect.poll(() => { 378 - trial++ 379 - throw new Error("ALWAYS_THROWS") 380 - }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 381 - }) 382 - `, 383 - }, { 384 - update: 'all', 385 - }) 386 - expect(result.stderr).toMatchInlineSnapshot(` 387 - " 388 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 389 - 390 - FAIL basic.test.ts > unstable 391 - Error: poll() did not produce a stable snapshot within the timeout 392 - ❯ basic.test.ts:10:38 393 - 8| trial++ 394 - 9| return { name: 'x', counter: String(trial) } 395 - 10| }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 396 - | ^ 397 - 11| }) 398 - 12| 399 - 400 - Caused by: Error: Matcher did not succeed in time. 401 - ❯ basic.test.ts:7:3 402 - 403 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 404 - 405 - FAIL basic.test.ts > hanging 406 - Error: poll() did not produce a stable snapshot within the timeout 407 - ❯ basic.test.ts:18:38 408 - 16| trial++ 409 - 17| return new Promise(() => {}) 410 - 18| }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 411 - | ^ 412 - 19| }) 413 - 20| 414 - 415 - Caused by: Error: Matcher did not succeed in time. 416 - ❯ basic.test.ts:15:3 417 - 418 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 419 - 420 - FAIL basic.test.ts > throwing 421 - Error: ALWAYS_THROWS 422 - ❯ basic.test.ts:26:38 423 - 24| trial++ 424 - 25| throw new Error("ALWAYS_THROWS") 425 - 26| }, { timeout: 100, interval: 10 }).toMatchKvInlineSnapshot(\`\`) 426 - | ^ 427 - 27| }) 428 - 28| 429 - 430 - Caused by: Error: Matcher did not succeed in time. 431 - ❯ basic.test.ts:23:3 432 - 433 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 434 - 435 - " 436 - `) 437 - expect(result.errorTree()).toMatchInlineSnapshot(` 438 - Object { 439 - "basic.test.ts": Object { 440 - "hanging": Array [ 441 - "poll() did not produce a stable snapshot within the timeout", 442 - ], 443 - "throwing": Array [ 444 - "ALWAYS_THROWS", 445 - ], 446 - "unstable": Array [ 447 - "poll() did not produce a stable snapshot within the timeout", 448 - ], 449 - }, 450 - } 451 - `) 452 - })
-496
test/snapshots/test/domain-poll.test.ts
··· 1 - /** 2 - * pollAssertDomain behavior matrix 3 - * 4 - * Stability requirement: poll must produce two consecutive identical renders. 5 - * When a reference exists (and not `update: all`), the stable value must also 6 - * pass `adapter.match` — otherwise the baseline resets and polling continues 7 - * through intermediate stable states. 8 - * 9 - * Poll behavior | no reference | has reference (match) | has reference (mismatch) 10 - * -----------------------|----------------------|------------------------|------------------------- 11 - * stable immediately | new: pass (creates) | none/new/all: pass | none/new: fail (diff) 12 - * | none: fail (missing) | | all: pass (rewrites) 13 - * | all: pass (creates) | | 14 - * throw then stable | same as above | pass (throw resets | same as above 15 - * | | baseline, re-polls) | 16 - * transitional → stable | same as above | pass (rides through | same as above 17 - * | | intermediate states) | 18 - * stable wrong → right | n/a (no ref to | pass (match rejects | n/a 19 - * | reject against) | wrong, rides through)| 20 - * never stabilizes | fail (unstable) | fail (unstable) | fail (unstable) 21 - * always throws | fail (unstable, | fail (unstable, | fail (unstable, 22 - * | cause: poll error) | cause: poll error) | cause: poll error) 23 - * poll hangs | fail (unstable) | fail (unstable) | fail (unstable) 24 - */ 25 - import fs, { readFileSync } from 'node:fs' 26 - import { join } from 'node:path' 27 - import { expect, test } from 'vitest' 28 - import { editFile, runInlineTests, runVitest } from '../../test-utils' 29 - 30 - test('domain snapshot with poll', async () => { 31 - const root = join(import.meta.dirname, 'fixtures/domain-poll') 32 - const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 33 - 34 - // clean slate 35 - fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 36 - 37 - // --- create snapshots (update: new) --- 38 - let result = await runVitest({ root, update: 'new' }) 39 - expect(result.stderr).toMatchInlineSnapshot(`""`) 40 - expect(result.errorTree()).toMatchInlineSnapshot(` 41 - Object { 42 - "basic.test.ts": Object { 43 - "empty snapshot": "passed", 44 - "multiple poll snapshots": "passed", 45 - "non-poll alongside poll": "passed", 46 - "stable": "passed", 47 - "throw then stable": "passed", 48 - "unstable then stable": "passed", 49 - }, 50 - } 51 - `) 52 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 53 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 54 - 55 - exports[\`empty snapshot 1\`] = \`\`; 56 - 57 - exports[\`multiple poll snapshots 1\`] = \` 58 - x=1 59 - \`; 60 - 61 - exports[\`multiple poll snapshots 2\`] = \` 62 - y=2 63 - \`; 64 - 65 - exports[\`non-poll alongside poll 1\`] = \` 66 - static=value 67 - \`; 68 - 69 - exports[\`non-poll alongside poll 2\`] = \` 70 - polled=value 71 - \`; 72 - 73 - exports[\`non-poll alongside poll 3\`] = \` 74 - another=static 75 - \`; 76 - 77 - exports[\`stable 1\`] = \` 78 - name=a 79 - age=23 80 - \`; 81 - 82 - exports[\`throw then stable 1\`] = \` 83 - name=b 84 - age=23 85 - \`; 86 - 87 - exports[\`unstable then stable 1\`] = \` 88 - status=done 89 - \`; 90 - " 91 - `) 92 - 93 - // --- re-run unchanged (update: none) --- 94 - const result2 = await runVitest({ root, update: 'none' }) 95 - expect(result2.stderr).toBe(result.stderr) 96 - expect(result2.errorTree()).toEqual(result.errorTree()) 97 - 98 - // --- mismatch — stable on wrong value --- 99 - // Edit reference so "stable" poll stabilizes but doesn't match 100 - // Should produce a mismatch error with diff, not "unstable" error 101 - editFile(snapshotFile, s => s 102 - .replace('name=a\n', 'name=a-changed\n')) 103 - 104 - result = await runVitest({ root, update: 'none' }) 105 - expect(result.stderr).toMatchInlineSnapshot(` 106 - " 107 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ 108 - 109 - FAIL basic.test.ts > stable 110 - Error: Snapshot \`stable 1\` mismatched 111 - 112 - - Expected 113 - + Received 114 - 115 - - name=a-changed 116 - + name=a 117 - age=23 118 - 119 - ❯ basic.test.ts:9:24 120 - 7| trial++ 121 - 8| return { name: 'a', age: '23' } 122 - 9| }, { interval: 10 }).toMatchKvSnapshot() 123 - | ^ 124 - 10| expect(trial).toBe(2) 125 - 11| }) 126 - 127 - Caused by: Error: Matcher did not succeed in time. 128 - ❯ basic.test.ts:6:3 129 - 130 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 131 - 132 - " 133 - `) 134 - expect(result.errorTree()).toMatchInlineSnapshot(` 135 - Object { 136 - "basic.test.ts": Object { 137 - "empty snapshot": "passed", 138 - "multiple poll snapshots": "passed", 139 - "non-poll alongside poll": "passed", 140 - "stable": Array [ 141 - "Snapshot \`stable 1\` mismatched", 142 - ], 143 - "throw then stable": "passed", 144 - "unstable then stable": "passed", 145 - }, 146 - } 147 - `) 148 - 149 - // --- update mode (update: all) --- 150 - // Rewrite snapshots with current stable values 151 - result = await runVitest({ root, update: 'all' }) 152 - expect(result.stderr).toMatchInlineSnapshot(`""`) 153 - expect(result.errorTree()).toMatchInlineSnapshot(` 154 - Object { 155 - "basic.test.ts": Object { 156 - "empty snapshot": "passed", 157 - "multiple poll snapshots": "passed", 158 - "non-poll alongside poll": "passed", 159 - "stable": "passed", 160 - "throw then stable": "passed", 161 - "unstable then stable": "passed", 162 - }, 163 - } 164 - `) 165 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 166 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 167 - 168 - exports[\`empty snapshot 1\`] = \`\`; 169 - 170 - exports[\`multiple poll snapshots 1\`] = \` 171 - x=1 172 - \`; 173 - 174 - exports[\`multiple poll snapshots 2\`] = \` 175 - y=2 176 - \`; 177 - 178 - exports[\`non-poll alongside poll 1\`] = \` 179 - static=value 180 - \`; 181 - 182 - exports[\`non-poll alongside poll 2\`] = \` 183 - polled=value 184 - \`; 185 - 186 - exports[\`non-poll alongside poll 3\`] = \` 187 - another=static 188 - \`; 189 - 190 - exports[\`stable 1\`] = \` 191 - name=a 192 - age=23 193 - \`; 194 - 195 - exports[\`throw then stable 1\`] = \` 196 - name=b 197 - age=23 198 - \`; 199 - 200 - exports[\`unstable then stable 1\`] = \` 201 - status=done 202 - \`; 203 - " 204 - `) 205 - 206 - // --- pattern-preserving update --- 207 - // Inject regex pattern into snapshot, verify --update preserves it 208 - editFile(snapshotFile, s => s 209 - .replace('name=a\n', 'name=/\\\\w/\n')) 210 - 211 - result = await runVitest({ root, update: 'all' }) 212 - expect(result.stderr).toMatchInlineSnapshot(`""`) 213 - expect(result.errorTree()).toMatchInlineSnapshot(` 214 - Object { 215 - "basic.test.ts": Object { 216 - "empty snapshot": "passed", 217 - "multiple poll snapshots": "passed", 218 - "non-poll alongside poll": "passed", 219 - "stable": "passed", 220 - "throw then stable": "passed", 221 - "unstable then stable": "passed", 222 - }, 223 - } 224 - `) 225 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 226 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 227 - 228 - exports[\`empty snapshot 1\`] = \`\`; 229 - 230 - exports[\`multiple poll snapshots 1\`] = \` 231 - x=1 232 - \`; 233 - 234 - exports[\`multiple poll snapshots 2\`] = \` 235 - y=2 236 - \`; 237 - 238 - exports[\`non-poll alongside poll 1\`] = \` 239 - static=value 240 - \`; 241 - 242 - exports[\`non-poll alongside poll 2\`] = \` 243 - polled=value 244 - \`; 245 - 246 - exports[\`non-poll alongside poll 3\`] = \` 247 - another=static 248 - \`; 249 - 250 - exports[\`stable 1\`] = \` 251 - name=/\\\\w/ 252 - age=23 253 - \`; 254 - 255 - exports[\`throw then stable 1\`] = \` 256 - name=b 257 - age=23 258 - \`; 259 - 260 - exports[\`unstable then stable 1\`] = \` 261 - status=done 262 - \`; 263 - " 264 - `) 265 - }) 266 - 267 - test('poll until stable match when "none"', async () => { 268 - const result = await runInlineTests({ 269 - '__snapshots__/basic.test.ts.snap': `\ 270 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 271 - 272 - exports[\`stable wrong then right 1\`] = \` 273 - phase=complete 274 - \`; 275 - `, 276 - 'basic.test.ts': ` 277 - import { expect, test } from 'vitest' 278 - import '../test/fixtures/domain/basic-extend' 279 - 280 - test('stable wrong then right', async () => { 281 - let trial = 0 282 - await expect.poll(() => { 283 - trial++ 284 - if (trial <= 4) return { phase: 'pending' } 285 - return { phase: 'complete' } 286 - }, { interval: 10 }).toMatchKvSnapshot() 287 - expect(trial).toBe(6) 288 - }) 289 - `, 290 - }, { 291 - update: 'none', 292 - }) 293 - expect(result.stderr).toMatchInlineSnapshot(`""`) 294 - expect(result.errorTree()).toMatchInlineSnapshot(` 295 - Object { 296 - "basic.test.ts": Object { 297 - "stable wrong then right": "passed", 298 - }, 299 - } 300 - `) 301 - }) 302 - 303 - test('poll until stable when "all"', async () => { 304 - const result = await runInlineTests({ 305 - '__snapshots__/basic.test.ts.snap': `\ 306 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 307 - 308 - exports[\`stable wrong then right 1\`] = \` 309 - phase=complete 310 - \`; 311 - `, 312 - 'basic.test.ts': ` 313 - import { expect, test } from 'vitest' 314 - import '../test/fixtures/domain/basic-extend' 315 - 316 - test('stable wrong then right', async () => { 317 - let trial = 0 318 - await expect.poll(() => { 319 - trial++ 320 - if (trial <= 4) return { phase: 'pending' } 321 - return { phase: 'complete' } 322 - }, { interval: 10 }).toMatchKvSnapshot() 323 - expect(trial).toBe(2) 324 - }) 325 - `, 326 - }, { 327 - update: 'all', 328 - }) 329 - expect(result.stderr).toMatchInlineSnapshot(`""`) 330 - expect(result.errorTree()).toMatchInlineSnapshot(` 331 - Object { 332 - "basic.test.ts": Object { 333 - "stable wrong then right": "passed", 334 - }, 335 - } 336 - `) 337 - expect(result.fs.readFile('__snapshots__/basic.test.ts.snap')).toMatchInlineSnapshot(` 338 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 339 - 340 - exports[\`stable wrong then right 1\`] = \` 341 - phase=pending 342 - \`; 343 - " 344 - `) 345 - }) 346 - 347 - test('errors', async () => { 348 - const result = await runInlineTests({ 349 - 'basic.test.ts': ` 350 - import { expect, test } from 'vitest' 351 - import '../test/fixtures/domain/basic-extend' 352 - 353 - test('unstable', async () => { 354 - let trial = 0 355 - await expect.poll(() => { 356 - trial++ 357 - return { name: 'x', counter: String(trial) } 358 - }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 359 - }) 360 - 361 - test('hanging', async () => { 362 - let trial = 0 363 - await expect.poll(() => { 364 - trial++ 365 - return new Promise(() => {}) 366 - }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 367 - }) 368 - 369 - test('throwing', async () => { 370 - let trial = 0 371 - await expect.poll(() => { 372 - trial++ 373 - throw new Error("ALWAYS_THROWS") 374 - }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 375 - }) 376 - `, 377 - }, { 378 - update: 'all', 379 - }) 380 - expect(result.stderr).toMatchInlineSnapshot(` 381 - " 382 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 383 - 384 - FAIL basic.test.ts > unstable 385 - Error: poll() did not produce a stable snapshot within the timeout 386 - ❯ basic.test.ts:10:38 387 - 8| trial++ 388 - 9| return { name: 'x', counter: String(trial) } 389 - 10| }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 390 - | ^ 391 - 11| }) 392 - 12| 393 - 394 - Caused by: Error: Matcher did not succeed in time. 395 - ❯ basic.test.ts:7:3 396 - 397 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 398 - 399 - FAIL basic.test.ts > hanging 400 - Error: poll() did not produce a stable snapshot within the timeout 401 - ❯ basic.test.ts:18:38 402 - 16| trial++ 403 - 17| return new Promise(() => {}) 404 - 18| }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 405 - | ^ 406 - 19| }) 407 - 20| 408 - 409 - Caused by: Error: Matcher did not succeed in time. 410 - ❯ basic.test.ts:15:3 411 - 412 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 413 - 414 - FAIL basic.test.ts > throwing 415 - Error: ALWAYS_THROWS 416 - ❯ basic.test.ts:26:38 417 - 24| trial++ 418 - 25| throw new Error("ALWAYS_THROWS") 419 - 26| }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 420 - | ^ 421 - 27| }) 422 - 28| 423 - 424 - Caused by: Error: Matcher did not succeed in time. 425 - ❯ basic.test.ts:23:3 426 - 427 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 428 - 429 - " 430 - `) 431 - expect(result.errorTree()).toMatchInlineSnapshot(` 432 - Object { 433 - "basic.test.ts": Object { 434 - "hanging": Array [ 435 - "poll() did not produce a stable snapshot within the timeout", 436 - ], 437 - "throwing": Array [ 438 - "ALWAYS_THROWS", 439 - ], 440 - "unstable": Array [ 441 - "poll() did not produce a stable snapshot within the timeout", 442 - ], 443 - }, 444 - } 445 - `) 446 - }) 447 - 448 - test('signal', async () => { 449 - const result = await runInlineTests({ 450 - 'basic.test.ts': ` 451 - import '../test/fixtures/domain/basic-extend' 452 - 453 - test('signal', async () => { 454 - let aborted = false 455 - await expect( 456 - expect.poll(({ signal }) => { 457 - signal.addEventListener('abort', () => { 458 - aborted = true 459 - }) 460 - return new Promise(() => {}) 461 - }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 462 - ).rejects.toThrowErrorMatchingInlineSnapshot() 463 - expect(aborted).toMatchInlineSnapshot() 464 - }) 465 - `, 466 - }, { 467 - globals: true, 468 - update: 'all', 469 - }) 470 - expect(result.stderr).toMatchInlineSnapshot(`""`) 471 - expect(result.errorTree()).toMatchInlineSnapshot(` 472 - Object { 473 - "basic.test.ts": Object { 474 - "signal": "passed", 475 - }, 476 - } 477 - `) 478 - expect(result.fs.readFile('basic.test.ts')).toMatchInlineSnapshot(` 479 - " 480 - import '../test/fixtures/domain/basic-extend' 481 - 482 - test('signal', async () => { 483 - let aborted = false 484 - await expect( 485 - expect.poll(({ signal }) => { 486 - signal.addEventListener('abort', () => { 487 - aborted = true 488 - }) 489 - return new Promise(() => {}) 490 - }, { timeout: 100, interval: 10 }).toMatchKvSnapshot() 491 - ).rejects.toThrowErrorMatchingInlineSnapshot(\`[Error: poll() did not produce a stable snapshot within the timeout]\`) 492 - expect(aborted).toMatchInlineSnapshot(\`true\`) 493 - }) 494 - " 495 - `) 496 - })
-233
test/snapshots/test/domain.test.ts
··· 1 - import fs, { readFileSync } from 'node:fs' 2 - import { join } from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - 6 - test('domain snapshot', async () => { 7 - const root = join(import.meta.dirname, 'fixtures/domain') 8 - const testFile = join(root, 'basic.test.ts') 9 - const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 10 - 11 - // clean slate 12 - fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 13 - 14 - // create snapshots from scratch — literal rendered values 15 - let result = await runVitest({ root, update: 'new' }) 16 - expect(result.stderr).toMatchInlineSnapshot(`""`) 17 - expect(result.errorTree()).toMatchInlineSnapshot(` 18 - Object { 19 - "basic.test.ts": Object { 20 - "all literal": "passed", 21 - "empty snapshot": "passed", 22 - "with regex": "passed", 23 - }, 24 - } 25 - `) 26 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 27 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 28 - 29 - exports[\`all literal 1\`] = \` 30 - name=alice 31 - age=30 32 - \`; 33 - 34 - exports[\`empty snapshot 1\`] = \`\`; 35 - 36 - exports[\`with regex 1\`] = \` 37 - name=bob 38 - age=24 39 - score=999 40 - status=active 41 - \`; 42 - " 43 - `) 44 - 45 - // hand-edit snapshot 46 - editFile(snapshotFile, s => s 47 - // match any numbers match for score 48 - .replace('score=999', 'score=/\\\\d+/') 49 - .replace('age=24\n', '')) 50 - 51 - // re-run without update 52 - result = await runVitest({ root, update: 'none' }) 53 - expect(result.stderr).toMatchInlineSnapshot(`""`) 54 - expect(result.errorTree()).toMatchInlineSnapshot(` 55 - Object { 56 - "basic.test.ts": Object { 57 - "all literal": "passed", 58 - "empty snapshot": "passed", 59 - "with regex": "passed", 60 - }, 61 - } 62 - `) 63 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 64 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 65 - 66 - exports[\`all literal 1\`] = \` 67 - name=alice 68 - age=30 69 - \`; 70 - 71 - exports[\`empty snapshot 1\`] = \`\`; 72 - 73 - exports[\`with regex 1\`] = \` 74 - name=bob 75 - score=/\\\\d+/ 76 - status=active 77 - \`; 78 - " 79 - `) 80 - 81 - // edit test 82 - editFile(testFile, s => s 83 - .replace(`name: 'alice',`, ``) 84 - .replace(`score: '999'`, `score: '42'`) 85 - .replace(`status: 'active'`, `status: 'inactive'`)) 86 - 87 - // run without update 88 - // (note that `age` and `score` is not in diff) 89 - result = await runVitest({ root, update: 'none' }) 90 - expect(result.stderr).toMatchInlineSnapshot(` 91 - " 92 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 93 - 94 - FAIL basic.test.ts > all literal 95 - Error: Snapshot \`all literal 1\` mismatched 96 - 97 - - Expected 98 - + Received 99 - 100 - - name=alice 101 - age=30 102 - 103 - ❯ basic.test.ts:5:26 104 - 3| 105 - 4| test('all literal', () => { 106 - 5| expect({ age: '30' }).toMatchKvSnapshot() 107 - | ^ 108 - 6| }) 109 - 7| 110 - 111 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 112 - 113 - FAIL basic.test.ts > with regex 114 - Error: Snapshot \`with regex 1\` mismatched 115 - 116 - - Expected 117 - + Received 118 - 119 - name=bob 120 - score=/\\d+/ 121 - - status=active 122 - + status=inactive 123 - 124 - ❯ basic.test.ts:9:71 125 - 7| 126 - 8| test('with regex', () => { 127 - 9| expect({ name: 'bob', age: '24', score: '42', status: 'inactive' }).… 128 - | ^ 129 - 10| }) 130 - 11| 131 - 132 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 133 - 134 - " 135 - `) 136 - expect(result.errorTree()).toMatchInlineSnapshot(` 137 - Object { 138 - "basic.test.ts": Object { 139 - "all literal": Array [ 140 - "Snapshot \`all literal 1\` mismatched", 141 - ], 142 - "empty snapshot": "passed", 143 - "with regex": Array [ 144 - "Snapshot \`with regex 1\` mismatched", 145 - ], 146 - }, 147 - } 148 - `) 149 - 150 - // run with update — should preserve score regex (matched), 151 - // overwrite status with literal (didn't match) 152 - result = await runVitest({ root, update: 'all' }) 153 - expect(result.stderr).toMatchInlineSnapshot(`""`) 154 - expect(result.errorTree()).toMatchInlineSnapshot(` 155 - Object { 156 - "basic.test.ts": Object { 157 - "all literal": "passed", 158 - "empty snapshot": "passed", 159 - "with regex": "passed", 160 - }, 161 - } 162 - `) 163 - // NOTE 164 - // score regex matched '42' -> preserved as /\d+/ 165 - // status literal 'active' != 'inactive' -> overwritten with literal 166 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 167 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 168 - 169 - exports[\`all literal 1\`] = \` 170 - age=30 171 - \`; 172 - 173 - exports[\`empty snapshot 1\`] = \`\`; 174 - 175 - exports[\`with regex 1\`] = \` 176 - name=bob 177 - score=/\\\\d+/ 178 - status=inactive 179 - \`; 180 - " 181 - `) 182 - }) 183 - 184 - test('domain parseExpected error', async () => { 185 - const root = join(import.meta.dirname, 'fixtures/domain-error') 186 - const result = await runVitest({ root, update: 'none' }) 187 - expect(result.stderr).toMatchInlineSnapshot(` 188 - " 189 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯ 190 - 191 - FAIL basic.test.ts > file 192 - Error: Invalid KV Format: 'file-broken' 193 - ❯ ../domain/basic.ts:38:15 194 - 36| const eq = line.indexOf('=') 195 - 37| if (eq === -1) { 196 - 38| throw new Error(\`Invalid KV Format: '\${line}'\`) 197 - | ^ 198 - 39| } 199 - 40| const key = line.slice(0, eq) 200 - ❯ Object.parseExpected ../domain/basic.ts:35:46 201 - ❯ Object.toMatchKvSnapshot ../domain/basic-extend.ts:16:44 202 - 203 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ 204 - 205 - FAIL basic.test.ts > inline 206 - Error: Invalid KV Format: 'inine-broken' 207 - ❯ ../domain/basic.ts:38:15 208 - 36| const eq = line.indexOf('=') 209 - 37| if (eq === -1) { 210 - 38| throw new Error(\`Invalid KV Format: '\${line}'\`) 211 - | ^ 212 - 39| } 213 - 40| const key = line.slice(0, eq) 214 - ❯ Object.parseExpected ../domain/basic.ts:35:46 215 - ❯ Object.toMatchKvInlineSnapshot ../domain/basic-extend.ts:22:50 216 - 217 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ 218 - 219 - " 220 - `) 221 - expect(result.errorTree()).toMatchInlineSnapshot(` 222 - Object { 223 - "basic.test.ts": Object { 224 - "file": Array [ 225 - "Invalid KV Format: 'file-broken'", 226 - ], 227 - "inline": Array [ 228 - "Invalid KV Format: 'inine-broken'", 229 - ], 230 - }, 231 - } 232 - `) 233 - })
-28
test/snapshots/test/file.test.ts
··· 1 - import { join } from 'node:path' 2 - import { expect, test } from 'vitest' 3 - import { editFile, runVitest } from '../../test-utils' 4 - 5 - test('white space sensitive', async () => { 6 - const root = join(import.meta.dirname, 'fixtures/file') 7 - 8 - // check correct snapshot 9 - let vitest = await runVitest({ root }) 10 - expect(vitest.exitCode).toBe(0) 11 - 12 - // check diff of wrong snapshot 13 - editFile(join(root, 'snapshot-1.txt'), s => s.trim()) 14 - editFile(join(root, 'snapshot-2.txt'), s => s.replace('echo', 'ECHO')) 15 - vitest = await runVitest({ root }) 16 - expect(vitest.stderr).toContain(` 17 - - white space 18 - + 19 - + 20 - + white space 21 - + 22 - `) 23 - expect(vitest.stderr).toContain(` 24 - - ECHO "hello" 25 - + echo "hello" 26 - `) 27 - expect(vitest.exitCode).toBe(1) 28 - })
-28
test/snapshots/test/indent.test.ts
··· 1 - import { join } from 'node:path' 2 - import { expect, test } from 'vitest' 3 - import { editFile, runVitest } from '../../test-utils' 4 - 5 - test('white space sensitive', async () => { 6 - const root = join(import.meta.dirname, 'fixtures/indent') 7 - 8 - // ensure correct snapshot 9 - let vitest = await runVitest({ root, update: true }) 10 - expect(vitest.exitCode).toBe(0) 11 - 12 - // check diff of wrong snapshot 13 - editFile(join(root, 'basic.test.ts'), s => s.replace('1111', 'aaaa').replace('2222', 'bbbb')) 14 - vitest = await runVitest({ root }) 15 - expect(vitest.stderr).toContain(` 16 - - 1111 17 - + aaaa 18 - xxxx { 19 - } 20 - `) 21 - expect(vitest.stderr).toContain(` 22 - - 2222 23 - + bbbb 24 - yyyy { 25 - } 26 - `) 27 - expect(vitest.exitCode).toBe(1) 28 - })
-725
test/snapshots/test/inline-multiple-calls.test.ts
··· 1 - import fs, { readFileSync } from 'node:fs' 2 - import { join } from 'pathe' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - 6 - // pnpm -C test/snapshots test:snaps inline-multiple-calls 7 - 8 - test('same snapshots in single test', async () => { 9 - // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls same.test 10 - 11 - // reset snapshot 12 - const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 13 - const testFile = join(root, 'same.test.ts') 14 - editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 15 - 16 - // initial run (create snapshot) 17 - let vitest = await runVitest({ 18 - root, 19 - include: [testFile], 20 - update: true, 21 - }) 22 - expect(vitest.stderr).toBe('') 23 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 24 - Object { 25 - "added": 2, 26 - "didUpdate": true, 27 - "failure": false, 28 - "filesAdded": 1, 29 - "filesRemoved": 0, 30 - "filesRemovedList": Array [], 31 - "filesUnmatched": 0, 32 - "filesUpdated": 0, 33 - "matched": 0, 34 - "total": 2, 35 - "unchecked": 0, 36 - "uncheckedKeysByFile": Array [], 37 - "unmatched": 0, 38 - "updated": 0, 39 - } 40 - `) 41 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 42 - 43 - // no-update run 44 - vitest = await runVitest({ 45 - root, 46 - include: [testFile], 47 - update: false, 48 - }) 49 - expect(vitest.stderr).toBe('') 50 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 51 - Object { 52 - "added": 0, 53 - "didUpdate": false, 54 - "failure": false, 55 - "filesAdded": 0, 56 - "filesRemoved": 0, 57 - "filesRemovedList": Array [], 58 - "filesUnmatched": 0, 59 - "filesUpdated": 0, 60 - "matched": 2, 61 - "total": 2, 62 - "unchecked": 0, 63 - "uncheckedKeysByFile": Array [], 64 - "unmatched": 0, 65 - "updated": 0, 66 - } 67 - `) 68 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 69 - 70 - // update run 71 - vitest = await runVitest({ 72 - root, 73 - include: [testFile], 74 - update: true, 75 - }) 76 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 77 - Object { 78 - "added": 0, 79 - "didUpdate": true, 80 - "failure": false, 81 - "filesAdded": 0, 82 - "filesRemoved": 0, 83 - "filesRemovedList": Array [], 84 - "filesUnmatched": 0, 85 - "filesUpdated": 0, 86 - "matched": 2, 87 - "total": 2, 88 - "unchecked": 0, 89 - "uncheckedKeysByFile": Array [], 90 - "unmatched": 0, 91 - "updated": 0, 92 - } 93 - `) 94 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 95 - }) 96 - 97 - test('same snapshots in multiple tests', async () => { 98 - // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls same2.test 99 - 100 - // reset snapshot 101 - const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 102 - const testFile = join(root, 'same2.test.ts') 103 - editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 104 - 105 - // initial run (create snapshot) 106 - let vitest = await runVitest({ 107 - root, 108 - include: [testFile], 109 - update: true, 110 - }) 111 - expect(vitest.stderr).toBe('') 112 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 113 - Object { 114 - "added": 2, 115 - "didUpdate": true, 116 - "failure": false, 117 - "filesAdded": 1, 118 - "filesRemoved": 0, 119 - "filesRemovedList": Array [], 120 - "filesUnmatched": 0, 121 - "filesUpdated": 0, 122 - "matched": 0, 123 - "total": 2, 124 - "unchecked": 0, 125 - "uncheckedKeysByFile": Array [], 126 - "unmatched": 0, 127 - "updated": 0, 128 - } 129 - `) 130 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 131 - 132 - // no-update run 133 - vitest = await runVitest({ 134 - root, 135 - include: [testFile], 136 - update: false, 137 - }) 138 - expect(vitest.stderr).toBe('') 139 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 140 - Object { 141 - "added": 0, 142 - "didUpdate": false, 143 - "failure": false, 144 - "filesAdded": 0, 145 - "filesRemoved": 0, 146 - "filesRemovedList": Array [], 147 - "filesUnmatched": 0, 148 - "filesUpdated": 0, 149 - "matched": 2, 150 - "total": 2, 151 - "unchecked": 0, 152 - "uncheckedKeysByFile": Array [], 153 - "unmatched": 0, 154 - "updated": 0, 155 - } 156 - `) 157 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 158 - 159 - // update run 160 - vitest = await runVitest({ 161 - root, 162 - include: [testFile], 163 - update: true, 164 - }) 165 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 166 - Object { 167 - "added": 0, 168 - "didUpdate": true, 169 - "failure": false, 170 - "filesAdded": 0, 171 - "filesRemoved": 0, 172 - "filesRemovedList": Array [], 173 - "filesUnmatched": 0, 174 - "filesUpdated": 0, 175 - "matched": 2, 176 - "total": 2, 177 - "unchecked": 0, 178 - "uncheckedKeysByFile": Array [], 179 - "unmatched": 0, 180 - "updated": 0, 181 - } 182 - `) 183 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 184 - }) 185 - 186 - test('different snapshots in single test', async () => { 187 - // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls different.test 188 - 189 - // reset snapshot 190 - const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 191 - const testFile = join(root, 'different.test.ts') 192 - editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 193 - 194 - // update run should fail 195 - let vitest = await runVitest({ 196 - root, 197 - include: [testFile], 198 - update: true, 199 - }) 200 - expect(vitest.stderr).toContain(` 201 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 202 - 203 - Expected: ""test1"" 204 - Received: ""test2"" 205 - `) 206 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 207 - expect(vitest.exitCode).not.toBe(0) 208 - 209 - // no-update run should fail 210 - vitest = await runVitest({ 211 - root, 212 - include: [testFile], 213 - update: false, 214 - }) 215 - if (process.env.CI) { 216 - expect(vitest.stderr).toContain(` 217 - Error: Snapshot \`single 1\` mismatched 218 - `) 219 - } 220 - else { 221 - expect(vitest.stderr).toContain(` 222 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 223 - 224 - Expected: ""test1"" 225 - Received: ""test2"" 226 - `) 227 - } 228 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 229 - 230 - // current snapshot is "test1" 231 - editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot()', 'expect(value).toMatchInlineSnapshot(`"test1"`)')) 232 - vitest = await runVitest({ 233 - root, 234 - include: [testFile], 235 - update: true, 236 - }) 237 - expect(vitest.stderr).toContain(` 238 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 239 - 240 - Expected: ""test1"" 241 - Received: ""test2"" 242 - `) 243 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 244 - 245 - vitest = await runVitest({ 246 - root, 247 - include: [testFile], 248 - update: false, 249 - }) 250 - expect(vitest.stderr).toContain(` 251 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 252 - 253 - Expected: ""test1"" 254 - Received: ""test2"" 255 - `) 256 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 257 - 258 - // current snapshot is "test2" 259 - editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot(`"test1"`)', 'expect(value).toMatchInlineSnapshot(`"test2"`)')) 260 - vitest = await runVitest({ 261 - root, 262 - include: [testFile], 263 - update: true, 264 - }) 265 - expect(vitest.stderr).toContain(` 266 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 267 - 268 - Expected: ""test1"" 269 - Received: ""test2"" 270 - `) 271 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 272 - 273 - vitest = await runVitest({ 274 - root, 275 - include: [testFile], 276 - update: false, 277 - }) 278 - expect(vitest.stderr).toContain(` 279 - Error: Snapshot \`single 1\` mismatched 280 - 281 - Expected: ""test2"" 282 - Received: ""test1"" 283 - `) 284 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 285 - }) 286 - 287 - test('different snapshots in multiple tests', async () => { 288 - // pnpm -C test/snapshots test:fixtures --root test/fixtures/inline-multiple-calls different2.test 289 - 290 - // reset snapshot 291 - const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 292 - const testFile = join(root, 'different2.test.ts') 293 - editFile(testFile, s => s.replace(/toMatchInlineSnapshot\(`.*`\)/gs, 'toMatchInlineSnapshot()')) 294 - 295 - // update run should fail 296 - let vitest = await runVitest({ 297 - root, 298 - include: [testFile], 299 - update: true, 300 - }) 301 - expect(vitest.stderr).toContain(` 302 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 303 - 304 - Expected: ""test1"" 305 - Received: ""test2"" 306 - `) 307 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 308 - expect(vitest.exitCode).not.toBe(0) 309 - 310 - // no-update run should fail 311 - vitest = await runVitest({ 312 - root, 313 - include: [testFile], 314 - update: false, 315 - }) 316 - if (process.env.CI) { 317 - expect(vitest.stderr).toContain(` 318 - Error: Snapshot \`a 1\` mismatched 319 - `) 320 - } 321 - else { 322 - expect(vitest.stderr).toContain(` 323 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 324 - 325 - Expected: ""test1"" 326 - Received: ""test2"" 327 - `) 328 - } 329 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot()') 330 - 331 - // current snapshot is "test1" 332 - editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot()', 'expect(value).toMatchInlineSnapshot(`"test1"`)')) 333 - vitest = await runVitest({ 334 - root, 335 - include: [testFile], 336 - update: true, 337 - }) 338 - expect(vitest.stderr).toContain(` 339 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 340 - 341 - Expected: ""test1"" 342 - Received: ""test2"" 343 - `) 344 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 345 - 346 - vitest = await runVitest({ 347 - root, 348 - include: [testFile], 349 - update: false, 350 - }) 351 - expect(vitest.stderr).toContain(` 352 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 353 - 354 - Expected: ""test1"" 355 - Received: ""test2"" 356 - `) 357 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test1"`)') 358 - 359 - // current snapshot is "test2" 360 - editFile(testFile, s => s.replace('expect(value).toMatchInlineSnapshot(`"test1"`)', 'expect(value).toMatchInlineSnapshot(`"test2"`)')) 361 - vitest = await runVitest({ 362 - root, 363 - include: [testFile], 364 - update: true, 365 - }) 366 - expect(vitest.stderr).toContain(` 367 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 368 - 369 - Expected: ""test1"" 370 - Received: ""test2"" 371 - `) 372 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 373 - 374 - vitest = await runVitest({ 375 - root, 376 - include: [testFile], 377 - update: false, 378 - }) 379 - expect(vitest.stderr).toContain(` 380 - Error: Snapshot \`a 1\` mismatched 381 - 382 - Expected: ""test2"" 383 - Received: ""test1"" 384 - `) 385 - expect(fs.readFileSync(testFile, 'utf-8')).toContain('expect(value).toMatchInlineSnapshot(`"test2"`)') 386 - }) 387 - 388 - test('test.each/for', async () => { 389 - const root = join(import.meta.dirname, 'fixtures/inline-multiple-calls') 390 - const testFile = join(root, 'each.test.ts') 391 - 392 - // remove inline snapshots 393 - editFile(testFile, s => s 394 - .replace(/toMatchInlineSnapshot\(`[^`]*`\)/g, 'toMatchInlineSnapshot()') 395 - .replace(/toThrowErrorMatchingInlineSnapshot\(`[^`]*`\)/g, 'toThrowErrorMatchingInlineSnapshot()')) 396 - 397 - // create snapshots from scratch 398 - let result = await runVitest({ root, include: [testFile], update: 'new' }) 399 - expect(result.stderr).toMatchInlineSnapshot(`""`) 400 - expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 401 - "import { expect, test, describe } from "vitest"; 402 - 403 - test.for(["hello", "world"])("test %s", (arg) => { 404 - expect(arg.length).toMatchInlineSnapshot(\`5\`); 405 - }); 406 - 407 - describe.for(["hello", "world"])("suite %s", (arg) => { 408 - test("length", () => { 409 - expect(arg.length).toMatchInlineSnapshot(\`5\`); 410 - }); 411 - }); 412 - 413 - test.for(["hello", "world"])("toThrowErrorMatchingInlineSnapshot %s", (arg) => { 414 - expect(() => { 415 - throw new Error(\`length = \${arg.length}\`); 416 - }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 417 - }); 418 - " 419 - `) 420 - expect(result.errorTree()).toMatchInlineSnapshot(` 421 - Object { 422 - "each.test.ts": Object { 423 - "suite hello": Object { 424 - "length": "passed", 425 - }, 426 - "suite world": Object { 427 - "length": "passed", 428 - }, 429 - "test hello": "passed", 430 - "test world": "passed", 431 - "toThrowErrorMatchingInlineSnapshot hello": "passed", 432 - "toThrowErrorMatchingInlineSnapshot world": "passed", 433 - }, 434 - } 435 - `) 436 - expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 437 - Object { 438 - "added": 6, 439 - "didUpdate": false, 440 - "failure": false, 441 - "filesAdded": 1, 442 - "filesRemoved": 0, 443 - "filesRemovedList": Array [], 444 - "filesUnmatched": 0, 445 - "filesUpdated": 0, 446 - "matched": 0, 447 - "total": 6, 448 - "unchecked": 0, 449 - "uncheckedKeysByFile": Array [], 450 - "unmatched": 0, 451 - "updated": 0, 452 - } 453 - `) 454 - 455 - // edit tests to introduce errors 456 - editFile(testFile, s => s.replaceAll(`"hello"`, `"hey"`)) 457 - 458 - // fails with update=false 459 - result = await runVitest({ root, include: [testFile], update: false }) 460 - expect(result.stderr).toMatchInlineSnapshot(` 461 - " 462 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯ 463 - 464 - FAIL each.test.ts > test hey 465 - Error: Snapshot \`test hey 1\` mismatched 466 - 467 - Expected: "5" 468 - Received: "3" 469 - 470 - ❯ each.test.ts:4:22 471 - 2| 472 - 3| test.for(["hey", "world"])("test %s", (arg) => { 473 - 4| expect(arg.length).toMatchInlineSnapshot(\`5\`); 474 - | ^ 475 - 5| }); 476 - 6| 477 - 478 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ 479 - 480 - FAIL each.test.ts > test world 481 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 482 - 483 - Expected: "3" 484 - Received: "5" 485 - 486 - ❯ each.test.ts:4:22 487 - 2| 488 - 3| test.for(["hey", "world"])("test %s", (arg) => { 489 - 4| expect(arg.length).toMatchInlineSnapshot(\`5\`); 490 - | ^ 491 - 5| }); 492 - 6| 493 - 494 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ 495 - 496 - FAIL each.test.ts > suite hey > length 497 - Error: Snapshot \`suite hey > length 1\` mismatched 498 - 499 - Expected: "5" 500 - Received: "3" 501 - 502 - ❯ each.test.ts:9:24 503 - 7| describe.for(["hey", "world"])("suite %s", (arg) => { 504 - 8| test("length", () => { 505 - 9| expect(arg.length).toMatchInlineSnapshot(\`5\`); 506 - | ^ 507 - 10| }); 508 - 11| }); 509 - 510 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ 511 - 512 - FAIL each.test.ts > suite world > length 513 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 514 - 515 - Expected: "3" 516 - Received: "5" 517 - 518 - ❯ each.test.ts:9:24 519 - 7| describe.for(["hey", "world"])("suite %s", (arg) => { 520 - 8| test("length", () => { 521 - 9| expect(arg.length).toMatchInlineSnapshot(\`5\`); 522 - | ^ 523 - 10| }); 524 - 11| }); 525 - 526 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ 527 - 528 - FAIL each.test.ts > toThrowErrorMatchingInlineSnapshot hey 529 - Error: Snapshot \`toThrowErrorMatchingInlineSnapshot hey 1\` mismatched 530 - 531 - Expected: "[Error: length = 5]" 532 - Received: "[Error: length = 3]" 533 - 534 - ❯ each.test.ts:16:6 535 - 14| expect(() => { 536 - 15| throw new Error(\`length = \${arg.length}\`); 537 - 16| }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 538 - | ^ 539 - 17| }); 540 - 18| 541 - 542 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ 543 - 544 - FAIL each.test.ts > toThrowErrorMatchingInlineSnapshot world 545 - Error: toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location 546 - 547 - Expected: "[Error: length = 3]" 548 - Received: "[Error: length = 5]" 549 - 550 - ❯ each.test.ts:16:6 551 - 14| expect(() => { 552 - 15| throw new Error(\`length = \${arg.length}\`); 553 - 16| }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 554 - | ^ 555 - 17| }); 556 - 18| 557 - 558 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯ 559 - 560 - " 561 - `) 562 - expect(result.errorTree()).toMatchInlineSnapshot(` 563 - Object { 564 - "each.test.ts": Object { 565 - "suite hey": Object { 566 - "length": Array [ 567 - "Snapshot \`suite hey > length 1\` mismatched", 568 - ], 569 - }, 570 - "suite world": Object { 571 - "length": Array [ 572 - "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 573 - ], 574 - }, 575 - "test hey": Array [ 576 - "Snapshot \`test hey 1\` mismatched", 577 - ], 578 - "test world": Array [ 579 - "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 580 - ], 581 - "toThrowErrorMatchingInlineSnapshot hey": Array [ 582 - "Snapshot \`toThrowErrorMatchingInlineSnapshot hey 1\` mismatched", 583 - ], 584 - "toThrowErrorMatchingInlineSnapshot world": Array [ 585 - "toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location", 586 - ], 587 - }, 588 - } 589 - `) 590 - expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 591 - Object { 592 - "added": 0, 593 - "didUpdate": false, 594 - "failure": false, 595 - "filesAdded": 0, 596 - "filesRemoved": 0, 597 - "filesRemovedList": Array [], 598 - "filesUnmatched": 1, 599 - "filesUpdated": 0, 600 - "matched": 0, 601 - "total": 3, 602 - "unchecked": 0, 603 - "uncheckedKeysByFile": Array [], 604 - "unmatched": 3, 605 - "updated": 0, 606 - } 607 - `) 608 - 609 - // fails with update=all 610 - result = await runVitest({ root, include: [testFile], update: 'all' }) 611 - expect(result.stderr).toMatchInlineSnapshot(` 612 - " 613 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 614 - 615 - FAIL each.test.ts > test world 616 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 617 - 618 - Expected: "3" 619 - Received: "5" 620 - 621 - ❯ each.test.ts:4:22 622 - 2| 623 - 3| test.for(["hey", "world"])("test %s", (arg) => { 624 - 4| expect(arg.length).toMatchInlineSnapshot(\`5\`); 625 - | ^ 626 - 5| }); 627 - 6| 628 - 629 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 630 - 631 - FAIL each.test.ts > suite world > length 632 - Error: toMatchInlineSnapshot with different snapshots cannot be called at the same location 633 - 634 - Expected: "3" 635 - Received: "5" 636 - 637 - ❯ each.test.ts:9:24 638 - 7| describe.for(["hey", "world"])("suite %s", (arg) => { 639 - 8| test("length", () => { 640 - 9| expect(arg.length).toMatchInlineSnapshot(\`5\`); 641 - | ^ 642 - 10| }); 643 - 11| }); 644 - 645 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 646 - 647 - FAIL each.test.ts > toThrowErrorMatchingInlineSnapshot world 648 - Error: toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location 649 - 650 - Expected: "[Error: length = 3]" 651 - Received: "[Error: length = 5]" 652 - 653 - ❯ each.test.ts:16:6 654 - 14| expect(() => { 655 - 15| throw new Error(\`length = \${arg.length}\`); 656 - 16| }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 657 - | ^ 658 - 17| }); 659 - 18| 660 - 661 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 662 - 663 - " 664 - `) 665 - expect(result.errorTree()).toMatchInlineSnapshot(` 666 - Object { 667 - "each.test.ts": Object { 668 - "suite hey": Object { 669 - "length": "passed", 670 - }, 671 - "suite world": Object { 672 - "length": Array [ 673 - "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 674 - ], 675 - }, 676 - "test hey": "passed", 677 - "test world": Array [ 678 - "toMatchInlineSnapshot with different snapshots cannot be called at the same location", 679 - ], 680 - "toThrowErrorMatchingInlineSnapshot hey": "passed", 681 - "toThrowErrorMatchingInlineSnapshot world": Array [ 682 - "toThrowErrorMatchingInlineSnapshot with different snapshots cannot be called at the same location", 683 - ], 684 - }, 685 - } 686 - `) 687 - expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 688 - "import { expect, test, describe } from "vitest"; 689 - 690 - test.for(["hey", "world"])("test %s", (arg) => { 691 - expect(arg.length).toMatchInlineSnapshot(\`5\`); 692 - }); 693 - 694 - describe.for(["hey", "world"])("suite %s", (arg) => { 695 - test("length", () => { 696 - expect(arg.length).toMatchInlineSnapshot(\`5\`); 697 - }); 698 - }); 699 - 700 - test.for(["hey", "world"])("toThrowErrorMatchingInlineSnapshot %s", (arg) => { 701 - expect(() => { 702 - throw new Error(\`length = \${arg.length}\`); 703 - }).toThrowErrorMatchingInlineSnapshot(\`[Error: length = 5]\`) 704 - }); 705 - " 706 - `) 707 - expect(result.ctx?.snapshot.summary).toMatchInlineSnapshot(` 708 - Object { 709 - "added": 0, 710 - "didUpdate": true, 711 - "failure": false, 712 - "filesAdded": 0, 713 - "filesRemoved": 0, 714 - "filesRemovedList": Array [], 715 - "filesUnmatched": 0, 716 - "filesUpdated": 1, 717 - "matched": 0, 718 - "total": 3, 719 - "unchecked": 0, 720 - "uncheckedKeysByFile": Array [], 721 - "unmatched": 0, 722 - "updated": 3, 723 - } 724 - `) 725 - })
-62
test/snapshots/test/jest-image-snapshot.test.ts
··· 1 - import fs from 'node:fs' 2 - import { join } from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { runVitest } from '../../test-utils' 5 - 6 - test('jest-image-snapshot', async () => { 7 - // cleanup snapshot 8 - const root = join(import.meta.dirname, 'fixtures/jest-image-snapshot') 9 - fs.rmSync(join(root, '__image_snapshots__'), { recursive: true, force: true }) 10 - 11 - // write snapshot 12 - let vitest = await runVitest({ 13 - root, 14 - update: true, 15 - }) 16 - expect(vitest.stderr).toBe('') 17 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 18 - Object { 19 - "added": 1, 20 - "didUpdate": true, 21 - "failure": false, 22 - "filesAdded": 1, 23 - "filesRemoved": 0, 24 - "filesRemovedList": Array [], 25 - "filesUnmatched": 0, 26 - "filesUpdated": 0, 27 - "matched": 0, 28 - "total": 1, 29 - "unchecked": 0, 30 - "uncheckedKeysByFile": Array [], 31 - "unmatched": 0, 32 - "updated": 0, 33 - } 34 - `) 35 - expect(fs.existsSync(join(root, '__image_snapshots__/basic-test-ts-to-match-image-snapshot-1-snap.png'))).toBe(true) 36 - 37 - // match existing snapshot 38 - vitest = await runVitest({ 39 - root, 40 - update: false, 41 - }) 42 - expect(vitest.stderr).toBe('') 43 - expect(vitest.ctx?.snapshot.summary).toMatchInlineSnapshot(` 44 - Object { 45 - "added": 0, 46 - "didUpdate": false, 47 - "failure": false, 48 - "filesAdded": 0, 49 - "filesRemoved": 0, 50 - "filesRemovedList": Array [], 51 - "filesUnmatched": 0, 52 - "filesUpdated": 0, 53 - "matched": 1, 54 - "total": 1, 55 - "unchecked": 0, 56 - "uncheckedKeysByFile": Array [], 57 - "unmatched": 0, 58 - "updated": 0, 59 - } 60 - `) 61 - expect(fs.existsSync(join(root, '__image_snapshots__/basic-test-ts-to-match-image-snapshot-1-snap.png'))).toBe(true) 62 - })
-68
test/snapshots/test/obsolete.test.ts
··· 1 - import fs from 'node:fs' 2 - import path from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { runVitest } from '../../test-utils' 5 - 6 - test('obsolete snapshot fails with update:none', async () => { 7 - // cleanup snapshot 8 - const root = path.join(import.meta.dirname, 'fixtures/obsolete') 9 - fs.rmSync(path.join(root, 'src/__snapshots__'), { recursive: true, force: true }) 10 - 11 - // initial run to write snapshot 12 - let result = await runVitest({ root, update: true }) 13 - expect(result.stderr).toBe('') 14 - expect(result.errorTree()).toMatchInlineSnapshot(` 15 - Object { 16 - "src/test1.test.ts": Object { 17 - "bar": "passed", 18 - "foo": "passed", 19 - "fuu": "passed", 20 - }, 21 - "src/test2.test.ts": Object { 22 - "bar": "passed", 23 - "foo": "passed", 24 - }, 25 - } 26 - `) 27 - 28 - // test fails with obsolete snapshots 29 - result = await runVitest({ 30 - root, 31 - update: 'none', 32 - env: { 33 - TEST_OBSOLETE: 'true', 34 - }, 35 - }) 36 - expect(result.stderr).toMatchInlineSnapshot(` 37 - " 38 - ⎯⎯⎯⎯⎯⎯ Failed Suites 1 ⎯⎯⎯⎯⎯⎯⎯ 39 - 40 - FAIL src/test1.test.ts [ src/test1.test.ts ] 41 - Error: Obsolete snapshots found when no snapshot update is expected. 42 - · foo 1 43 - · fuu 1 44 - 45 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ 46 - 47 - " 48 - `) 49 - expect(result.errorTree()).toMatchInlineSnapshot(` 50 - Object { 51 - "src/test1.test.ts": Object { 52 - "__module_errors__": Array [ 53 - "Obsolete snapshots found when no snapshot update is expected. 54 - · foo 1 55 - · fuu 1 56 - ", 57 - ], 58 - "bar": "passed", 59 - "foo": "passed", 60 - "fuu": "passed", 61 - }, 62 - "src/test2.test.ts": Object { 63 - "bar": "passed", 64 - "foo": "passed", 65 - }, 66 - } 67 - `) 68 - })
-80
test/snapshots/test/options.test.ts
··· 1 - import { describe, expect, test } from 'vitest' 2 - import { runInlineTests } from '../../test-utils' 3 - 4 - describe('maxOutputLength', () => { 5 - test('default', async () => { 6 - const result = await runInlineTests( 7 - { 8 - 'basic.test.ts': ` 9 - import { expect, test } from 'vitest' 10 - 11 - test('large snapshot', () => { 12 - expect(Array.from({ length: 500_000 }, (_, i) => ({ i }))).toMatchSnapshot() 13 - }) 14 - `, 15 - }, 16 - { 17 - update: 'all', 18 - }, 19 - ) 20 - 21 - expect(result.stderr).toMatchInlineSnapshot(`""`) 22 - const snapshot = result.fs.readFile('__snapshots__/basic.test.ts.snap') 23 - expect(snapshot.slice(-50)).toMatchInlineSnapshot(` 24 - " "i": 499998, 25 - }, 26 - { 27 - "i": 499999, 28 - }, 29 - ] 30 - \`; 31 - " 32 - `) 33 - expect(snapshot.length).toMatchInlineSnapshot(`12888992`) 34 - }) 35 - 36 - test('override', async () => { 37 - const result = await runInlineTests( 38 - { 39 - 'basic.test.ts': ` 40 - import { expect, test } from 'vitest' 41 - 42 - test('large snapshot', () => { 43 - expect(Array.from({ length: 8 }, (_, i) => ({ i }))).toMatchSnapshot() 44 - }) 45 - `, 46 - }, 47 - { 48 - update: 'all', 49 - snapshotFormat: { 50 - maxOutputLength: 50, 51 - }, 52 - }, 53 - ) 54 - 55 - expect(result.stderr).toMatchInlineSnapshot(`""`) 56 - expect(result.fs.readFile('__snapshots__/basic.test.ts.snap')).toMatchInlineSnapshot(` 57 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 58 - 59 - exports[\`large snapshot 1\`] = \` 60 - [ 61 - { 62 - "i": 0, 63 - }, 64 - { 65 - "i": 1, 66 - }, 67 - { 68 - "i": 2, 69 - }, 70 - [Object], 71 - [Object], 72 - [Object], 73 - [Object], 74 - [Object], 75 - ] 76 - \`; 77 - " 78 - `) 79 - }) 80 - })
-324
test/snapshots/test/properties.test.ts
··· 1 - import fs, { readFileSync } from 'node:fs' 2 - import { join } from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - 6 - const INLINE_BLOCK_RE = /\/\/ -- TEST INLINE START --\n([\s\S]*?)\/\/ -- TEST INLINE END --/g 7 - 8 - function extractInlineBlocks(content: string): string { 9 - return [...content.matchAll(INLINE_BLOCK_RE)].map(m => m[1].trim()).join('\n\n') 10 - } 11 - 12 - test('toMatchSnapshot and toMatchInlineSnapshot with properties', async () => { 13 - const root = join(import.meta.dirname, 'fixtures/properties') 14 - const testFile = join(root, 'basic.test.ts') 15 - const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 16 - 17 - // remove snapshots 18 - fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 19 - editFile(testFile, s => 20 - s.replace(/toMatchInlineSnapshot\((\{[^}]*\}),\s*`[^`]*`\)/g, 'toMatchInlineSnapshot($1)')) 21 - 22 - // create snapshots from scratch 23 - let result = await runVitest({ root, update: 'new' }) 24 - expect(result.stderr).toMatchInlineSnapshot(`""`) 25 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 26 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 27 - 28 - exports[\`file 1\`] = \` 29 - Object { 30 - "age": Any<Number>, 31 - "name": "alice", 32 - } 33 - \`; 34 - 35 - exports[\`file asymmetric 1\`] = \` 36 - Object { 37 - "name": "bob", 38 - "score": toSatisfy<[Function lessThan100]>, 39 - } 40 - \`; 41 - 42 - exports[\`file snapshot-only 1\`] = \` 43 - Object { 44 - "age": Any<Number>, 45 - "name": "dave", 46 - } 47 - \`; 48 - " 49 - `) 50 - expect(extractInlineBlocks(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 51 - "test("inline", () => { 52 - expect({ name: "carol", age: 25 }).toMatchInlineSnapshot({ age: expect.any(Number) }, \` 53 - Object { 54 - "age": Any<Number>, 55 - "name": "carol", 56 - } 57 - \`); 58 - });" 59 - `) 60 - expect(result.errorTree()).toMatchInlineSnapshot(` 61 - Object { 62 - "basic.test.ts": Object { 63 - "file": "passed", 64 - "file asymmetric": "passed", 65 - "file snapshot-only": "passed", 66 - "inline": "passed", 67 - }, 68 - } 69 - `) 70 - 71 - // verify idempotency — re-run without update passes cleanly 72 - const result2 = await runVitest({ root, update: 'none' }) 73 - expect(result2.stderr).toMatchInlineSnapshot(`""`) 74 - expect(result2.errorTree()).toEqual(result.errorTree()) 75 - 76 - // edit tests to break properties check 77 - editFile(testFile, s => 78 - s 79 - .replace('age: 30', 'age: \'thirty\'') 80 - .replace('score: 95', 'score: 999') 81 - .replace('name: "dave"', 'name: "dave-edit"') 82 - .replace('age: 25', 'age: \'twenty-five\'')) 83 - 84 - // properties mismatch should NOT cause false-positive obsolete snapshot 85 - result = await runVitest({ root, update: 'none' }) 86 - expect(result.stderr).toMatchInlineSnapshot(` 87 - " 88 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 4 ⎯⎯⎯⎯⎯⎯⎯ 89 - 90 - FAIL basic.test.ts > file 91 - Error: Snapshot properties mismatched 92 - 93 - - Expected 94 - + Received 95 - 96 - { 97 - - "age": Any<Number>, 98 - + "age": "thirty", 99 - + "name": "alice", 100 - } 101 - 102 - ❯ basic.test.ts:4:44 103 - 2| 104 - 3| test("file", () => { 105 - 4| expect({ name: "alice", age: 'thirty' }).toMatchSnapshot({ age: expe… 106 - | ^ 107 - 5| }); 108 - 6| 109 - 110 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯ 111 - 112 - FAIL basic.test.ts > file asymmetric 113 - Error: Snapshot properties mismatched 114 - 115 - - Expected 116 - + Received 117 - 118 - { 119 - - "score": toSatisfy<[Function lessThan100]>, 120 - + "name": "bob", 121 - + "score": 999, 122 - } 123 - 124 - ❯ basic.test.ts:8:39 125 - 6| 126 - 7| test("file asymmetric", () => { 127 - 8| expect({ name: "bob", score: 999 }).toMatchSnapshot({ 128 - | ^ 129 - 9| score: expect.toSatisfy(function lessThan100(n) { 130 - 10| return n < 100; 131 - 132 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/4]⎯ 133 - 134 - FAIL basic.test.ts > file snapshot-only 135 - Error: Snapshot \`file snapshot-only 1\` mismatched 136 - 137 - - Expected 138 - + Received 139 - 140 - Object { 141 - "age": Any<Number>, 142 - - "name": "dave", 143 - + "name": "dave-edit", 144 - } 145 - 146 - ❯ basic.test.ts:16:42 147 - 14| 148 - 15| test("file snapshot-only", () => { 149 - 16| expect({ name: "dave-edit", age: 42 }).toMatchSnapshot({ age: expect… 150 - | ^ 151 - 17| }); 152 - 18| 153 - 154 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/4]⎯ 155 - 156 - FAIL basic.test.ts > inline 157 - Error: Snapshot properties mismatched 158 - 159 - - Expected 160 - + Received 161 - 162 - { 163 - - "age": Any<Number>, 164 - + "age": "twenty-five", 165 - + "name": "carol", 166 - } 167 - 168 - ❯ basic.test.ts:21:49 169 - 19| // -- TEST INLINE START -- 170 - 20| test("inline", () => { 171 - 21| expect({ name: "carol", age: 'twenty-five' }).toMatchInlineSnapshot(… 172 - | ^ 173 - 22| Object { 174 - 23| "age": Any<Number>, 175 - 176 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/4]⎯ 177 - 178 - " 179 - `) 180 - expect(result.errorTree()).toMatchInlineSnapshot(` 181 - Object { 182 - "basic.test.ts": Object { 183 - "file": Array [ 184 - "Snapshot properties mismatched", 185 - ], 186 - "file asymmetric": Array [ 187 - "Snapshot properties mismatched", 188 - ], 189 - "file snapshot-only": Array [ 190 - "Snapshot \`file snapshot-only 1\` mismatched", 191 - ], 192 - "inline": Array [ 193 - "Snapshot properties mismatched", 194 - ], 195 - }, 196 - } 197 - `) 198 - 199 - // run with update — properties errors persist 200 - result = await runVitest({ root, update: 'all' }) 201 - expect(result.stderr).toMatchInlineSnapshot(` 202 - " 203 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 204 - 205 - FAIL basic.test.ts > file 206 - Error: Snapshot properties mismatched 207 - 208 - - Expected 209 - + Received 210 - 211 - { 212 - - "age": Any<Number>, 213 - + "age": "thirty", 214 - + "name": "alice", 215 - } 216 - 217 - ❯ basic.test.ts:4:44 218 - 2| 219 - 3| test("file", () => { 220 - 4| expect({ name: "alice", age: 'thirty' }).toMatchSnapshot({ age: expe… 221 - | ^ 222 - 5| }); 223 - 6| 224 - 225 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯ 226 - 227 - FAIL basic.test.ts > file asymmetric 228 - Error: Snapshot properties mismatched 229 - 230 - - Expected 231 - + Received 232 - 233 - { 234 - - "score": toSatisfy<[Function lessThan100]>, 235 - + "name": "bob", 236 - + "score": 999, 237 - } 238 - 239 - ❯ basic.test.ts:8:39 240 - 6| 241 - 7| test("file asymmetric", () => { 242 - 8| expect({ name: "bob", score: 999 }).toMatchSnapshot({ 243 - | ^ 244 - 9| score: expect.toSatisfy(function lessThan100(n) { 245 - 10| return n < 100; 246 - 247 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯ 248 - 249 - FAIL basic.test.ts > inline 250 - Error: Snapshot properties mismatched 251 - 252 - - Expected 253 - + Received 254 - 255 - { 256 - - "age": Any<Number>, 257 - + "age": "twenty-five", 258 - + "name": "carol", 259 - } 260 - 261 - ❯ basic.test.ts:21:49 262 - 19| // -- TEST INLINE START -- 263 - 20| test("inline", () => { 264 - 21| expect({ name: "carol", age: 'twenty-five' }).toMatchInlineSnapshot(… 265 - | ^ 266 - 22| Object { 267 - 23| "age": Any<Number>, 268 - 269 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯ 270 - 271 - " 272 - `) 273 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 274 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 275 - 276 - exports[\`file 1\`] = \` 277 - Object { 278 - "age": Any<Number>, 279 - "name": "alice", 280 - } 281 - \`; 282 - 283 - exports[\`file asymmetric 1\`] = \` 284 - Object { 285 - "name": "bob", 286 - "score": toSatisfy<[Function lessThan100]>, 287 - } 288 - \`; 289 - 290 - exports[\`file snapshot-only 1\`] = \` 291 - Object { 292 - "age": Any<Number>, 293 - "name": "dave-edit", 294 - } 295 - \`; 296 - " 297 - `) 298 - expect(extractInlineBlocks(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(` 299 - "test("inline", () => { 300 - expect({ name: "carol", age: 'twenty-five' }).toMatchInlineSnapshot({ age: expect.any(Number) }, \` 301 - Object { 302 - "age": Any<Number>, 303 - "name": "carol", 304 - } 305 - \`); 306 - });" 307 - `) 308 - expect(result.errorTree()).toMatchInlineSnapshot(` 309 - Object { 310 - "basic.test.ts": Object { 311 - "file": Array [ 312 - "Snapshot properties mismatched", 313 - ], 314 - "file asymmetric": Array [ 315 - "Snapshot properties mismatched", 316 - ], 317 - "file snapshot-only": "passed", 318 - "inline": Array [ 319 - "Snapshot properties mismatched", 320 - ], 321 - }, 322 - } 323 - `) 324 - })
-114
test/snapshots/test/skip-test.test.ts
··· 1 - import fs from 'node:fs' 2 - import path from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { runVitest } from '../../test-utils' 5 - 6 - test('snapshots in skipped test/suite is not obsolete', async () => { 7 - // create snapshot on first run 8 - fs.rmSync('test/fixtures/skip-test/__snapshots__', { recursive: true, force: true }) 9 - let vitest = await runVitest({ 10 - root: 'test/fixtures/skip-test', 11 - update: true, 12 - }) 13 - expect(vitest.stdout).toContain('Snapshots 2 written') 14 - expect(fs.readFileSync('test/fixtures/skip-test/__snapshots__/repro.test.ts.snap', 'utf-8')).toMatchInlineSnapshot(` 15 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 16 - 17 - exports[\`repro suite > inner case 1\`] = \`"hi-1"\`; 18 - 19 - exports[\`top-level case 1\`] = \`"hi-2"\`; 20 - " 21 - `) 22 - 23 - // running with `skipIf` enabled should not show "obsolete" 24 - vitest = await runVitest({ 25 - root: 'test/fixtures/skip-test', 26 - env: { 27 - ENABLE_SKIP: '1', 28 - }, 29 - }) 30 - expect(vitest.stdout).toContain('2 skipped') 31 - expect(vitest.stdout).not.toContain('obsolete') 32 - 33 - // running with `skipIf` and `update` should keep snapshots 34 - vitest = await runVitest({ 35 - root: 'test/fixtures/skip-test', 36 - update: true, 37 - env: { 38 - ENABLE_SKIP: '1', 39 - }, 40 - }) 41 - expect(fs.readFileSync('test/fixtures/skip-test/__snapshots__/repro.test.ts.snap', 'utf-8')).toMatchInlineSnapshot(` 42 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 43 - 44 - exports[\`repro suite > inner case 1\`] = \`"hi-1"\`; 45 - 46 - exports[\`top-level case 1\`] = \`"hi-2"\`; 47 - " 48 - `) 49 - }) 50 - 51 - test('handle obsoleteness of toMatchSnapshot("custom message")', async () => { 52 - const root = path.join(import.meta.dirname, './fixtures/skip-test-custom') 53 - 54 - // clear snapshots 55 - fs.rmSync(path.join(root, '__snapshots__'), { recursive: true, force: true }) 56 - 57 - // create snapshot on first run 58 - let vitest = await runVitest({ 59 - root, 60 - update: true, 61 - }) 62 - expect(vitest.stdout).toContain('Snapshots 4 written') 63 - expect(fs.readFileSync(path.join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 64 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 65 - 66 - exports[\`custom a > x 1\`] = \`0\`; 67 - 68 - exports[\`custom a > y 1\`] = \`0\`; 69 - 70 - exports[\`custom b > w 1\`] = \`0\`; 71 - 72 - exports[\`custom b > z 1\`] = \`0\`; 73 - " 74 - `) 75 - 76 - // Skipped tests' `toMatchSnapshot("...")` is not considered obsolete 77 - vitest = await runVitest({ 78 - root, 79 - testNamePattern: 'custom a', 80 - }) 81 - expect(vitest.stdout).toContain('1 passed') 82 - expect(vitest.stdout).toContain('1 skipped') 83 - expect(vitest.stdout).not.toContain('obsolete') 84 - 85 - vitest = await runVitest({ 86 - root, 87 - testNamePattern: 'custom b', 88 - }) 89 - expect(vitest.stdout).toContain('1 passed') 90 - expect(vitest.stdout).toContain('1 skipped') 91 - expect(vitest.stdout).not.toContain('obsolete') 92 - 93 - // check snapshot doesn't change when skip + update 94 - vitest = await runVitest({ 95 - root, 96 - update: true, 97 - testNamePattern: 'custom a', 98 - }) 99 - expect(vitest.stdout).toContain('1 passed') 100 - expect(vitest.stdout).toContain('1 skipped') 101 - expect(vitest.stdout).not.toContain('obsolete') 102 - expect(fs.readFileSync(path.join(root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` 103 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 104 - 105 - exports[\`custom a > x 1\`] = \`0\`; 106 - 107 - exports[\`custom a > y 1\`] = \`0\`; 108 - 109 - exports[\`custom b > w 1\`] = \`0\`; 110 - 111 - exports[\`custom b > z 1\`] = \`0\`; 112 - " 113 - `) 114 - })
-120
test/snapshots/test/snapshots.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - import { editFile, runInlineTests, runVitest } from '../../test-utils' 4 - 5 - test('non default snapshot format', () => { 6 - expect({ foo: ['bar'] }).toMatchInlineSnapshot(` 7 - Object { 8 - "foo": Array [ 9 - "bar", 10 - ], 11 - } 12 - `) 13 - }) 14 - 15 - test('--update works for workspace project', async () => { 16 - // setup wrong snapshot value 17 - editFile( 18 - 'test/fixtures/workspace/packages/space/test/__snapshots__/basic.test.ts.snap', 19 - data => data.replace('`1`', '`2`'), 20 - ) 21 - 22 - // run with --update 23 - const { stdout, exitCode } = await runVitest({ 24 - update: true, 25 - root: 'test/fixtures/workspace', 26 - }) 27 - expect.soft(stdout).include('Snapshots 1 updated') 28 - expect.soft(exitCode).toBe(0) 29 - }) 30 - 31 - test('test.fails fails snapshot', async () => { 32 - const result = await runInlineTests({ 33 - 'basic.test.ts': ` 34 - import { expect, test } from 'vitest' 35 - 36 - test.fails('file', () => { 37 - expect('a').toMatchSnapshot() 38 - }) 39 - 40 - test.fails('inline', () => { 41 - expect('b').toMatchInlineSnapshot() 42 - }) 43 - 44 - test.fails('soft', () => { 45 - expect.soft('c').toMatchSnapshot() 46 - expect.soft('d').toMatchInlineSnapshot() 47 - }) 48 - `, 49 - }) 50 - expect(result.stderr).toMatchInlineSnapshot(` 51 - " 52 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 53 - 54 - FAIL basic.test.ts > file 55 - TestSyntaxError: 'toMatchSnapshot' cannot be used with 'test.fails' 56 - ❯ basic.test.ts:5:15 57 - 3| 58 - 4| test.fails('file', () => { 59 - 5| expect('a').toMatchSnapshot() 60 - | ^ 61 - 6| }) 62 - 7| 63 - 64 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯ 65 - 66 - FAIL basic.test.ts > inline 67 - TestSyntaxError: 'toMatchInlineSnapshot' cannot be used with 'test.fails' 68 - ❯ basic.test.ts:9:15 69 - 7| 70 - 8| test.fails('inline', () => { 71 - 9| expect('b').toMatchInlineSnapshot() 72 - | ^ 73 - 10| }) 74 - 11| 75 - 76 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/4]⎯ 77 - 78 - FAIL basic.test.ts > soft 79 - TestSyntaxError: 'toMatchSnapshot' cannot be used with 'test.fails' 80 - ❯ basic.test.ts:13:20 81 - 11| 82 - 12| test.fails('soft', () => { 83 - 13| expect.soft('c').toMatchSnapshot() 84 - | ^ 85 - 14| expect.soft('d').toMatchInlineSnapshot() 86 - 15| }) 87 - 88 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/4]⎯ 89 - 90 - FAIL basic.test.ts > soft 91 - TestSyntaxError: 'toMatchInlineSnapshot' cannot be used with 'test.fails' 92 - ❯ basic.test.ts:14:20 93 - 12| test.fails('soft', () => { 94 - 13| expect.soft('c').toMatchSnapshot() 95 - 14| expect.soft('d').toMatchInlineSnapshot() 96 - | ^ 97 - 15| }) 98 - 16| 99 - 100 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/4]⎯ 101 - 102 - " 103 - `) 104 - expect(result.errorTree()).toMatchInlineSnapshot(` 105 - Object { 106 - "basic.test.ts": Object { 107 - "file": Array [ 108 - "'toMatchSnapshot' cannot be used with 'test.fails'", 109 - ], 110 - "inline": Array [ 111 - "'toMatchInlineSnapshot' cannot be used with 'test.fails'", 112 - ], 113 - "soft": Array [ 114 - "'toMatchSnapshot' cannot be used with 'test.fails'", 115 - "'toMatchInlineSnapshot' cannot be used with 'test.fails'", 116 - ], 117 - }, 118 - } 119 - `) 120 - })
-89
test/snapshots/test/soft-inline.test.ts
··· 1 - import { readFileSync } from 'node:fs' 2 - import { join } from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - 6 - test('soft inline', async () => { 7 - const root = join(import.meta.dirname, 'fixtures/soft-inline') 8 - const testFile = join(root, 'basic.test.ts') 9 - 10 - // remove inline snapshots 11 - editFile(testFile, s => s 12 - .replace(/toMatchInlineSnapshot\(`[^`]*`\)/g, 'toMatchInlineSnapshot()') 13 - .replace(/toThrowErrorMatchingInlineSnapshot\(`[^`]*`\)/g, 'toThrowErrorMatchingInlineSnapshot()')) 14 - 15 - // create snapshots from scratch 16 - let result = await runVitest({ root, update: 'new' }) 17 - expect(result.stderr).toMatchInlineSnapshot(`""`) 18 - expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 19 - "import { expect, test } from 'vitest' 20 - 21 - test('toMatchInlineSnapshot', () => { 22 - expect.soft('--snap-1--').toMatchInlineSnapshot(\`"--snap-1--"\`) 23 - expect.soft('--snap-2--').toMatchInlineSnapshot(\`"--snap-2--"\`) 24 - }) 25 - 26 - test('toThrowErrorMatchingInlineSnapshot', () => { 27 - expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-1--]\`) 28 - expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-2--]\`) 29 - }) 30 - " 31 - `) 32 - expect(result.errorTree()).toMatchInlineSnapshot(` 33 - Object { 34 - "basic.test.ts": Object { 35 - "toMatchInlineSnapshot": "passed", 36 - "toThrowErrorMatchingInlineSnapshot": "passed", 37 - }, 38 - } 39 - `) 40 - 41 - // edit tests to introduce snapshot errors 42 - editFile(testFile, s => s 43 - .replace('expect.soft(\'--snap-1--\')', 'expect.soft(\'--snap-1-edit--\')') 44 - .replace('expect.soft(\'--snap-2--\')', 'expect.soft(\'--snap-2-edit--\')') 45 - .replace('new Error(\'--error-1--\')', 'new Error(\'--error-1-edit--\')') 46 - .replace('new Error(\'--error-2--\')', 'new Error(\'--error-2-edit--\')')) 47 - 48 - result = await runVitest({ root, update: false }) 49 - expect(result.errorTree()).toMatchInlineSnapshot(` 50 - Object { 51 - "basic.test.ts": Object { 52 - "toMatchInlineSnapshot": Array [ 53 - "Snapshot \`toMatchInlineSnapshot 1\` mismatched", 54 - "Snapshot \`toMatchInlineSnapshot 2\` mismatched", 55 - ], 56 - "toThrowErrorMatchingInlineSnapshot": Array [ 57 - "Snapshot \`toThrowErrorMatchingInlineSnapshot 1\` mismatched", 58 - "Snapshot \`toThrowErrorMatchingInlineSnapshot 2\` mismatched", 59 - ], 60 - }, 61 - } 62 - `) 63 - 64 - // run with update 65 - result = await runVitest({ root, update: 'all' }) 66 - expect(result.stderr).toMatchInlineSnapshot(`""`) 67 - expect(readFileSync(testFile, 'utf-8')).toMatchInlineSnapshot(` 68 - "import { expect, test } from 'vitest' 69 - 70 - test('toMatchInlineSnapshot', () => { 71 - expect.soft('--snap-1-edit--').toMatchInlineSnapshot(\`"--snap-1-edit--"\`) 72 - expect.soft('--snap-2-edit--').toMatchInlineSnapshot(\`"--snap-2-edit--"\`) 73 - }) 74 - 75 - test('toThrowErrorMatchingInlineSnapshot', () => { 76 - expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-1-edit--]\`) 77 - expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowErrorMatchingInlineSnapshot(\`[Error: --error-2-edit--]\`) 78 - }) 79 - " 80 - `) 81 - expect(result.errorTree()).toMatchInlineSnapshot(` 82 - Object { 83 - "basic.test.ts": Object { 84 - "toMatchInlineSnapshot": "passed", 85 - "toThrowErrorMatchingInlineSnapshot": "passed", 86 - }, 87 - } 88 - `) 89 - })
-200
test/snapshots/test/soft.test.ts
··· 1 - import fs, { readFileSync } from 'node:fs' 2 - import { join } from 'node:path' 3 - import { expect, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - 6 - test('soft', async () => { 7 - const root = join(import.meta.dirname, 'fixtures/soft') 8 - const testFile = join(root, 'basic.test.ts') 9 - const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 10 - const customFile1 = join(root, '__snapshots__/custom1.txt') 11 - const customFile2 = join(root, '__snapshots__/custom2.txt') 12 - 13 - // remove snapshots 14 - fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true }) 15 - 16 - // create snapshots from scratch 17 - let result = await runVitest({ root, update: 'new' }) 18 - expect(result.stderr).toMatchInlineSnapshot(`""`) 19 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 20 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 21 - 22 - exports[\`toMatchSnapshot 1\`] = \`"--snap-1--"\`; 23 - 24 - exports[\`toMatchSnapshot 2\`] = \`"--snap-2--"\`; 25 - 26 - exports[\`toThrowErrorMatchingSnapshot 1\`] = \`[Error: --error-1--]\`; 27 - 28 - exports[\`toThrowErrorMatchingSnapshot 2\`] = \`[Error: --error-2--]\`; 29 - " 30 - `) 31 - expect(readFileSync(customFile1, 'utf-8')).toMatchInlineSnapshot(`"--file-1--"`) 32 - expect(readFileSync(customFile2, 'utf-8')).toMatchInlineSnapshot(`"--file-2--"`) 33 - expect(result.errorTree()).toMatchInlineSnapshot(` 34 - Object { 35 - "basic.test.ts": Object { 36 - "toMatchFileSnapshot": "passed", 37 - "toMatchSnapshot": "passed", 38 - "toThrowErrorMatchingSnapshot": "passed", 39 - }, 40 - } 41 - `) 42 - 43 - // edit tests to introduce snapshot errors 44 - editFile(testFile, s => s 45 - .replace(`--snap-1--`, `--snap-1-edit--`) 46 - .replace(`--snap-2--`, `--snap-2-edit--`) 47 - .replace(`--file-1--`, `--file-1-edit--`) 48 - .replace(`--file-2--`, `--file-2-edit--`) 49 - .replace(`--error-1--`, `--error-1-edit--`) 50 - .replace(`--error-2--`, `--error-2-edit--`)) 51 - 52 - result = await runVitest({ root, update: false }) 53 - expect(result.stderr).toMatchInlineSnapshot(` 54 - " 55 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ 56 - 57 - FAIL basic.test.ts > toMatchSnapshot 58 - Error: Snapshot \`toMatchSnapshot 1\` mismatched 59 - 60 - Expected: ""--snap-1--"" 61 - Received: ""--snap-1-edit--"" 62 - 63 - ❯ basic.test.ts:4:34 64 - 2| 65 - 3| test('toMatchSnapshot', () => { 66 - 4| expect.soft('--snap-1-edit--').toMatchSnapshot() 67 - | ^ 68 - 5| expect.soft('--snap-2-edit--').toMatchSnapshot() 69 - 6| }) 70 - 71 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ 72 - 73 - FAIL basic.test.ts > toMatchSnapshot 74 - Error: Snapshot \`toMatchSnapshot 2\` mismatched 75 - 76 - Expected: ""--snap-2--"" 77 - Received: ""--snap-2-edit--"" 78 - 79 - ❯ basic.test.ts:5:34 80 - 3| test('toMatchSnapshot', () => { 81 - 4| expect.soft('--snap-1-edit--').toMatchSnapshot() 82 - 5| expect.soft('--snap-2-edit--').toMatchSnapshot() 83 - | ^ 84 - 6| }) 85 - 7| 86 - 87 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ 88 - 89 - FAIL basic.test.ts > toMatchFileSnapshot 90 - Error: Snapshot \`toMatchFileSnapshot 1\` mismatched 91 - 92 - Expected: "--file-1--" 93 - Received: "--file-1-edit--" 94 - 95 - ❯ basic.test.ts:9:3 96 - 7| 97 - 8| test('toMatchFileSnapshot', async () => { 98 - 9| await expect.soft('--file-1-edit--').toMatchFileSnapshot('./__snapsh… 99 - | ^ 100 - 10| await expect.soft('--file-2-edit--').toMatchFileSnapshot('./__snapsh… 101 - 11| }) 102 - 103 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ 104 - 105 - FAIL basic.test.ts > toMatchFileSnapshot 106 - Error: Snapshot \`toMatchFileSnapshot 2\` mismatched 107 - 108 - Expected: "--file-2--" 109 - Received: "--file-2-edit--" 110 - 111 - ❯ basic.test.ts:10:3 112 - 8| test('toMatchFileSnapshot', async () => { 113 - 9| await expect.soft('--file-1-edit--').toMatchFileSnapshot('./__snapsh… 114 - 10| await expect.soft('--file-2-edit--').toMatchFileSnapshot('./__snapsh… 115 - | ^ 116 - 11| }) 117 - 12| 118 - 119 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ 120 - 121 - FAIL basic.test.ts > toThrowErrorMatchingSnapshot 122 - Error: Snapshot \`toThrowErrorMatchingSnapshot 1\` mismatched 123 - 124 - Expected: "[Error: --error-1--]" 125 - Received: "[Error: --error-1-edit--]" 126 - 127 - ❯ basic.test.ts:14:62 128 - 12| 129 - 13| test('toThrowErrorMatchingSnapshot', () => { 130 - 14| expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowEr… 131 - | ^ 132 - 15| expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowEr… 133 - 16| }) 134 - 135 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ 136 - 137 - FAIL basic.test.ts > toThrowErrorMatchingSnapshot 138 - Error: Snapshot \`toThrowErrorMatchingSnapshot 2\` mismatched 139 - 140 - Expected: "[Error: --error-2--]" 141 - Received: "[Error: --error-2-edit--]" 142 - 143 - ❯ basic.test.ts:15:62 144 - 13| test('toThrowErrorMatchingSnapshot', () => { 145 - 14| expect.soft(() => { throw new Error('--error-1-edit--') }).toThrowEr… 146 - 15| expect.soft(() => { throw new Error('--error-2-edit--') }).toThrowEr… 147 - | ^ 148 - 16| }) 149 - 17| 150 - 151 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯ 152 - 153 - " 154 - `) 155 - expect(result.errorTree()).toMatchInlineSnapshot(` 156 - Object { 157 - "basic.test.ts": Object { 158 - "toMatchFileSnapshot": Array [ 159 - "Snapshot \`toMatchFileSnapshot 1\` mismatched", 160 - "Snapshot \`toMatchFileSnapshot 2\` mismatched", 161 - ], 162 - "toMatchSnapshot": Array [ 163 - "Snapshot \`toMatchSnapshot 1\` mismatched", 164 - "Snapshot \`toMatchSnapshot 2\` mismatched", 165 - ], 166 - "toThrowErrorMatchingSnapshot": Array [ 167 - "Snapshot \`toThrowErrorMatchingSnapshot 1\` mismatched", 168 - "Snapshot \`toThrowErrorMatchingSnapshot 2\` mismatched", 169 - ], 170 - }, 171 - } 172 - `) 173 - 174 - // run with update 175 - result = await runVitest({ root, update: 'all' }) 176 - expect(result.stderr).toMatchInlineSnapshot(`""`) 177 - expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 178 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 179 - 180 - exports[\`toMatchSnapshot 1\`] = \`"--snap-1-edit--"\`; 181 - 182 - exports[\`toMatchSnapshot 2\`] = \`"--snap-2-edit--"\`; 183 - 184 - exports[\`toThrowErrorMatchingSnapshot 1\`] = \`[Error: --error-1-edit--]\`; 185 - 186 - exports[\`toThrowErrorMatchingSnapshot 2\`] = \`[Error: --error-2-edit--]\`; 187 - " 188 - `) 189 - expect(readFileSync(customFile1, 'utf-8')).toMatchInlineSnapshot(`"--file-1-edit--"`) 190 - expect(readFileSync(customFile2, 'utf-8')).toMatchInlineSnapshot(`"--file-2-edit--"`) 191 - expect(result.errorTree()).toMatchInlineSnapshot(` 192 - Object { 193 - "basic.test.ts": Object { 194 - "toMatchFileSnapshot": "passed", 195 - "toMatchSnapshot": "passed", 196 - "toThrowErrorMatchingSnapshot": "passed", 197 - }, 198 - } 199 - `) 200 - })
-93
test/snapshots/test/summary.test.ts
··· 1 - import fs from 'node:fs' 2 - import { join } from 'node:path' 3 - import { assert, expect, onTestFailed, onTestFinished, test } from 'vitest' 4 - import { editFile, runVitest } from '../../test-utils' 5 - 6 - function fsUpdate(file: string, updateFn: (data: string) => string) { 7 - fs.writeFileSync(file, updateFn(fs.readFileSync(file, 'utf-8'))) 8 - } 9 - 10 - test('summary', async () => { 11 - // cleanup snapshot 12 - const dir = join(import.meta.dirname, 'fixtures/summary') 13 - const testFile = join(dir, 'basic.test.ts') 14 - const snapshotFile = join(dir, '__snapshots__/basic.test.ts.snap') 15 - fsUpdate(testFile, s => s.replace(/`"@SNAP\d"`/g, '')) 16 - fs.rmSync(snapshotFile, { recursive: true, force: true }) 17 - 18 - // write everything 19 - let vitest = await runVitest({ 20 - root: 'test/fixtures/summary', 21 - update: true, 22 - }) 23 - expect(vitest.stdout).toContain('Snapshots 12 written') 24 - 25 - // write partially 26 - fsUpdate(testFile, s => s.replace('`"@SNAP2"`', '')) 27 - fsUpdate(snapshotFile, s => s.replace('exports[`file repeats 1`] = `"@SNAP5"`;', '')) 28 - vitest = await runVitest({ 29 - root: 'test/fixtures/summary', 30 - update: true, 31 - }) 32 - expect(vitest.stdout).toContain('Snapshots 2 written') 33 - 34 - // update partially 35 - fsUpdate(testFile, s => s.replace('`"@SNAP2"`', '`"@WRONG"`')) 36 - fsUpdate(snapshotFile, s => s.replace('`"@SNAP5"`', '`"@WRONG"`')) 37 - vitest = await runVitest({ 38 - root: 'test/fixtures/summary', 39 - update: true, 40 - }) 41 - expect(vitest.stdout).toContain('Snapshots 2 updated') 42 - }) 43 - 44 - test('first obsolete then remove', async () => { 45 - const root = join(import.meta.dirname, 'fixtures/summary-removed') 46 - const testFile = join(root, 'basic.test.ts') 47 - const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap') 48 - 49 - // reset snapshot 50 - fs.rmSync(snapshotFile, { recursive: true, force: true }) 51 - await runVitest({ 52 - root, 53 - update: true, 54 - }) 55 - expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 56 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 57 - 58 - exports[\`x 1\`] = \`0\`; 59 - 60 - exports[\`y 1\`] = \`0\`; 61 - " 62 - `) 63 - 64 - // watch run 65 - const { ctx, ...result } = await runVitest( 66 - { 67 - watch: true, 68 - root, 69 - }, 70 - ) 71 - assert(ctx) 72 - onTestFinished(() => { 73 - ctx.close() 74 - }) 75 - onTestFailed(() => { 76 - console.error(result.vitest.stdout) 77 - console.error(result.vitest.stderr) 78 - }) 79 - 80 - // remove `toMatchSnapshot()` and rerun -> obsolete snapshot 81 - editFile(testFile, s => s.replace(/REMOVE-START.*REMOVE-END/s, '')) 82 - await result.vitest.waitForStdout('1 obsolete') 83 - 84 - // rerun with update -> remove snapshot 85 - await ctx.updateSnapshot() 86 - await result.vitest.waitForStdout('1 removed') 87 - expect(fs.readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(` 88 - "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 89 - 90 - exports[\`x 1\`] = \`0\`; 91 - " 92 - `) 93 - })
-86
test/snapshots/test/test-update.test.ts
··· 1 - import fs, { rmSync } from 'node:fs' 2 - import { join } from 'node:path' 3 - import { globSync } from 'tinyglobby' 4 - import { expect, test } from 'vitest' 5 - import { runVitest } from '../../test-utils' 6 - 7 - test('test update', async () => { 8 - // copy fixtures/test-update to fixtures/test-update-result 9 - const srcDir = join(import.meta.dirname, 'fixtures/test-update') 10 - const dstDir = join(import.meta.dirname, 'fixtures/test-update-result') 11 - rmSync(dstDir, { recursive: true }) 12 - fs.cpSync(srcDir, dstDir, { recursive: true }) 13 - 14 - // run and update snapshots 15 - const result = await runVitest({ root: dstDir, update: true }) 16 - expect(result.stderr).toMatchInlineSnapshot(`""`) 17 - expect(result.errorTree()).toMatchInlineSnapshot(` 18 - Object { 19 - "inline-concurrent.test.js": Object { 20 - "1st": "passed", 21 - "2nd": "passed", 22 - "3rd": "passed", 23 - }, 24 - "inline.test.js": Object { 25 - "snapshots are generated in correct order": Object { 26 - "first snapshot": "passed", 27 - "second snapshot": "passed", 28 - }, 29 - "snapshots with properties": Object { 30 - "mixed with and without snapshot": "passed", 31 - "with snapshot": "passed", 32 - "without snapshot": "passed", 33 - }, 34 - }, 35 - "retry-file.test.ts": Object { 36 - "file repeats": "passed", 37 - "file repeats many": "passed", 38 - "file retry": "passed", 39 - "file retry many": "passed", 40 - "file retry partial": "passed", 41 - }, 42 - "retry-inline.test.ts": Object { 43 - "inline repeats": "passed", 44 - "inline retry": "passed", 45 - }, 46 - "same-title-file.test.js": Object { 47 - "same title exist": "passed", 48 - "same title new": "passed", 49 - }, 50 - "same-title-inline.test.js": Object { 51 - "same title": "passed", 52 - }, 53 - } 54 - `) 55 - const resultFiles = readFiles(dstDir) 56 - expect(Object.keys(resultFiles)).toMatchInlineSnapshot(` 57 - Array [ 58 - "__snapshots__/retry-file.test.ts.snap", 59 - "__snapshots__/same-title-file.test.js.snap", 60 - "inline-concurrent.test.js", 61 - "inline.test.js", 62 - "retry-file.test.ts", 63 - "retry-inline.test.ts", 64 - "same-title-file.test.js", 65 - "same-title-inline.test.js", 66 - ] 67 - `) 68 - 69 - // re-run without update and files are unchanged 70 - const result2 = await runVitest({ root: dstDir, update: 'none' }) 71 - expect(result2.stderr).toMatchInlineSnapshot(`""`) 72 - expect(result2.errorTree()).toEqual(result.errorTree()) 73 - expect(readFiles(dstDir)).toEqual(resultFiles) 74 - 75 - const result3 = await runVitest({ root: dstDir, update: 'new' }) 76 - expect(result3.stderr).toMatchInlineSnapshot(`""`) 77 - expect(result3.errorTree()).toEqual(result.errorTree()) 78 - expect(readFiles(dstDir)).toEqual(resultFiles) 79 - }) 80 - 81 - function readFiles(dir: string) { 82 - const files = globSync('**', { cwd: dir, ignore: ['**/node_modules/**'] }) 83 - return Object.fromEntries( 84 - files.sort().map(file => [file, fs.readFileSync(join(dir, file), 'utf-8')]), 85 - ) 86 - }
-20
test/snapshots/test/utils.ts
··· 1 - import fs from 'node:fs' 2 - 3 - export function readInlineSnapshots(file: string) { 4 - return extractInlineSnaphsots(fs.readFileSync(file, 'utf-8')) 5 - } 6 - 7 - export function extractInlineSnaphsots(code: string) { 8 - const matches = Array.from( 9 - code.matchAll(/\.toMatch(\w*)InlineSnapshot\(\s*`[\s\S]*?`\s*\)/g), 10 - ) 11 - const snapshots = matches.map((match) => { 12 - const end = match.index! + match[0].length 13 - const start = code.lastIndexOf('expect', match.index) 14 - if (start === -1) { 15 - throw new Error(`Failed to extract inline snapshot: no expect found for match ${match[0]}`) 16 - } 17 - return code.slice(start, end) 18 - }) 19 - return `\n${snapshots.join('\n\n')}\n` 20 - }
+1
test/e2e/snapshots/fixtures/ci/.gitignore
··· 1 + __snapshots__
+5
test/e2e/snapshots/fixtures/ci/basic.test.ts
··· 1 + import { test, expect } from "vitest" 2 + 3 + test("basic", () => { 4 + expect("ok").toMatchSnapshot() 5 + })
+1
test/e2e/snapshots/fixtures/ci/vitest.config.ts
··· 1 + export default {}
+21
test/e2e/snapshots/fixtures/compare-keys/basic.test.ts
··· 1 + import { test, expect } from 'vitest'; 2 + 3 + test('compareKeys', () => { 4 + expect({ 5 + a: 1, 6 + b: 2, 7 + c: 3, 8 + }).toMatchSnapshot(); 9 + 10 + expect({ 11 + c: 1, 12 + b: 2, 13 + a: 3, 14 + }).toMatchSnapshot(); 15 + 16 + expect({ 17 + b: 1, 18 + a: 2, 19 + c: 3, 20 + }).toMatchSnapshot(); 21 + });
+9
test/e2e/snapshots/fixtures/compare-keys/vitest.config.ts
··· 1 + import { defineConfig } from "vitest/config"; 2 + 3 + export default defineConfig({ 4 + test: { 5 + // snapshotFormat: { 6 + // compareKeys: null, 7 + // } 8 + } 9 + })
+1
test/e2e/snapshots/fixtures/custom-matcher/.gitignore
··· 1 + __snapshots__
+97
test/e2e/snapshots/fixtures/custom-matcher/basic.test.ts
··· 1 + import { expect, test, Snapshots, chai } from 'vitest' 2 + 3 + const { 4 + toMatchFileSnapshot, 5 + toMatchInlineSnapshot, 6 + toMatchSnapshot, 7 + } = Snapshots 8 + 9 + // custom snapshot matcher to wraper input code string 10 + interface CustomMatchers<R = unknown> { 11 + toMatchCustomSnapshot: (properties?: object) => R 12 + toMatchCustomInlineSnapshot: (snapshot?: string) => R 13 + toMatchCustomFileSnapshot: (filepath: string) => Promise<R> 14 + toMatchCustomAsyncInlineSnapshot: (snapshot?: string) => Promise<R> 15 + } 16 + 17 + declare module 'vitest' { 18 + interface Assertion<T = any> extends CustomMatchers<T> {} 19 + } 20 + 21 + function formatCustom(input: string) { 22 + return { 23 + reversed: input.split('').reverse().join(''), 24 + length: input.length, 25 + } 26 + } 27 + 28 + expect.extend({ 29 + toMatchCustomSnapshot(actual: string, properties?: object) { 30 + const actualCustom = formatCustom(actual) 31 + const result = toMatchSnapshot.call(this, actualCustom, properties) 32 + // result can be further enhanced 33 + return { ...result, message: () => `[custom error] ${result.message()}` } 34 + }, 35 + toMatchCustomInlineSnapshot( 36 + actual: string, 37 + inlineSnapshot?: string, 38 + ) { 39 + const actualCustom = formatCustom(actual) 40 + const result = toMatchInlineSnapshot.call(this, actualCustom, inlineSnapshot) 41 + return { ...result, message: () => `[custom error] ${result.message()}` } 42 + }, 43 + async toMatchCustomFileSnapshot(actual: string, filepath: string) { 44 + const actualCustom = formatCustom(actual) 45 + const result = await toMatchFileSnapshot.call(this, actualCustom, filepath) 46 + return { ...result, message: () => `[custom error] ${result.message()}` } 47 + }, 48 + async toMatchCustomAsyncInlineSnapshot( 49 + actual: string, 50 + inlineSnapshot?: string, 51 + ) { 52 + chai.util.flag(this.assertion, 'error', new Error()) 53 + await Promise.resolve() 54 + const inner = async () => { 55 + await Promise.resolve() 56 + const actualCustom = formatCustom(actual) 57 + const result = toMatchInlineSnapshot.call(this, actualCustom, inlineSnapshot) 58 + return { ...result, message: () => `[custom error] ${result.message()}` } 59 + } 60 + const result = await inner(); 61 + return result; 62 + } 63 + }) 64 + 65 + test('file', () => { 66 + expect(`hahaha`).toMatchCustomSnapshot() 67 + }) 68 + 69 + test('properties 1', () => { 70 + expect(`popopo`).toMatchCustomSnapshot({ length: 6 }) 71 + }) 72 + 73 + test('properties 2', () => { 74 + expect(`pepepe`).toMatchCustomSnapshot({ length: expect.toSatisfy(function lessThan10(n) { return n < 10 }) }) 75 + }) 76 + 77 + test('raw', async () => { 78 + await expect(`hihihi`).toMatchCustomFileSnapshot('./__snapshots__/raw.txt') 79 + }) 80 + 81 + test('inline', () => { 82 + expect(`hehehe`).toMatchCustomInlineSnapshot(` 83 + { 84 + "length": 6, 85 + "reversed": "eheheh", 86 + } 87 + `) 88 + }) 89 + 90 + test('async inline', async () => { 91 + await expect(`huhuhu`).toMatchCustomAsyncInlineSnapshot(` 92 + { 93 + "length": 6, 94 + "reversed": "uhuhuh", 95 + } 96 + `) 97 + })
+1
test/e2e/snapshots/fixtures/custom-matcher/vitest.config.ts
··· 1 + export default {}
+1
test/e2e/snapshots/fixtures/custom-serializers-empty/.gitignore
··· 1 + __snapshots__/
+26
test/e2e/snapshots/fixtures/custom-serializers-empty/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + expect.addSnapshotSerializer({ 4 + test(value) { 5 + return value && typeof value === 'object' && '__unwrap__' in value 6 + }, 7 + serialize(value) { 8 + return value.__unwrap__ 9 + }, 10 + }) 11 + 12 + test('file empty', () => { 13 + expect({ __unwrap__: "" }).toMatchSnapshot() 14 + }) 15 + 16 + test('inline empty', () => { 17 + expect({ __unwrap__: "" }).toMatchInlineSnapshot(``) 18 + }) 19 + 20 + test('file whitespaces', () => { 21 + expect({ __unwrap__: " ".repeat(4) }).toMatchSnapshot() 22 + }) 23 + 24 + test('inline whitespaces', () => { 25 + expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(``) 26 + })
+4
test/e2e/snapshots/fixtures/custom-serializers-empty/vitest.config.ts
··· 1 + import { defineConfig } from "vitest/config"; 2 + 3 + export default defineConfig({ 4 + })
+23
test/e2e/snapshots/fixtures/custom-serializers/custom-serializers.test.ts
··· 1 + import { test, expect } from "vitest"; 2 + 3 + test("", () => { 4 + expect({foo: { 5 + a: 1, 6 + b: 2 7 + }}).toMatchInlineSnapshot(` 8 + Pretty foo: { 9 + "a": 1, 10 + "b": 2, 11 + } 12 + `); 13 + 14 + expect({bar: { 15 + a: 1, 16 + b: 2 17 + }}).toMatchInlineSnapshot(` 18 + Pretty bar: { 19 + "a": 1, 20 + "b": 2, 21 + } 22 + `); 23 + })
+14
test/e2e/snapshots/fixtures/custom-serializers/serializer-1.js
··· 1 + export default { 2 + serialize(val, config, indentation, depth, refs, printer) { 3 + return `Pretty foo: ${printer( 4 + val.foo, 5 + config, 6 + indentation, 7 + depth, 8 + refs, 9 + )}` 10 + }, 11 + test(val) { 12 + return val && Object.prototype.hasOwnProperty.call(val, 'foo') 13 + }, 14 + }
+16
test/e2e/snapshots/fixtures/custom-serializers/serializer-2.ts
··· 1 + import { SnapshotSerializer } from 'vitest' 2 + 3 + export default { 4 + serialize(val, config, indentation, depth, refs, printer) { 5 + return `Pretty bar: ${printer( 6 + val.bar, 7 + config, 8 + indentation, 9 + depth, 10 + refs, 11 + )}` 12 + }, 13 + test(val) { 14 + return val && Object.prototype.hasOwnProperty.call(val, 'bar') 15 + }, 16 + } satisfies SnapshotSerializer
+7
test/e2e/snapshots/fixtures/custom-serializers/vitest.config.ts
··· 1 + import { defineConfig } from "vitest/config"; 2 + 3 + export default defineConfig({ 4 + test: { 5 + snapshotSerializers: ['./serializer-1.js', './serializer-2.ts'] 6 + } 7 + })
+45
test/e2e/snapshots/fixtures/custom-snapshot-environment/snapshot-environment.ts
··· 1 + import { relative as _relative } from 'pathe' 2 + import { VitestSnapshotEnvironment } from 'vitest/runtime' 3 + 4 + function relative(file: string) { 5 + return _relative(process.cwd(), file) 6 + } 7 + 8 + class CustomSnapshotEnvironment extends VitestSnapshotEnvironment { 9 + getVersion(): string { 10 + console.log('## getVersion') 11 + return super.getVersion() 12 + } 13 + 14 + getHeader() { 15 + console.log('## getHeader') 16 + return super.getHeader() 17 + } 18 + 19 + resolvePath(filepath: string) { 20 + console.log('## resolvePath', relative(filepath)) 21 + return super.resolvePath(filepath) 22 + } 23 + 24 + resolveRawPath(testPath: string, rawPath: string) { 25 + console.log('## resolveRawPath', relative(testPath), relative(rawPath)) 26 + return super.resolveRawPath(testPath, rawPath) 27 + } 28 + 29 + saveSnapshotFile(filepath: string, snapshot: string) { 30 + console.log('## saveSnapshotFile', relative(filepath)) 31 + return super.saveSnapshotFile(filepath, snapshot) 32 + } 33 + 34 + readSnapshotFile(filepath: string) { 35 + console.log('## readSnapshotFile', relative(filepath)) 36 + return super.readSnapshotFile(filepath) 37 + } 38 + 39 + removeSnapshotFile(filepath: string) { 40 + console.log('## removeSnapshotFile', relative(filepath)) 41 + return super.removeSnapshotFile(filepath) 42 + } 43 + } 44 + 45 + export default new CustomSnapshotEnvironment()
+7
test/e2e/snapshots/fixtures/custom-snapshot-environment/vitest.config.ts
··· 1 + import { defineConfig } from 'vitest/config'; 2 + 3 + export default defineConfig({ 4 + test: { 5 + snapshotEnvironment: './snapshot-environment.ts' 6 + } 7 + })
+30
test/e2e/snapshots/fixtures/domain-aria-inline/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('simple heading', () => { 4 + document.body.innerHTML = ` 5 + <h1>Hello World</h1> 6 + <p>Some description</p> 7 + ` 8 + expect(document.body).toMatchAriaInlineSnapshot(` 9 + - heading "Hello World" [level=1] 10 + - paragraph: Some description 11 + `) 12 + }) 13 + 14 + test('semantic match with regex in snapshot', () => { 15 + document.body.innerHTML = ` 16 + <p>Original</p> 17 + <button aria-label="1234">Pattern</button> 18 + ` 19 + expect(document.body).toMatchAriaInlineSnapshot(` 20 + - paragraph: Original 21 + - button "1234": Pattern 22 + `) 23 + }) 24 + 25 + test("empty", () => { 26 + document.body.innerHTML = ` 27 + <button aria-hidden="true">Hidden</button> 28 + ` 29 + expect(document.body).toMatchAriaInlineSnapshot() 30 + })
+17
test/e2e/snapshots/fixtures/domain-aria-inline/vitest.config.ts
··· 1 + import { defineConfig } from "vitest/config" 2 + import { playwright } from "@vitest/browser-playwright" 3 + 4 + export default defineConfig({ 5 + test: { 6 + browser: { 7 + enabled: true, 8 + headless: true, 9 + provider: playwright(), 10 + instances: [ 11 + { 12 + browser: "chromium", 13 + } 14 + ] 15 + } 16 + } 17 + })
+1
test/e2e/snapshots/fixtures/domain-aria/.gitignore
··· 1 + __snapshots__/
+28
test/e2e/snapshots/fixtures/domain-aria/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('simple heading and paragraph', () => { 4 + document.body.innerHTML = ` 5 + <h1>Hello World</h1> 6 + <p> 7 + Some 8 + <br/> 9 + description 10 + </p> 11 + ` 12 + expect(document.body).toMatchAriaSnapshot() 13 + }) 14 + 15 + test('semantic match with regex in snapshot', () => { 16 + document.body.innerHTML = ` 17 + <p>Original</p> 18 + <button aria-label="1234">Pattern</button> 19 + ` 20 + expect(document.body).toMatchAriaSnapshot() 21 + }) 22 + 23 + test("empty", () => { 24 + document.body.innerHTML = ` 25 + <button aria-hidden="true">Hidden</button> 26 + ` 27 + expect(document.body).toMatchAriaSnapshot() 28 + })
+17
test/e2e/snapshots/fixtures/domain-aria/vitest.config.ts
··· 1 + import { defineConfig } from "vitest/config" 2 + import { playwright } from "@vitest/browser-playwright" 3 + 4 + export default defineConfig({ 5 + test: { 6 + browser: { 7 + enabled: true, 8 + headless: true, 9 + provider: playwright(), 10 + instances: [ 11 + { 12 + browser: "chromium", 13 + } 14 + ] 15 + } 16 + } 17 + })
+13
test/e2e/snapshots/fixtures/domain-error/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + import "../domain/basic-extend" 3 + 4 + test('file', () => { 5 + expect({ name: 'alice', age: '30' }).toMatchKvSnapshot() 6 + }) 7 + 8 + test('inline', () => { 9 + expect({ name: 'alice', age: '30' }).toMatchKvInlineSnapshot(` 10 + name=bob 11 + inine-broken 12 + `) 13 + })
+1
test/e2e/snapshots/fixtures/domain-error/vitest.config.ts
··· 1 + export default {}
+21
test/e2e/snapshots/fixtures/domain-inline/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + import "../domain/basic-extend" 3 + 4 + test('all literal', () => { 5 + expect({ name: 'alice', age: '30' }).toMatchKvInlineSnapshot(` 6 + name=alice 7 + age=30 8 + `) 9 + }) 10 + 11 + test('with regex', () => { 12 + expect({ name: 'bob', score: '999', status: 'active' }).toMatchKvInlineSnapshot(` 13 + name=bob 14 + score=999 15 + status=active 16 + `) 17 + }) 18 + 19 + test('empty snapshot', () => { 20 + expect({}).toMatchKvInlineSnapshot(``) 21 + })
+1
test/e2e/snapshots/fixtures/domain-inline/vitest.config.ts
··· 1 + export default {}
+1
test/e2e/snapshots/fixtures/domain-poll-inline/.gitignore
··· 1 + __snapshots__/
+77
test/e2e/snapshots/fixtures/domain-poll-inline/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + import "../domain/basic-extend" 3 + 4 + test('stable', async () => { 5 + let trial = 0 6 + await expect.poll(() => { 7 + trial++ 8 + return { name: 'a', age: '23' } 9 + }, { interval: 10 }).toMatchKvInlineSnapshot(` 10 + name=a 11 + age=23 12 + `) 13 + expect(trial).toBe(2) 14 + }) 15 + 16 + test('throw then stable', async () => { 17 + let trial = 0 18 + await expect.poll(() => { 19 + trial++ 20 + if (trial <= 3) { 21 + throw new Error(`Fail at ${trial}`) 22 + } 23 + return { name: 'b', age: '23' } 24 + }, { interval: 10 }).toMatchKvInlineSnapshot(` 25 + name=b 26 + age=23 27 + `) 28 + expect(trial).toBe(5) 29 + }) 30 + 31 + test('unstable then stable', async () => { 32 + let trial = 0 33 + await expect.poll(() => { 34 + trial++ 35 + if (trial <= 3) return { status: 'loading', trial } // unstable 36 + return { status: 'done' } // then stable 37 + }, { interval: 10 }).toMatchKvInlineSnapshot(` 38 + status=done 39 + `) 40 + expect(trial).toBe(5) 41 + }) 42 + 43 + test('multiple poll snapshots', async () => { 44 + await expect.poll(() => { 45 + return { x: '1' } 46 + }, { interval: 10 }).toMatchKvInlineSnapshot(` 47 + x=1 48 + `) 49 + 50 + await expect.poll(() => { 51 + return { y: '2' } 52 + }, { interval: 10 }).toMatchKvInlineSnapshot(` 53 + y=2 54 + `) 55 + }) 56 + 57 + test('non-poll alongside poll', async () => { 58 + expect({ static: 'value' }).toMatchKvInlineSnapshot(` 59 + static=value 60 + `) 61 + 62 + await expect.poll(() => { 63 + return { polled: 'value' } 64 + }, { interval: 10 }).toMatchKvInlineSnapshot(` 65 + polled=value 66 + `) 67 + 68 + expect({ another: 'static' }).toMatchKvInlineSnapshot(` 69 + another=static 70 + `) 71 + }) 72 + 73 + test('empty snapshot', async () => { 74 + await expect.poll(() => { 75 + return {} 76 + }, { interval: 10 }).toMatchKvInlineSnapshot(``) 77 + })
+1
test/e2e/snapshots/fixtures/domain-poll-inline/vitest.config.ts
··· 1 + export default {}
+1
test/e2e/snapshots/fixtures/domain-poll/.gitignore
··· 1 + __snapshots__/
+58
test/e2e/snapshots/fixtures/domain-poll/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + import "../domain/basic-extend" 3 + 4 + test('stable', async () => { 5 + let trial = 0 6 + await expect.poll(() => { 7 + trial++ 8 + return { name: 'a', age: '23' } 9 + }, { interval: 10 }).toMatchKvSnapshot() 10 + expect(trial).toBe(2) 11 + }) 12 + 13 + test('throw then stable', async () => { 14 + let trial = 0 15 + await expect.poll(() => { 16 + trial++ 17 + if (trial <= 3) { 18 + throw new Error(`Fail at ${trial}`) 19 + } 20 + return { name: 'b', age: '23' } 21 + }, { interval: 10 }).toMatchKvSnapshot() 22 + expect(trial).toBe(5) 23 + }) 24 + 25 + test('unstable then stable', async () => { 26 + let trial = 0 27 + await expect.poll(() => { 28 + trial++ 29 + if (trial <= 3) return { status: 'loading', trial } // unstable 30 + return { status: 'done' } // then stable 31 + }, { interval: 10 }).toMatchKvSnapshot() 32 + expect(trial).toBe(5) 33 + }) 34 + 35 + test('multiple poll snapshots', async () => { 36 + await expect.poll(() => { 37 + return { x: '1' } 38 + }, { interval: 10 }).toMatchKvSnapshot() 39 + 40 + await expect.poll(() => { 41 + return { y: '2' } 42 + }, { interval: 10 }).toMatchKvSnapshot() 43 + }) 44 + 45 + test('non-poll alongside poll', async () => { 46 + expect({ static: 'value' }).toMatchKvSnapshot() 47 + await expect.poll(() => { 48 + return { polled: 'value' } 49 + }, { interval: 10 }).toMatchKvSnapshot() 50 + 51 + expect({ another: 'static' }).toMatchKvSnapshot() 52 + }) 53 + 54 + test('empty snapshot', async () => { 55 + await expect.poll(() => { 56 + return {} 57 + }, { interval: 10 }).toMatchKvSnapshot() 58 + })
+1
test/e2e/snapshots/fixtures/domain-poll/vitest.config.ts
··· 1 + export default {}
+1
test/e2e/snapshots/fixtures/domain/.gitignore
··· 1 + __snapshots__/
+33
test/e2e/snapshots/fixtures/domain/basic-extend.ts
··· 1 + import { expect, Snapshots } from "vitest" 2 + import type { MatchersObject } from "vitest" 3 + import { kvAdapter } from "./basic" 4 + 5 + interface CustomMatchers<R = unknown> { 6 + toMatchKvSnapshot: () => R 7 + toMatchKvInlineSnapshot: (snapshot?: string) => R 8 + } 9 + 10 + declare module 'vitest' { 11 + interface Assertion<T = any> extends CustomMatchers<T> {} 12 + } 13 + 14 + const matchers: MatchersObject = { 15 + toMatchKvSnapshot(actual: unknown) { 16 + return Snapshots.toMatchDomainSnapshot.call(this, kvAdapter, actual) 17 + }, 18 + toMatchKvInlineSnapshot( 19 + actual: unknown, 20 + inlineSnapshot?: string, 21 + ) { 22 + return Snapshots.toMatchDomainInlineSnapshot.call(this, kvAdapter, actual, inlineSnapshot) 23 + }, 24 + } 25 + 26 + // internal flag to allow expect.poll for snapshot matchers 27 + for (const matcher of Object.values(matchers)) { 28 + Object.assign(matcher, { 29 + __vitest_poll_takeover__: true, 30 + }) 31 + } 32 + 33 + expect.extend(matchers)
+14
test/e2e/snapshots/fixtures/domain/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + import "./basic-extend" 3 + 4 + test('all literal', () => { 5 + expect({ name: 'alice', age: '30' }).toMatchKvSnapshot() 6 + }) 7 + 8 + test('with regex', () => { 9 + expect({ name: 'bob', age: '24', score: '999', status: 'active' }).toMatchKvSnapshot() 10 + }) 11 + 12 + test('empty snapshot', () => { 13 + expect({}).toMatchKvSnapshot() 14 + })
+80
test/e2e/snapshots/fixtures/domain/basic.ts
··· 1 + import type { DomainMatchResult, DomainSnapshotAdapter } from 'vitest' 2 + 3 + // Key-value domain adapter: each snapshot is multiple lines of `key=value`. 4 + // Values can be literal strings or `/regex/` patterns in the stored snapshot. 5 + // On match, each line is checked independently — regex lines use RegExp.test(). 6 + // On partial match, `mergedExpected` preserves regex for matched lines 7 + // and substitutes literal rendered values for unmatched lines. 8 + 9 + type KVCaptured = Record<string, string> 10 + type KVExpected = Record<string, string | RegExp> 11 + 12 + function renderKV(obj: Record<string, unknown>) { 13 + const result = Object.entries(obj).map(([k, v]) => `${k}=${v}`).join('\n'); 14 + return result ? `\n${result}\n` : '' 15 + } 16 + 17 + export const kvAdapter: DomainSnapshotAdapter<KVCaptured, KVExpected> = { 18 + name: 'kv', 19 + 20 + capture(received: unknown): KVCaptured { 21 + if (received && typeof received === 'object') { 22 + return Object.fromEntries(Object.entries(received).map(([k, v]) => [k, String(v)])) 23 + } 24 + throw new TypeError('kv adapter expects a plain object') 25 + }, 26 + 27 + render(captured: KVCaptured): string { 28 + return renderKV(captured) 29 + }, 30 + 31 + parseExpected(input: string): KVExpected { 32 + if (!input.trim()) { 33 + return {} 34 + } 35 + const entries = input.trim().split('\n').map((line) => { 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) 41 + const raw = line.slice(eq + 1) 42 + const value = (raw.startsWith('/') && raw.endsWith('/') && raw.length > 1) 43 + ? new RegExp(raw.slice(1, -1)) 44 + : raw 45 + return [key, value] 46 + }) 47 + return Object.fromEntries(entries) 48 + }, 49 + 50 + match(captured: KVCaptured, expected: KVExpected): DomainMatchResult { 51 + const resolvedLines: string[] = [] 52 + let pass = true 53 + 54 + // iterate on `expected` side so extra key on `actual` side 55 + // is ignored and works as subset match 56 + for (const [key, expectedValue] of Object.entries(expected)) { 57 + const actualValue = captured[key] 58 + if (actualValue === undefined) { 59 + pass = false 60 + continue 61 + } 62 + 63 + // preserve matched pattern for normalized error diff and partial update 64 + if (expectedValue instanceof RegExp && expectedValue.test(actualValue)) { 65 + resolvedLines.push(`${key}=/${expectedValue.source}/`) 66 + continue 67 + } 68 + 69 + resolvedLines.push(`${key}=${actualValue}`) 70 + pass &&= actualValue === expectedValue 71 + } 72 + 73 + return { 74 + pass, 75 + message: pass ? undefined : 'KV entries do not match', 76 + resolved: `\n${resolvedLines.join('\n')}\n`, 77 + expected: `\n${renderKV(expected)}\n`, 78 + } 79 + }, 80 + }
+1
test/e2e/snapshots/fixtures/domain/vitest.config.ts
··· 1 + export default {}
+25
test/e2e/snapshots/fixtures/file/basic.test.ts
··· 1 + import { test, expect } from "vitest" 2 + 3 + // pnpm -C test/snapshots test:fixtures --root test/fixtures/file 4 + 5 + test('white space', async () => { 6 + await expect(` 7 + 8 + white space 9 + `).toMatchFileSnapshot('snapshot-1.txt') 10 + }) 11 + 12 + test('indent', async () => { 13 + await expect(`\ 14 + example: | 15 + { 16 + echo "hello" 17 + } 18 + some: 19 + nesting: 20 + - "hello world" 21 + even: 22 + more: 23 + nesting: true 24 + `).toMatchFileSnapshot('snapshot-2.txt') 25 + })
+3
test/e2e/snapshots/fixtures/file/snapshot-1.txt
··· 1 + 2 + 3 + white space
+10
test/e2e/snapshots/fixtures/file/snapshot-2.txt
··· 1 + example: | 2 + { 3 + echo "hello" 4 + } 5 + some: 6 + nesting: 7 + - "hello world" 8 + even: 9 + more: 10 + nesting: true
+1
test/e2e/snapshots/fixtures/file/vitest.config.ts
··· 1 + export default {}
+28
test/e2e/snapshots/fixtures/indent/basic.test.ts
··· 1 + import { test, expect } from "vitest" 2 + 3 + // pnpm -C test/snapshots test:fixtures --root test/fixtures/indent 4 + 5 + test('toMatchSnapshot string', () => { 6 + expect(` 7 + 1111 8 + xxxx { 9 + } 10 + 11 + `).toMatchSnapshot() 12 + }) 13 + 14 + test('toMatchInlineSnapshot string', () => { 15 + expect(` 16 + 2222 17 + yyyy { 18 + } 19 + 20 + `).toMatchInlineSnapshot(` 21 + " 22 + 2222 23 + yyyy { 24 + } 25 + 26 + " 27 + `) 28 + })
+1
test/e2e/snapshots/fixtures/indent/vitest.config.ts
··· 1 + export default {}
+7
test/e2e/snapshots/fixtures/inline-multiple-calls/different.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('single', () => { 4 + for (const value of ["test1", "test2"]) { 5 + expect(value).toMatchInlineSnapshot() 6 + } 7 + })
+13
test/e2e/snapshots/fixtures/inline-multiple-calls/different2.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('a', () => { 4 + snap('test1') 5 + }) 6 + 7 + test('b', () => { 8 + snap('test2') 9 + }) 10 + 11 + function snap(value: unknown) { 12 + expect(value).toMatchInlineSnapshot() 13 + }
+17
test/e2e/snapshots/fixtures/inline-multiple-calls/each.test.ts
··· 1 + import { expect, test, describe } from "vitest"; 2 + 3 + test.for(["hello", "world"])("test %s", (arg) => { 4 + expect(arg.length).toMatchInlineSnapshot(`5`); 5 + }); 6 + 7 + describe.for(["hello", "world"])("suite %s", (arg) => { 8 + test("length", () => { 9 + expect(arg.length).toMatchInlineSnapshot(`5`); 10 + }); 11 + }); 12 + 13 + test.for(["hello", "world"])("toThrowErrorMatchingInlineSnapshot %s", (arg) => { 14 + expect(() => { 15 + throw new Error(`length = ${arg.length}`); 16 + }).toThrowErrorMatchingInlineSnapshot(`[Error: length = 5]`) 17 + });
+7
test/e2e/snapshots/fixtures/inline-multiple-calls/same.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('single', () => { 4 + for (const value of ["test1", "test1"]) { 5 + expect(value).toMatchInlineSnapshot(`"test1"`) 6 + } 7 + })
+13
test/e2e/snapshots/fixtures/inline-multiple-calls/same2.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('a', () => { 4 + snap('test1') 5 + }) 6 + 7 + test('b', () => { 8 + snap('test1') 9 + }) 10 + 11 + function snap(value: unknown) { 12 + expect(value).toMatchInlineSnapshot(`"test1"`) 13 + }
+1
test/e2e/snapshots/fixtures/inline-multiple-calls/vitest.config.ts
··· 1 + export default {}
+19
test/e2e/snapshots/fixtures/jest-image-snapshot/basic.test.ts
··· 1 + import { expect, it } from "vitest"; 2 + import fs from "fs"; 3 + 4 + // @ts-expect-error no type 5 + import { toMatchImageSnapshot } from "jest-image-snapshot"; 6 + expect.extend({ toMatchImageSnapshot }); 7 + 8 + declare module 'vitest' { 9 + interface Assertion<T = any> { 10 + toMatchImageSnapshot(): void 11 + } 12 + } 13 + 14 + // pnpm -C test/snapshots test:fixtures --root test/fixtures/jest-image-snapshot 15 + 16 + it("toMatchImageSnapshot", async () => { 17 + const file = new URL("./test.png", import.meta.url) 18 + expect(fs.readFileSync(file)).toMatchImageSnapshot(); 19 + });
test/e2e/snapshots/fixtures/jest-image-snapshot/test.png

This is a binary file and will not be displayed.

+1
test/e2e/snapshots/fixtures/jest-image-snapshot/vitest.config.ts
··· 1 + export default {}
+3
test/e2e/snapshots/fixtures/obsolete/vitest.config.ts
··· 1 + import { defineConfig } from 'vitest/config' 2 + 3 + export default defineConfig({})
+1
test/e2e/snapshots/fixtures/properties/.gitignore
··· 1 + __snapshots__
+28
test/e2e/snapshots/fixtures/properties/basic.test.ts
··· 1 + import { expect, test } from "vitest"; 2 + 3 + test("file", () => { 4 + expect({ name: "alice", age: 30 }).toMatchSnapshot({ age: expect.any(Number) }); 5 + }); 6 + 7 + test("file asymmetric", () => { 8 + expect({ name: "bob", score: 95 }).toMatchSnapshot({ 9 + score: expect.toSatisfy(function lessThan100(n) { 10 + return n < 100; 11 + }), 12 + }); 13 + }); 14 + 15 + test("file snapshot-only", () => { 16 + expect({ name: "dave", age: 42 }).toMatchSnapshot({ age: expect.any(Number) }); 17 + }); 18 + 19 + // -- TEST INLINE START -- 20 + test("inline", () => { 21 + expect({ name: "carol", age: 25 }).toMatchInlineSnapshot({ age: expect.any(Number) }, ` 22 + { 23 + "age": Any<Number>, 24 + "name": "carol", 25 + } 26 + `); 27 + }); 28 + // -- TEST INLINE END --
+1
test/e2e/snapshots/fixtures/properties/vitest.config.ts
··· 1 + export default {}
+11
test/e2e/snapshots/fixtures/skip-test-custom/basic.test.ts
··· 1 + import { expect, test } from 'vitest'; 2 + 3 + test('custom a', () => { 4 + expect(0).toMatchSnapshot('x'); 5 + expect(0).toMatchSnapshot('y'); 6 + }); 7 + 8 + test('custom b', () => { 9 + expect(0).toMatchSnapshot('z'); 10 + expect(0).toMatchSnapshot('w'); 11 + });
+1
test/e2e/snapshots/fixtures/skip-test-custom/vitest.config.ts
··· 1 + export default {}
+20
test/e2e/snapshots/fixtures/skip-test/repro.test.ts
··· 1 + import { describe, expect, it } from 'vitest' 2 + 3 + const ENABLE_SKIP = process.env.ENABLE_SKIP; 4 + 5 + describe.skipIf(ENABLE_SKIP)('repro suite', () => { 6 + it('inner case', () => { 7 + expect('hi-1').toMatchSnapshot() 8 + }) 9 + }) 10 + 11 + it.skipIf(ENABLE_SKIP)('top-level case', () => { 12 + expect('hi-2').toMatchSnapshot() 13 + }) 14 + 15 + // at least one non-skipped test is needed to reproduce a bug. 16 + // without this, there will be no SnapshotClient.startCurrentRun, 17 + // so the code to check skip/obsolete snapshot is not exercised. 18 + it('normal case', () => { 19 + expect(0).toBe(0) 20 + })
+3
test/e2e/snapshots/fixtures/skip-test/vitest.config.ts
··· 1 + import { defineConfig } from 'vitest/config' 2 + 3 + export default defineConfig({})
+11
test/e2e/snapshots/fixtures/soft-inline/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('toMatchInlineSnapshot', () => { 4 + expect.soft('--snap-1--').toMatchInlineSnapshot(`"--snap-1--"`) 5 + expect.soft('--snap-2--').toMatchInlineSnapshot(`"--snap-2--"`) 6 + }) 7 + 8 + test('toThrowErrorMatchingInlineSnapshot', () => { 9 + expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingInlineSnapshot(`[Error: --error-1--]`) 10 + expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingInlineSnapshot(`[Error: --error-2--]`) 11 + })
+1
test/e2e/snapshots/fixtures/soft-inline/vitest.config.ts
··· 1 + export default {}
+1
test/e2e/snapshots/fixtures/soft/.gitignore
··· 1 + __snapshots__
+16
test/e2e/snapshots/fixtures/soft/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('toMatchSnapshot', () => { 4 + expect.soft('--snap-1--').toMatchSnapshot() 5 + expect.soft('--snap-2--').toMatchSnapshot() 6 + }) 7 + 8 + test('toMatchFileSnapshot', async () => { 9 + await expect.soft('--file-1--').toMatchFileSnapshot('./__snapshots__/custom1.txt') 10 + await expect.soft('--file-2--').toMatchFileSnapshot('./__snapshots__/custom2.txt') 11 + }) 12 + 13 + test('toThrowErrorMatchingSnapshot', () => { 14 + expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingSnapshot() 15 + expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingSnapshot() 16 + })
+1
test/e2e/snapshots/fixtures/soft/vitest.config.ts
··· 1 + export default {}
+1
test/e2e/snapshots/fixtures/summary-removed/.gitignore
··· 1 + __snapshots__
+11
test/e2e/snapshots/fixtures/summary-removed/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('x', () => { 4 + expect(0).toMatchSnapshot() 5 + }) 6 + 7 + // REMOVE-START 8 + test('y', () => { 9 + expect(0).toMatchSnapshot() 10 + }) 11 + // REMOVE-END
+1
test/e2e/snapshots/fixtures/summary-removed/vitest.config.ts
··· 1 + export default {}
+52
test/e2e/snapshots/fixtures/summary/basic.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('inline normal', () => { 4 + expect('@SNAP1').toMatchInlineSnapshot(`"@SNAP1"`) 5 + }) 6 + 7 + test('inline repeats', { repeats: 1 }, () => { 8 + expect('@SNAP2').toMatchInlineSnapshot(`"@SNAP2"`) 9 + }) 10 + 11 + test('inline retry', { retry: 1 }, (ctx) => { 12 + expect('@SNAP3').toMatchInlineSnapshot(`"@SNAP3"`) 13 + if (ctx.task.result?.retryCount === 0) { 14 + throw new Error('boom') 15 + } 16 + }) 17 + 18 + test('file normal', () => { 19 + expect('@SNAP4').toMatchSnapshot() 20 + }) 21 + 22 + test('file repeats', { repeats: 1 }, () => { 23 + expect('@SNAP5').toMatchSnapshot() 24 + }) 25 + 26 + test('file retry', { retry: 1 }, (ctx) => { 27 + expect('@SNAP6').toMatchSnapshot() 28 + if (ctx.task.result?.retryCount === 0) { 29 + throw new Error('@retry') 30 + } 31 + }) 32 + 33 + test('file repeats many', { repeats: 1 }, () => { 34 + expect('@SNAP7').toMatchSnapshot() 35 + expect('@SNAP8').toMatchSnapshot() 36 + }) 37 + 38 + test('file retry many', { retry: 1 }, (ctx) => { 39 + expect('@SNAP9').toMatchSnapshot() 40 + expect('@SNAP10').toMatchSnapshot() 41 + if (ctx.task.result?.retryCount === 0) { 42 + throw new Error('@retry') 43 + } 44 + }) 45 + 46 + test('file retry partial', { retry: 1 }, (ctx) => { 47 + expect('@SNAP11').toMatchSnapshot() 48 + if (ctx.task.result?.retryCount === 0) { 49 + throw new Error('@retry') 50 + } 51 + expect('@SNAP12').toMatchSnapshot() 52 + })
+1
test/e2e/snapshots/fixtures/summary/vitest.config.ts
··· 1 + export default {}
+13
test/e2e/snapshots/fixtures/test-update-result/inline-concurrent.test.js
··· 1 + import { it } from 'vitest' 2 + 3 + it.concurrent('1st', ({ expect }) => { 4 + expect('hi1').toMatchInlineSnapshot(`"hi1"`) 5 + }) 6 + 7 + it.concurrent('2nd', ({ expect }) => { 8 + expect('hi2').toMatchInlineSnapshot(`"hi2"`) 9 + }) 10 + 11 + it.concurrent('3rd', ({ expect }) => { 12 + expect('hi3').toMatchInlineSnapshot(`"hi3"`) 13 + })
+69
test/e2e/snapshots/fixtures/test-update-result/inline.test.js
··· 1 + import { describe, expect, test } from 'vitest' 2 + 3 + // when snapshots are generated Vitest reruns `toMatchInlineSnapshot` checks 4 + // please, don't commit generated snapshots 5 + describe('snapshots are generated in correct order', async () => { 6 + test('first snapshot', () => { 7 + expect({ foo: ['bar'] }).toMatchInlineSnapshot(` 8 + { 9 + "foo": [ 10 + "bar", 11 + ], 12 + } 13 + `) 14 + }) 15 + 16 + test('second snapshot', () => { 17 + expect({ foo: ['zed'] }).toMatchInlineSnapshot(` 18 + { 19 + "foo": [ 20 + "zed", 21 + ], 22 + } 23 + `) 24 + }) 25 + }) 26 + 27 + describe('snapshots with properties', () => { 28 + test('without snapshot', () => { 29 + expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, ` 30 + { 31 + "foo": Any<String>, 32 + } 33 + `) 34 + }) 35 + 36 + test('with snapshot', () => { 37 + expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 38 + { 39 + "first": { 40 + "second": { 41 + "foo": Any<String>, 42 + }, 43 + }, 44 + } 45 + `) 46 + }) 47 + 48 + test('mixed with and without snapshot', () => { 49 + expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 50 + { 51 + "first": { 52 + "second": { 53 + "foo": Any<String>, 54 + }, 55 + }, 56 + } 57 + `) 58 + 59 + expect({ first: { second: { foo: 'zed' } } }).toMatchInlineSnapshot(` 60 + { 61 + "first": { 62 + "second": { 63 + "foo": "zed", 64 + }, 65 + }, 66 + } 67 + `) 68 + }) 69 + })
+33
test/e2e/snapshots/fixtures/test-update-result/retry-file.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('file repeats', { repeats: 1 }, () => { 4 + expect('foo').toMatchSnapshot() 5 + }) 6 + 7 + test('file retry', { retry: 1 }, (ctx) => { 8 + expect('foo').toMatchSnapshot() 9 + if (ctx.task.result?.retryCount === 0) { 10 + throw new Error('boom') 11 + } 12 + }) 13 + 14 + test('file repeats many', { repeats: 1 }, () => { 15 + expect('foo').toMatchSnapshot() 16 + expect('bar').toMatchSnapshot() 17 + }) 18 + 19 + test('file retry many', { retry: 1 }, (ctx) => { 20 + expect('foo').toMatchSnapshot() 21 + expect('bar').toMatchSnapshot() 22 + if (ctx.task.result?.retryCount === 0) { 23 + throw new Error('boom') 24 + } 25 + }) 26 + 27 + test('file retry partial', { retry: 1 }, (ctx) => { 28 + expect('foo').toMatchSnapshot() 29 + if (ctx.task.result?.retryCount === 0) { 30 + throw new Error('boom') 31 + } 32 + expect('bar').toMatchSnapshot() 33 + })
+12
test/e2e/snapshots/fixtures/test-update-result/retry-inline.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('inline repeats', { repeats: 1 }, () => { 4 + expect('foo').toMatchInlineSnapshot(`"foo"`) 5 + }) 6 + 7 + test('inline retry', { retry: 1 }, (ctx) => { 8 + expect('foo').toMatchInlineSnapshot(`"foo"`) 9 + if (ctx.task.result?.retryCount === 0) { 10 + throw new Error('boom') 11 + } 12 + })
+20
test/e2e/snapshots/fixtures/test-update-result/same-title-file.test.js
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('same title exist', () => { 4 + // correct entry exists in .snap 5 + expect('a').toMatchSnapshot() 6 + }) 7 + 8 + test('same title exist', () => { 9 + // wrong entry exists in .snap 10 + expect('b').toMatchSnapshot() 11 + }) 12 + 13 + test('same title new', () => { 14 + expect('a').toMatchSnapshot() 15 + }) 16 + 17 + test('same title new', () => { 18 + expect('b').toMatchSnapshot() 19 + expect('c').toMatchSnapshot() 20 + })
+16
test/e2e/snapshots/fixtures/test-update-result/same-title-inline.test.js
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('same title', () => { 4 + expect('new').toMatchInlineSnapshot(`"new"`) 5 + expect('new').toMatchInlineSnapshot(`"new"`) 6 + }) 7 + 8 + test('same title', () => { 9 + expect('a').toMatchInlineSnapshot(`"a"`) 10 + expect('a').toMatchInlineSnapshot(`"a"`) 11 + }) 12 + 13 + test('same title', () => { 14 + expect('b').toMatchInlineSnapshot(`"b"`) 15 + expect('b').toMatchInlineSnapshot(`"b"`) 16 + })
+1
test/e2e/snapshots/fixtures/test-update-result/vitest.config.ts
··· 1 + export default {}
+13
test/e2e/snapshots/fixtures/test-update/inline-concurrent.test.js
··· 1 + import { it } from 'vitest' 2 + 3 + it.concurrent('1st', ({ expect }) => { 4 + expect('hi1').toMatchInlineSnapshot() 5 + }) 6 + 7 + it.concurrent('2nd', ({ expect }) => { 8 + expect('hi2').toMatchInlineSnapshot() 9 + }) 10 + 11 + it.concurrent('3rd', ({ expect }) => { 12 + expect('hi3').toMatchInlineSnapshot() 13 + })
+51
test/e2e/snapshots/fixtures/test-update/inline.test.js
··· 1 + import { describe, expect, test } from 'vitest' 2 + 3 + // when snapshots are generated Vitest reruns `toMatchInlineSnapshot` checks 4 + // please, don't commit generated snapshots 5 + describe('snapshots are generated in correct order', async () => { 6 + test('first snapshot', () => { 7 + expect({ foo: ['bar'] }).toMatchInlineSnapshot() 8 + }) 9 + 10 + test('second snapshot', () => { 11 + expect({ foo: ['zed'] }).toMatchInlineSnapshot() 12 + }) 13 + }) 14 + 15 + describe('snapshots with properties', () => { 16 + test('without snapshot', () => { 17 + expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }) 18 + }) 19 + 20 + test('with snapshot', () => { 21 + expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 22 + Object { 23 + "first": Object { 24 + "wrong": Any<String>, 25 + "second": null, 26 + } 27 + } 28 + `) 29 + }) 30 + 31 + test('mixed with and without snapshot', () => { 32 + expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 33 + Object { 34 + "first": Object { 35 + "wrong": Any<String>, 36 + "second": null, 37 + } 38 + } 39 + `) 40 + 41 + expect({ first: { second: { foo: 'zed' } } }).toMatchInlineSnapshot(` 42 + Object { 43 + "first": Object { 44 + "second": { 45 + "foo": "zed" 46 + } 47 + } 48 + } 49 + `) 50 + }) 51 + })
+33
test/e2e/snapshots/fixtures/test-update/retry-file.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('file repeats', { repeats: 1 }, () => { 4 + expect('foo').toMatchSnapshot() 5 + }) 6 + 7 + test('file retry', { retry: 1 }, (ctx) => { 8 + expect('foo').toMatchSnapshot() 9 + if (ctx.task.result?.retryCount === 0) { 10 + throw new Error('boom') 11 + } 12 + }) 13 + 14 + test('file repeats many', { repeats: 1 }, () => { 15 + expect('foo').toMatchSnapshot() 16 + expect('bar').toMatchSnapshot() 17 + }) 18 + 19 + test('file retry many', { retry: 1 }, (ctx) => { 20 + expect('foo').toMatchSnapshot() 21 + expect('bar').toMatchSnapshot() 22 + if (ctx.task.result?.retryCount === 0) { 23 + throw new Error('boom') 24 + } 25 + }) 26 + 27 + test('file retry partial', { retry: 1 }, (ctx) => { 28 + expect('foo').toMatchSnapshot() 29 + if (ctx.task.result?.retryCount === 0) { 30 + throw new Error('boom') 31 + } 32 + expect('bar').toMatchSnapshot() 33 + })
+12
test/e2e/snapshots/fixtures/test-update/retry-inline.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('inline repeats', { repeats: 1 }, () => { 4 + expect('foo').toMatchInlineSnapshot() 5 + }) 6 + 7 + test('inline retry', { retry: 1 }, (ctx) => { 8 + expect('foo').toMatchInlineSnapshot() 9 + if (ctx.task.result?.retryCount === 0) { 10 + throw new Error('boom') 11 + } 12 + })
+20
test/e2e/snapshots/fixtures/test-update/same-title-file.test.js
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('same title exist', () => { 4 + // correct entry exists in .snap 5 + expect('a').toMatchSnapshot() 6 + }) 7 + 8 + test('same title exist', () => { 9 + // wrong entry exists in .snap 10 + expect('b').toMatchSnapshot() 11 + }) 12 + 13 + test('same title new', () => { 14 + expect('a').toMatchSnapshot() 15 + }) 16 + 17 + test('same title new', () => { 18 + expect('b').toMatchSnapshot() 19 + expect('c').toMatchSnapshot() 20 + })
+16
test/e2e/snapshots/fixtures/test-update/same-title-inline.test.js
··· 1 + import { expect, test } from 'vitest' 2 + 3 + test('same title', () => { 4 + expect('new').toMatchInlineSnapshot() 5 + expect('new').toMatchInlineSnapshot() 6 + }) 7 + 8 + test('same title', () => { 9 + expect('a').toMatchInlineSnapshot(`"a"`) 10 + expect('a').toMatchInlineSnapshot(`"a"`) 11 + }) 12 + 13 + test('same title', () => { 14 + expect('b').toMatchInlineSnapshot(`"wrong"`) 15 + expect('b').toMatchInlineSnapshot(`"wrong"`) 16 + })
+1
test/e2e/snapshots/fixtures/test-update/vitest.config.ts
··· 1 + export default {}
+7
test/e2e/snapshots/fixtures/workspace/vitest.config.ts
··· 1 + import { defineConfig } from 'vitest/config' 2 + 3 + export default defineConfig({ 4 + test: { 5 + projects: ['packages/*'], 6 + }, 7 + })
-1
test/snapshots/test/fixtures/ci/.gitignore
··· 1 - __snapshots__
-5
test/snapshots/test/fixtures/ci/basic.test.ts
··· 1 - import { test, expect } from "vitest" 2 - 3 - test("basic", () => { 4 - expect("ok").toMatchSnapshot() 5 - })
-21
test/snapshots/test/fixtures/compare-keys/basic.test.ts
··· 1 - import { test, expect } from 'vitest'; 2 - 3 - test('compareKeys', () => { 4 - expect({ 5 - a: 1, 6 - b: 2, 7 - c: 3, 8 - }).toMatchSnapshot(); 9 - 10 - expect({ 11 - c: 1, 12 - b: 2, 13 - a: 3, 14 - }).toMatchSnapshot(); 15 - 16 - expect({ 17 - b: 1, 18 - a: 2, 19 - c: 3, 20 - }).toMatchSnapshot(); 21 - });
-9
test/snapshots/test/fixtures/compare-keys/vitest.config.ts
··· 1 - import { defineConfig } from "vitest/config"; 2 - 3 - export default defineConfig({ 4 - test: { 5 - // snapshotFormat: { 6 - // compareKeys: null, 7 - // } 8 - } 9 - })
-1
test/snapshots/test/fixtures/custom-matcher/.gitignore
··· 1 - __snapshots__
-97
test/snapshots/test/fixtures/custom-matcher/basic.test.ts
··· 1 - import { expect, test, Snapshots, chai } from 'vitest' 2 - 3 - const { 4 - toMatchFileSnapshot, 5 - toMatchInlineSnapshot, 6 - toMatchSnapshot, 7 - } = Snapshots 8 - 9 - // custom snapshot matcher to wraper input code string 10 - interface CustomMatchers<R = unknown> { 11 - toMatchCustomSnapshot: (properties?: object) => R 12 - toMatchCustomInlineSnapshot: (snapshot?: string) => R 13 - toMatchCustomFileSnapshot: (filepath: string) => Promise<R> 14 - toMatchCustomAsyncInlineSnapshot: (snapshot?: string) => Promise<R> 15 - } 16 - 17 - declare module 'vitest' { 18 - interface Assertion<T = any> extends CustomMatchers<T> {} 19 - } 20 - 21 - function formatCustom(input: string) { 22 - return { 23 - reversed: input.split('').reverse().join(''), 24 - length: input.length, 25 - } 26 - } 27 - 28 - expect.extend({ 29 - toMatchCustomSnapshot(actual: string, properties?: object) { 30 - const actualCustom = formatCustom(actual) 31 - const result = toMatchSnapshot.call(this, actualCustom, properties) 32 - // result can be further enhanced 33 - return { ...result, message: () => `[custom error] ${result.message()}` } 34 - }, 35 - toMatchCustomInlineSnapshot( 36 - actual: string, 37 - inlineSnapshot?: string, 38 - ) { 39 - const actualCustom = formatCustom(actual) 40 - const result = toMatchInlineSnapshot.call(this, actualCustom, inlineSnapshot) 41 - return { ...result, message: () => `[custom error] ${result.message()}` } 42 - }, 43 - async toMatchCustomFileSnapshot(actual: string, filepath: string) { 44 - const actualCustom = formatCustom(actual) 45 - const result = await toMatchFileSnapshot.call(this, actualCustom, filepath) 46 - return { ...result, message: () => `[custom error] ${result.message()}` } 47 - }, 48 - async toMatchCustomAsyncInlineSnapshot( 49 - actual: string, 50 - inlineSnapshot?: string, 51 - ) { 52 - chai.util.flag(this.assertion, 'error', new Error()) 53 - await Promise.resolve() 54 - const inner = async () => { 55 - await Promise.resolve() 56 - const actualCustom = formatCustom(actual) 57 - const result = toMatchInlineSnapshot.call(this, actualCustom, inlineSnapshot) 58 - return { ...result, message: () => `[custom error] ${result.message()}` } 59 - } 60 - const result = await inner(); 61 - return result; 62 - } 63 - }) 64 - 65 - test('file', () => { 66 - expect(`hahaha`).toMatchCustomSnapshot() 67 - }) 68 - 69 - test('properties 1', () => { 70 - expect(`popopo`).toMatchCustomSnapshot({ length: 6 }) 71 - }) 72 - 73 - test('properties 2', () => { 74 - expect(`pepepe`).toMatchCustomSnapshot({ length: expect.toSatisfy(function lessThan10(n) { return n < 10 }) }) 75 - }) 76 - 77 - test('raw', async () => { 78 - await expect(`hihihi`).toMatchCustomFileSnapshot('./__snapshots__/raw.txt') 79 - }) 80 - 81 - test('inline', () => { 82 - expect(`hehehe`).toMatchCustomInlineSnapshot(` 83 - Object { 84 - "length": 6, 85 - "reversed": "eheheh", 86 - } 87 - `) 88 - }) 89 - 90 - test('async inline', async () => { 91 - await expect(`huhuhu`).toMatchCustomAsyncInlineSnapshot(` 92 - Object { 93 - "length": 6, 94 - "reversed": "uhuhuh", 95 - } 96 - `) 97 - })
-1
test/snapshots/test/fixtures/custom-serializers-empty/.gitignore
··· 1 - __snapshots__/
-26
test/snapshots/test/fixtures/custom-serializers-empty/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - expect.addSnapshotSerializer({ 4 - test(value) { 5 - return value && typeof value === 'object' && '__unwrap__' in value 6 - }, 7 - serialize(value) { 8 - return value.__unwrap__ 9 - }, 10 - }) 11 - 12 - test('file empty', () => { 13 - expect({ __unwrap__: "" }).toMatchSnapshot() 14 - }) 15 - 16 - test('inline empty', () => { 17 - expect({ __unwrap__: "" }).toMatchInlineSnapshot(``) 18 - }) 19 - 20 - test('file whitespaces', () => { 21 - expect({ __unwrap__: " ".repeat(4) }).toMatchSnapshot() 22 - }) 23 - 24 - test('inline whitespaces', () => { 25 - expect({ __unwrap__: " ".repeat(4) }).toMatchInlineSnapshot(``) 26 - })
-4
test/snapshots/test/fixtures/custom-serializers-empty/vitest.config.ts
··· 1 - import { defineConfig } from "vitest/config"; 2 - 3 - export default defineConfig({ 4 - })
-23
test/snapshots/test/fixtures/custom-serializers/custom-serializers.test.ts
··· 1 - import { test, expect } from "vitest"; 2 - 3 - test("", () => { 4 - expect({foo: { 5 - a: 1, 6 - b: 2 7 - }}).toMatchInlineSnapshot(` 8 - Pretty foo: { 9 - "a": 1, 10 - "b": 2, 11 - } 12 - `); 13 - 14 - expect({bar: { 15 - a: 1, 16 - b: 2 17 - }}).toMatchInlineSnapshot(` 18 - Pretty bar: { 19 - "a": 1, 20 - "b": 2, 21 - } 22 - `); 23 - })
-14
test/snapshots/test/fixtures/custom-serializers/serializer-1.js
··· 1 - export default { 2 - serialize(val, config, indentation, depth, refs, printer) { 3 - return `Pretty foo: ${printer( 4 - val.foo, 5 - config, 6 - indentation, 7 - depth, 8 - refs, 9 - )}` 10 - }, 11 - test(val) { 12 - return val && Object.prototype.hasOwnProperty.call(val, 'foo') 13 - }, 14 - }
-16
test/snapshots/test/fixtures/custom-serializers/serializer-2.ts
··· 1 - import { SnapshotSerializer } from 'vitest' 2 - 3 - export default { 4 - serialize(val, config, indentation, depth, refs, printer) { 5 - return `Pretty bar: ${printer( 6 - val.bar, 7 - config, 8 - indentation, 9 - depth, 10 - refs, 11 - )}` 12 - }, 13 - test(val) { 14 - return val && Object.prototype.hasOwnProperty.call(val, 'bar') 15 - }, 16 - } satisfies SnapshotSerializer
-7
test/snapshots/test/fixtures/custom-serializers/vitest.config.ts
··· 1 - import { defineConfig } from "vitest/config"; 2 - 3 - export default defineConfig({ 4 - test: { 5 - snapshotSerializers: ['./serializer-1.js', './serializer-2.ts'] 6 - } 7 - })
-45
test/snapshots/test/fixtures/custom-snapshot-environment/snapshot-environment.ts
··· 1 - import { relative as _relative } from 'pathe' 2 - import { VitestSnapshotEnvironment } from 'vitest/runtime' 3 - 4 - function relative(file: string) { 5 - return _relative(process.cwd(), file) 6 - } 7 - 8 - class CustomSnapshotEnvironment extends VitestSnapshotEnvironment { 9 - getVersion(): string { 10 - console.log('## getVersion') 11 - return super.getVersion() 12 - } 13 - 14 - getHeader() { 15 - console.log('## getHeader') 16 - return super.getHeader() 17 - } 18 - 19 - resolvePath(filepath: string) { 20 - console.log('## resolvePath', relative(filepath)) 21 - return super.resolvePath(filepath) 22 - } 23 - 24 - resolveRawPath(testPath: string, rawPath: string) { 25 - console.log('## resolveRawPath', relative(testPath), relative(rawPath)) 26 - return super.resolveRawPath(testPath, rawPath) 27 - } 28 - 29 - saveSnapshotFile(filepath: string, snapshot: string) { 30 - console.log('## saveSnapshotFile', relative(filepath)) 31 - return super.saveSnapshotFile(filepath, snapshot) 32 - } 33 - 34 - readSnapshotFile(filepath: string) { 35 - console.log('## readSnapshotFile', relative(filepath)) 36 - return super.readSnapshotFile(filepath) 37 - } 38 - 39 - removeSnapshotFile(filepath: string) { 40 - console.log('## removeSnapshotFile', relative(filepath)) 41 - return super.removeSnapshotFile(filepath) 42 - } 43 - } 44 - 45 - export default new CustomSnapshotEnvironment()
-7
test/snapshots/test/fixtures/custom-snapshot-environment/vitest.config.ts
··· 1 - import { defineConfig } from 'vitest/config'; 2 - 3 - export default defineConfig({ 4 - test: { 5 - snapshotEnvironment: './snapshot-environment.ts' 6 - } 7 - })
-30
test/snapshots/test/fixtures/domain-aria-inline/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('simple heading', () => { 4 - document.body.innerHTML = ` 5 - <h1>Hello World</h1> 6 - <p>Some description</p> 7 - ` 8 - expect(document.body).toMatchAriaInlineSnapshot(` 9 - - heading "Hello World" [level=1] 10 - - paragraph: Some description 11 - `) 12 - }) 13 - 14 - test('semantic match with regex in snapshot', () => { 15 - document.body.innerHTML = ` 16 - <p>Original</p> 17 - <button aria-label="1234">Pattern</button> 18 - ` 19 - expect(document.body).toMatchAriaInlineSnapshot(` 20 - - paragraph: Original 21 - - button "1234": Pattern 22 - `) 23 - }) 24 - 25 - test("empty", () => { 26 - document.body.innerHTML = ` 27 - <button aria-hidden="true">Hidden</button> 28 - ` 29 - expect(document.body).toMatchAriaInlineSnapshot() 30 - })
-17
test/snapshots/test/fixtures/domain-aria-inline/vitest.config.ts
··· 1 - import { defineConfig } from "vitest/config" 2 - import { playwright } from "@vitest/browser-playwright" 3 - 4 - export default defineConfig({ 5 - test: { 6 - browser: { 7 - enabled: true, 8 - headless: true, 9 - provider: playwright(), 10 - instances: [ 11 - { 12 - browser: "chromium", 13 - } 14 - ] 15 - } 16 - } 17 - })
-1
test/snapshots/test/fixtures/domain-aria/.gitignore
··· 1 - __snapshots__/
-28
test/snapshots/test/fixtures/domain-aria/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('simple heading and paragraph', () => { 4 - document.body.innerHTML = ` 5 - <h1>Hello World</h1> 6 - <p> 7 - Some 8 - <br/> 9 - description 10 - </p> 11 - ` 12 - expect(document.body).toMatchAriaSnapshot() 13 - }) 14 - 15 - test('semantic match with regex in snapshot', () => { 16 - document.body.innerHTML = ` 17 - <p>Original</p> 18 - <button aria-label="1234">Pattern</button> 19 - ` 20 - expect(document.body).toMatchAriaSnapshot() 21 - }) 22 - 23 - test("empty", () => { 24 - document.body.innerHTML = ` 25 - <button aria-hidden="true">Hidden</button> 26 - ` 27 - expect(document.body).toMatchAriaSnapshot() 28 - })
-17
test/snapshots/test/fixtures/domain-aria/vitest.config.ts
··· 1 - import { defineConfig } from "vitest/config" 2 - import { playwright } from "@vitest/browser-playwright" 3 - 4 - export default defineConfig({ 5 - test: { 6 - browser: { 7 - enabled: true, 8 - headless: true, 9 - provider: playwright(), 10 - instances: [ 11 - { 12 - browser: "chromium", 13 - } 14 - ] 15 - } 16 - } 17 - })
-13
test/snapshots/test/fixtures/domain-error/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - import "../domain/basic-extend" 3 - 4 - test('file', () => { 5 - expect({ name: 'alice', age: '30' }).toMatchKvSnapshot() 6 - }) 7 - 8 - test('inline', () => { 9 - expect({ name: 'alice', age: '30' }).toMatchKvInlineSnapshot(` 10 - name=bob 11 - inine-broken 12 - `) 13 - })
-21
test/snapshots/test/fixtures/domain-inline/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - import "../domain/basic-extend" 3 - 4 - test('all literal', () => { 5 - expect({ name: 'alice', age: '30' }).toMatchKvInlineSnapshot(` 6 - name=alice 7 - age=30 8 - `) 9 - }) 10 - 11 - test('with regex', () => { 12 - expect({ name: 'bob', score: '999', status: 'active' }).toMatchKvInlineSnapshot(` 13 - name=bob 14 - score=999 15 - status=active 16 - `) 17 - }) 18 - 19 - test('empty snapshot', () => { 20 - expect({}).toMatchKvInlineSnapshot(``) 21 - })
-1
test/snapshots/test/fixtures/domain-poll-inline/.gitignore
··· 1 - __snapshots__/
-77
test/snapshots/test/fixtures/domain-poll-inline/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - import "../domain/basic-extend" 3 - 4 - test('stable', async () => { 5 - let trial = 0 6 - await expect.poll(() => { 7 - trial++ 8 - return { name: 'a', age: '23' } 9 - }, { interval: 10 }).toMatchKvInlineSnapshot(` 10 - name=a 11 - age=23 12 - `) 13 - expect(trial).toBe(2) 14 - }) 15 - 16 - test('throw then stable', async () => { 17 - let trial = 0 18 - await expect.poll(() => { 19 - trial++ 20 - if (trial <= 3) { 21 - throw new Error(`Fail at ${trial}`) 22 - } 23 - return { name: 'b', age: '23' } 24 - }, { interval: 10 }).toMatchKvInlineSnapshot(` 25 - name=b 26 - age=23 27 - `) 28 - expect(trial).toBe(5) 29 - }) 30 - 31 - test('unstable then stable', async () => { 32 - let trial = 0 33 - await expect.poll(() => { 34 - trial++ 35 - if (trial <= 3) return { status: 'loading', trial } // unstable 36 - return { status: 'done' } // then stable 37 - }, { interval: 10 }).toMatchKvInlineSnapshot(` 38 - status=done 39 - `) 40 - expect(trial).toBe(5) 41 - }) 42 - 43 - test('multiple poll snapshots', async () => { 44 - await expect.poll(() => { 45 - return { x: '1' } 46 - }, { interval: 10 }).toMatchKvInlineSnapshot(` 47 - x=1 48 - `) 49 - 50 - await expect.poll(() => { 51 - return { y: '2' } 52 - }, { interval: 10 }).toMatchKvInlineSnapshot(` 53 - y=2 54 - `) 55 - }) 56 - 57 - test('non-poll alongside poll', async () => { 58 - expect({ static: 'value' }).toMatchKvInlineSnapshot(` 59 - static=value 60 - `) 61 - 62 - await expect.poll(() => { 63 - return { polled: 'value' } 64 - }, { interval: 10 }).toMatchKvInlineSnapshot(` 65 - polled=value 66 - `) 67 - 68 - expect({ another: 'static' }).toMatchKvInlineSnapshot(` 69 - another=static 70 - `) 71 - }) 72 - 73 - test('empty snapshot', async () => { 74 - await expect.poll(() => { 75 - return {} 76 - }, { interval: 10 }).toMatchKvInlineSnapshot(``) 77 - })
-1
test/snapshots/test/fixtures/domain-poll/.gitignore
··· 1 - __snapshots__/
-58
test/snapshots/test/fixtures/domain-poll/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - import "../domain/basic-extend" 3 - 4 - test('stable', async () => { 5 - let trial = 0 6 - await expect.poll(() => { 7 - trial++ 8 - return { name: 'a', age: '23' } 9 - }, { interval: 10 }).toMatchKvSnapshot() 10 - expect(trial).toBe(2) 11 - }) 12 - 13 - test('throw then stable', async () => { 14 - let trial = 0 15 - await expect.poll(() => { 16 - trial++ 17 - if (trial <= 3) { 18 - throw new Error(`Fail at ${trial}`) 19 - } 20 - return { name: 'b', age: '23' } 21 - }, { interval: 10 }).toMatchKvSnapshot() 22 - expect(trial).toBe(5) 23 - }) 24 - 25 - test('unstable then stable', async () => { 26 - let trial = 0 27 - await expect.poll(() => { 28 - trial++ 29 - if (trial <= 3) return { status: 'loading', trial } // unstable 30 - return { status: 'done' } // then stable 31 - }, { interval: 10 }).toMatchKvSnapshot() 32 - expect(trial).toBe(5) 33 - }) 34 - 35 - test('multiple poll snapshots', async () => { 36 - await expect.poll(() => { 37 - return { x: '1' } 38 - }, { interval: 10 }).toMatchKvSnapshot() 39 - 40 - await expect.poll(() => { 41 - return { y: '2' } 42 - }, { interval: 10 }).toMatchKvSnapshot() 43 - }) 44 - 45 - test('non-poll alongside poll', async () => { 46 - expect({ static: 'value' }).toMatchKvSnapshot() 47 - await expect.poll(() => { 48 - return { polled: 'value' } 49 - }, { interval: 10 }).toMatchKvSnapshot() 50 - 51 - expect({ another: 'static' }).toMatchKvSnapshot() 52 - }) 53 - 54 - test('empty snapshot', async () => { 55 - await expect.poll(() => { 56 - return {} 57 - }, { interval: 10 }).toMatchKvSnapshot() 58 - })
-1
test/snapshots/test/fixtures/domain/.gitignore
··· 1 - __snapshots__/
-33
test/snapshots/test/fixtures/domain/basic-extend.ts
··· 1 - import { expect, Snapshots } from "vitest" 2 - import type { MatchersObject } from "vitest" 3 - import { kvAdapter } from "./basic" 4 - 5 - interface CustomMatchers<R = unknown> { 6 - toMatchKvSnapshot: () => R 7 - toMatchKvInlineSnapshot: (snapshot?: string) => R 8 - } 9 - 10 - declare module 'vitest' { 11 - interface Assertion<T = any> extends CustomMatchers<T> {} 12 - } 13 - 14 - const matchers: MatchersObject = { 15 - toMatchKvSnapshot(actual: unknown) { 16 - return Snapshots.toMatchDomainSnapshot.call(this, kvAdapter, actual) 17 - }, 18 - toMatchKvInlineSnapshot( 19 - actual: unknown, 20 - inlineSnapshot?: string, 21 - ) { 22 - return Snapshots.toMatchDomainInlineSnapshot.call(this, kvAdapter, actual, inlineSnapshot) 23 - }, 24 - } 25 - 26 - // internal flag to allow expect.poll for snapshot matchers 27 - for (const matcher of Object.values(matchers)) { 28 - Object.assign(matcher, { 29 - __vitest_poll_takeover__: true, 30 - }) 31 - } 32 - 33 - expect.extend(matchers)
-14
test/snapshots/test/fixtures/domain/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - import "./basic-extend" 3 - 4 - test('all literal', () => { 5 - expect({ name: 'alice', age: '30' }).toMatchKvSnapshot() 6 - }) 7 - 8 - test('with regex', () => { 9 - expect({ name: 'bob', age: '24', score: '999', status: 'active' }).toMatchKvSnapshot() 10 - }) 11 - 12 - test('empty snapshot', () => { 13 - expect({}).toMatchKvSnapshot() 14 - })
-80
test/snapshots/test/fixtures/domain/basic.ts
··· 1 - import type { DomainMatchResult, DomainSnapshotAdapter } from 'vitest' 2 - 3 - // Key-value domain adapter: each snapshot is multiple lines of `key=value`. 4 - // Values can be literal strings or `/regex/` patterns in the stored snapshot. 5 - // On match, each line is checked independently — regex lines use RegExp.test(). 6 - // On partial match, `mergedExpected` preserves regex for matched lines 7 - // and substitutes literal rendered values for unmatched lines. 8 - 9 - type KVCaptured = Record<string, string> 10 - type KVExpected = Record<string, string | RegExp> 11 - 12 - function renderKV(obj: Record<string, unknown>) { 13 - const result = Object.entries(obj).map(([k, v]) => `${k}=${v}`).join('\n'); 14 - return result ? `\n${result}\n` : '' 15 - } 16 - 17 - export const kvAdapter: DomainSnapshotAdapter<KVCaptured, KVExpected> = { 18 - name: 'kv', 19 - 20 - capture(received: unknown): KVCaptured { 21 - if (received && typeof received === 'object') { 22 - return Object.fromEntries(Object.entries(received).map(([k, v]) => [k, String(v)])) 23 - } 24 - throw new TypeError('kv adapter expects a plain object') 25 - }, 26 - 27 - render(captured: KVCaptured): string { 28 - return renderKV(captured) 29 - }, 30 - 31 - parseExpected(input: string): KVExpected { 32 - if (!input.trim()) { 33 - return {} 34 - } 35 - const entries = input.trim().split('\n').map((line) => { 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) 41 - const raw = line.slice(eq + 1) 42 - const value = (raw.startsWith('/') && raw.endsWith('/') && raw.length > 1) 43 - ? new RegExp(raw.slice(1, -1)) 44 - : raw 45 - return [key, value] 46 - }) 47 - return Object.fromEntries(entries) 48 - }, 49 - 50 - match(captured: KVCaptured, expected: KVExpected): DomainMatchResult { 51 - const resolvedLines: string[] = [] 52 - let pass = true 53 - 54 - // iterate on `expected` side so extra key on `actual` side 55 - // is ignored and works as subset match 56 - for (const [key, expectedValue] of Object.entries(expected)) { 57 - const actualValue = captured[key] 58 - if (actualValue === undefined) { 59 - pass = false 60 - continue 61 - } 62 - 63 - // preserve matched pattern for normalized error diff and partial update 64 - if (expectedValue instanceof RegExp && expectedValue.test(actualValue)) { 65 - resolvedLines.push(`${key}=/${expectedValue.source}/`) 66 - continue 67 - } 68 - 69 - resolvedLines.push(`${key}=${actualValue}`) 70 - pass &&= actualValue === expectedValue 71 - } 72 - 73 - return { 74 - pass, 75 - message: pass ? undefined : 'KV entries do not match', 76 - resolved: `\n${resolvedLines.join('\n')}\n`, 77 - expected: `\n${renderKV(expected)}\n`, 78 - } 79 - }, 80 - }
-25
test/snapshots/test/fixtures/file/basic.test.ts
··· 1 - import { test, expect } from "vitest" 2 - 3 - // pnpm -C test/snapshots test:fixtures --root test/fixtures/file 4 - 5 - test('white space', async () => { 6 - await expect(` 7 - 8 - white space 9 - `).toMatchFileSnapshot('snapshot-1.txt') 10 - }) 11 - 12 - test('indent', async () => { 13 - await expect(`\ 14 - example: | 15 - { 16 - echo "hello" 17 - } 18 - some: 19 - nesting: 20 - - "hello world" 21 - even: 22 - more: 23 - nesting: true 24 - `).toMatchFileSnapshot('snapshot-2.txt') 25 - })
-3
test/snapshots/test/fixtures/file/snapshot-1.txt
··· 1 - 2 - 3 - white space
-10
test/snapshots/test/fixtures/file/snapshot-2.txt
··· 1 - example: | 2 - { 3 - echo "hello" 4 - } 5 - some: 6 - nesting: 7 - - "hello world" 8 - even: 9 - more: 10 - nesting: true
-28
test/snapshots/test/fixtures/indent/basic.test.ts
··· 1 - import { test, expect } from "vitest" 2 - 3 - // pnpm -C test/snapshots test:fixtures --root test/fixtures/indent 4 - 5 - test('toMatchSnapshot string', () => { 6 - expect(` 7 - 1111 8 - xxxx { 9 - } 10 - 11 - `).toMatchSnapshot() 12 - }) 13 - 14 - test('toMatchInlineSnapshot string', () => { 15 - expect(` 16 - 2222 17 - yyyy { 18 - } 19 - 20 - `).toMatchInlineSnapshot(` 21 - " 22 - 2222 23 - yyyy { 24 - } 25 - 26 - " 27 - `) 28 - })
-7
test/snapshots/test/fixtures/inline-multiple-calls/different.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('single', () => { 4 - for (const value of ["test1", "test2"]) { 5 - expect(value).toMatchInlineSnapshot() 6 - } 7 - })
-13
test/snapshots/test/fixtures/inline-multiple-calls/different2.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('a', () => { 4 - snap('test1') 5 - }) 6 - 7 - test('b', () => { 8 - snap('test2') 9 - }) 10 - 11 - function snap(value: unknown) { 12 - expect(value).toMatchInlineSnapshot() 13 - }
-17
test/snapshots/test/fixtures/inline-multiple-calls/each.test.ts
··· 1 - import { expect, test, describe } from "vitest"; 2 - 3 - test.for(["hello", "world"])("test %s", (arg) => { 4 - expect(arg.length).toMatchInlineSnapshot(`5`); 5 - }); 6 - 7 - describe.for(["hello", "world"])("suite %s", (arg) => { 8 - test("length", () => { 9 - expect(arg.length).toMatchInlineSnapshot(`5`); 10 - }); 11 - }); 12 - 13 - test.for(["hello", "world"])("toThrowErrorMatchingInlineSnapshot %s", (arg) => { 14 - expect(() => { 15 - throw new Error(`length = ${arg.length}`); 16 - }).toThrowErrorMatchingInlineSnapshot(`[Error: length = 5]`) 17 - });
-7
test/snapshots/test/fixtures/inline-multiple-calls/same.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('single', () => { 4 - for (const value of ["test1", "test1"]) { 5 - expect(value).toMatchInlineSnapshot(`"test1"`) 6 - } 7 - })
-13
test/snapshots/test/fixtures/inline-multiple-calls/same2.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('a', () => { 4 - snap('test1') 5 - }) 6 - 7 - test('b', () => { 8 - snap('test1') 9 - }) 10 - 11 - function snap(value: unknown) { 12 - expect(value).toMatchInlineSnapshot(`"test1"`) 13 - }
-19
test/snapshots/test/fixtures/jest-image-snapshot/basic.test.ts
··· 1 - import { expect, it } from "vitest"; 2 - import fs from "fs"; 3 - 4 - // @ts-expect-error no type 5 - import { toMatchImageSnapshot } from "jest-image-snapshot"; 6 - expect.extend({ toMatchImageSnapshot }); 7 - 8 - declare module 'vitest' { 9 - interface Assertion<T = any> { 10 - toMatchImageSnapshot(): void 11 - } 12 - } 13 - 14 - // pnpm -C test/snapshots test:fixtures --root test/fixtures/jest-image-snapshot 15 - 16 - it("toMatchImageSnapshot", async () => { 17 - const file = new URL("./test.png", import.meta.url) 18 - expect(fs.readFileSync(file)).toMatchImageSnapshot(); 19 - });
test/snapshots/test/fixtures/jest-image-snapshot/test.png

This is a binary file and will not be displayed.

-3
test/snapshots/test/fixtures/obsolete/vitest.config.ts
··· 1 - import { defineConfig } from 'vitest/config' 2 - 3 - export default defineConfig({})
-1
test/snapshots/test/fixtures/properties/.gitignore
··· 1 - __snapshots__
-28
test/snapshots/test/fixtures/properties/basic.test.ts
··· 1 - import { expect, test } from "vitest"; 2 - 3 - test("file", () => { 4 - expect({ name: "alice", age: 30 }).toMatchSnapshot({ age: expect.any(Number) }); 5 - }); 6 - 7 - test("file asymmetric", () => { 8 - expect({ name: "bob", score: 95 }).toMatchSnapshot({ 9 - score: expect.toSatisfy(function lessThan100(n) { 10 - return n < 100; 11 - }), 12 - }); 13 - }); 14 - 15 - test("file snapshot-only", () => { 16 - expect({ name: "dave", age: 42 }).toMatchSnapshot({ age: expect.any(Number) }); 17 - }); 18 - 19 - // -- TEST INLINE START -- 20 - test("inline", () => { 21 - expect({ name: "carol", age: 25 }).toMatchInlineSnapshot({ age: expect.any(Number) }, ` 22 - Object { 23 - "age": Any<Number>, 24 - "name": "carol", 25 - } 26 - `); 27 - }); 28 - // -- TEST INLINE END --
-11
test/snapshots/test/fixtures/skip-test-custom/basic.test.ts
··· 1 - import { expect, test } from 'vitest'; 2 - 3 - test('custom a', () => { 4 - expect(0).toMatchSnapshot('x'); 5 - expect(0).toMatchSnapshot('y'); 6 - }); 7 - 8 - test('custom b', () => { 9 - expect(0).toMatchSnapshot('z'); 10 - expect(0).toMatchSnapshot('w'); 11 - });
-20
test/snapshots/test/fixtures/skip-test/repro.test.ts
··· 1 - import { describe, expect, it } from 'vitest' 2 - 3 - const ENABLE_SKIP = process.env.ENABLE_SKIP; 4 - 5 - describe.skipIf(ENABLE_SKIP)('repro suite', () => { 6 - it('inner case', () => { 7 - expect('hi-1').toMatchSnapshot() 8 - }) 9 - }) 10 - 11 - it.skipIf(ENABLE_SKIP)('top-level case', () => { 12 - expect('hi-2').toMatchSnapshot() 13 - }) 14 - 15 - // at least one non-skipped test is needed to reproduce a bug. 16 - // without this, there will be no SnapshotClient.startCurrentRun, 17 - // so the code to check skip/obsolete snapshot is not exercised. 18 - it('normal case', () => { 19 - expect(0).toBe(0) 20 - })
-3
test/snapshots/test/fixtures/skip-test/vitest.config.ts
··· 1 - import { defineConfig } from 'vitest/config' 2 - 3 - export default defineConfig({})
-11
test/snapshots/test/fixtures/soft-inline/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('toMatchInlineSnapshot', () => { 4 - expect.soft('--snap-1--').toMatchInlineSnapshot(`"--snap-1--"`) 5 - expect.soft('--snap-2--').toMatchInlineSnapshot(`"--snap-2--"`) 6 - }) 7 - 8 - test('toThrowErrorMatchingInlineSnapshot', () => { 9 - expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingInlineSnapshot(`[Error: --error-1--]`) 10 - expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingInlineSnapshot(`[Error: --error-2--]`) 11 - })
-1
test/snapshots/test/fixtures/soft/.gitignore
··· 1 - __snapshots__
-16
test/snapshots/test/fixtures/soft/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('toMatchSnapshot', () => { 4 - expect.soft('--snap-1--').toMatchSnapshot() 5 - expect.soft('--snap-2--').toMatchSnapshot() 6 - }) 7 - 8 - test('toMatchFileSnapshot', async () => { 9 - await expect.soft('--file-1--').toMatchFileSnapshot('./__snapshots__/custom1.txt') 10 - await expect.soft('--file-2--').toMatchFileSnapshot('./__snapshots__/custom2.txt') 11 - }) 12 - 13 - test('toThrowErrorMatchingSnapshot', () => { 14 - expect.soft(() => { throw new Error('--error-1--') }).toThrowErrorMatchingSnapshot() 15 - expect.soft(() => { throw new Error('--error-2--') }).toThrowErrorMatchingSnapshot() 16 - })
-1
test/snapshots/test/fixtures/summary-removed/.gitignore
··· 1 - __snapshots__
-11
test/snapshots/test/fixtures/summary-removed/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('x', () => { 4 - expect(0).toMatchSnapshot() 5 - }) 6 - 7 - // REMOVE-START 8 - test('y', () => { 9 - expect(0).toMatchSnapshot() 10 - }) 11 - // REMOVE-END
-52
test/snapshots/test/fixtures/summary/basic.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('inline normal', () => { 4 - expect('@SNAP1').toMatchInlineSnapshot(`"@SNAP1"`) 5 - }) 6 - 7 - test('inline repeats', { repeats: 1 }, () => { 8 - expect('@SNAP2').toMatchInlineSnapshot(`"@SNAP2"`) 9 - }) 10 - 11 - test('inline retry', { retry: 1 }, (ctx) => { 12 - expect('@SNAP3').toMatchInlineSnapshot(`"@SNAP3"`) 13 - if (ctx.task.result?.retryCount === 0) { 14 - throw new Error('boom') 15 - } 16 - }) 17 - 18 - test('file normal', () => { 19 - expect('@SNAP4').toMatchSnapshot() 20 - }) 21 - 22 - test('file repeats', { repeats: 1 }, () => { 23 - expect('@SNAP5').toMatchSnapshot() 24 - }) 25 - 26 - test('file retry', { retry: 1 }, (ctx) => { 27 - expect('@SNAP6').toMatchSnapshot() 28 - if (ctx.task.result?.retryCount === 0) { 29 - throw new Error('@retry') 30 - } 31 - }) 32 - 33 - test('file repeats many', { repeats: 1 }, () => { 34 - expect('@SNAP7').toMatchSnapshot() 35 - expect('@SNAP8').toMatchSnapshot() 36 - }) 37 - 38 - test('file retry many', { retry: 1 }, (ctx) => { 39 - expect('@SNAP9').toMatchSnapshot() 40 - expect('@SNAP10').toMatchSnapshot() 41 - if (ctx.task.result?.retryCount === 0) { 42 - throw new Error('@retry') 43 - } 44 - }) 45 - 46 - test('file retry partial', { retry: 1 }, (ctx) => { 47 - expect('@SNAP11').toMatchSnapshot() 48 - if (ctx.task.result?.retryCount === 0) { 49 - throw new Error('@retry') 50 - } 51 - expect('@SNAP12').toMatchSnapshot() 52 - })
-1
test/snapshots/test/fixtures/summary/vitest.config.ts
··· 1 - export default {}
-13
test/snapshots/test/fixtures/test-update-result/inline-concurrent.test.js
··· 1 - import { it } from 'vitest' 2 - 3 - it.concurrent('1st', ({ expect }) => { 4 - expect('hi1').toMatchInlineSnapshot(`"hi1"`) 5 - }) 6 - 7 - it.concurrent('2nd', ({ expect }) => { 8 - expect('hi2').toMatchInlineSnapshot(`"hi2"`) 9 - }) 10 - 11 - it.concurrent('3rd', ({ expect }) => { 12 - expect('hi3').toMatchInlineSnapshot(`"hi3"`) 13 - })
-69
test/snapshots/test/fixtures/test-update-result/inline.test.js
··· 1 - import { describe, expect, test } from 'vitest' 2 - 3 - // when snapshots are generated Vitest reruns `toMatchInlineSnapshot` checks 4 - // please, don't commit generated snapshots 5 - describe('snapshots are generated in correct order', async () => { 6 - test('first snapshot', () => { 7 - expect({ foo: ['bar'] }).toMatchInlineSnapshot(` 8 - Object { 9 - "foo": Array [ 10 - "bar", 11 - ], 12 - } 13 - `) 14 - }) 15 - 16 - test('second snapshot', () => { 17 - expect({ foo: ['zed'] }).toMatchInlineSnapshot(` 18 - Object { 19 - "foo": Array [ 20 - "zed", 21 - ], 22 - } 23 - `) 24 - }) 25 - }) 26 - 27 - describe('snapshots with properties', () => { 28 - test('without snapshot', () => { 29 - expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, ` 30 - Object { 31 - "foo": Any<String>, 32 - } 33 - `) 34 - }) 35 - 36 - test('with snapshot', () => { 37 - expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 38 - Object { 39 - "first": Object { 40 - "second": Object { 41 - "foo": Any<String>, 42 - }, 43 - }, 44 - } 45 - `) 46 - }) 47 - 48 - test('mixed with and without snapshot', () => { 49 - expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 50 - Object { 51 - "first": Object { 52 - "second": Object { 53 - "foo": Any<String>, 54 - }, 55 - }, 56 - } 57 - `) 58 - 59 - expect({ first: { second: { foo: 'zed' } } }).toMatchInlineSnapshot(` 60 - Object { 61 - "first": Object { 62 - "second": Object { 63 - "foo": "zed", 64 - }, 65 - }, 66 - } 67 - `) 68 - }) 69 - })
-33
test/snapshots/test/fixtures/test-update-result/retry-file.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('file repeats', { repeats: 1 }, () => { 4 - expect('foo').toMatchSnapshot() 5 - }) 6 - 7 - test('file retry', { retry: 1 }, (ctx) => { 8 - expect('foo').toMatchSnapshot() 9 - if (ctx.task.result?.retryCount === 0) { 10 - throw new Error('boom') 11 - } 12 - }) 13 - 14 - test('file repeats many', { repeats: 1 }, () => { 15 - expect('foo').toMatchSnapshot() 16 - expect('bar').toMatchSnapshot() 17 - }) 18 - 19 - test('file retry many', { retry: 1 }, (ctx) => { 20 - expect('foo').toMatchSnapshot() 21 - expect('bar').toMatchSnapshot() 22 - if (ctx.task.result?.retryCount === 0) { 23 - throw new Error('boom') 24 - } 25 - }) 26 - 27 - test('file retry partial', { retry: 1 }, (ctx) => { 28 - expect('foo').toMatchSnapshot() 29 - if (ctx.task.result?.retryCount === 0) { 30 - throw new Error('boom') 31 - } 32 - expect('bar').toMatchSnapshot() 33 - })
-12
test/snapshots/test/fixtures/test-update-result/retry-inline.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('inline repeats', { repeats: 1 }, () => { 4 - expect('foo').toMatchInlineSnapshot(`"foo"`) 5 - }) 6 - 7 - test('inline retry', { retry: 1 }, (ctx) => { 8 - expect('foo').toMatchInlineSnapshot(`"foo"`) 9 - if (ctx.task.result?.retryCount === 0) { 10 - throw new Error('boom') 11 - } 12 - })
-20
test/snapshots/test/fixtures/test-update-result/same-title-file.test.js
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('same title exist', () => { 4 - // correct entry exists in .snap 5 - expect('a').toMatchSnapshot() 6 - }) 7 - 8 - test('same title exist', () => { 9 - // wrong entry exists in .snap 10 - expect('b').toMatchSnapshot() 11 - }) 12 - 13 - test('same title new', () => { 14 - expect('a').toMatchSnapshot() 15 - }) 16 - 17 - test('same title new', () => { 18 - expect('b').toMatchSnapshot() 19 - expect('c').toMatchSnapshot() 20 - })
-16
test/snapshots/test/fixtures/test-update-result/same-title-inline.test.js
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('same title', () => { 4 - expect('new').toMatchInlineSnapshot(`"new"`) 5 - expect('new').toMatchInlineSnapshot(`"new"`) 6 - }) 7 - 8 - test('same title', () => { 9 - expect('a').toMatchInlineSnapshot(`"a"`) 10 - expect('a').toMatchInlineSnapshot(`"a"`) 11 - }) 12 - 13 - test('same title', () => { 14 - expect('b').toMatchInlineSnapshot(`"b"`) 15 - expect('b').toMatchInlineSnapshot(`"b"`) 16 - })
-13
test/snapshots/test/fixtures/test-update/inline-concurrent.test.js
··· 1 - import { it } from 'vitest' 2 - 3 - it.concurrent('1st', ({ expect }) => { 4 - expect('hi1').toMatchInlineSnapshot() 5 - }) 6 - 7 - it.concurrent('2nd', ({ expect }) => { 8 - expect('hi2').toMatchInlineSnapshot() 9 - }) 10 - 11 - it.concurrent('3rd', ({ expect }) => { 12 - expect('hi3').toMatchInlineSnapshot() 13 - })
-51
test/snapshots/test/fixtures/test-update/inline.test.js
··· 1 - import { describe, expect, test } from 'vitest' 2 - 3 - // when snapshots are generated Vitest reruns `toMatchInlineSnapshot` checks 4 - // please, don't commit generated snapshots 5 - describe('snapshots are generated in correct order', async () => { 6 - test('first snapshot', () => { 7 - expect({ foo: ['bar'] }).toMatchInlineSnapshot() 8 - }) 9 - 10 - test('second snapshot', () => { 11 - expect({ foo: ['zed'] }).toMatchInlineSnapshot() 12 - }) 13 - }) 14 - 15 - describe('snapshots with properties', () => { 16 - test('without snapshot', () => { 17 - expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }) 18 - }) 19 - 20 - test('with snapshot', () => { 21 - expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 22 - Object { 23 - "first": Object { 24 - "wrong": Any<String>, 25 - "second": null, 26 - } 27 - } 28 - `) 29 - }) 30 - 31 - test('mixed with and without snapshot', () => { 32 - expect({ first: { second: { foo: 'bar' } } }).toMatchInlineSnapshot({ first: { second: { foo: expect.any(String) } } }, ` 33 - Object { 34 - "first": Object { 35 - "wrong": Any<String>, 36 - "second": null, 37 - } 38 - } 39 - `) 40 - 41 - expect({ first: { second: { foo: 'zed' } } }).toMatchInlineSnapshot(` 42 - Object { 43 - "first": Object { 44 - "second": { 45 - "foo": "zed" 46 - } 47 - } 48 - } 49 - `) 50 - }) 51 - })
-33
test/snapshots/test/fixtures/test-update/retry-file.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('file repeats', { repeats: 1 }, () => { 4 - expect('foo').toMatchSnapshot() 5 - }) 6 - 7 - test('file retry', { retry: 1 }, (ctx) => { 8 - expect('foo').toMatchSnapshot() 9 - if (ctx.task.result?.retryCount === 0) { 10 - throw new Error('boom') 11 - } 12 - }) 13 - 14 - test('file repeats many', { repeats: 1 }, () => { 15 - expect('foo').toMatchSnapshot() 16 - expect('bar').toMatchSnapshot() 17 - }) 18 - 19 - test('file retry many', { retry: 1 }, (ctx) => { 20 - expect('foo').toMatchSnapshot() 21 - expect('bar').toMatchSnapshot() 22 - if (ctx.task.result?.retryCount === 0) { 23 - throw new Error('boom') 24 - } 25 - }) 26 - 27 - test('file retry partial', { retry: 1 }, (ctx) => { 28 - expect('foo').toMatchSnapshot() 29 - if (ctx.task.result?.retryCount === 0) { 30 - throw new Error('boom') 31 - } 32 - expect('bar').toMatchSnapshot() 33 - })
-12
test/snapshots/test/fixtures/test-update/retry-inline.test.ts
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('inline repeats', { repeats: 1 }, () => { 4 - expect('foo').toMatchInlineSnapshot() 5 - }) 6 - 7 - test('inline retry', { retry: 1 }, (ctx) => { 8 - expect('foo').toMatchInlineSnapshot() 9 - if (ctx.task.result?.retryCount === 0) { 10 - throw new Error('boom') 11 - } 12 - })
-20
test/snapshots/test/fixtures/test-update/same-title-file.test.js
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('same title exist', () => { 4 - // correct entry exists in .snap 5 - expect('a').toMatchSnapshot() 6 - }) 7 - 8 - test('same title exist', () => { 9 - // wrong entry exists in .snap 10 - expect('b').toMatchSnapshot() 11 - }) 12 - 13 - test('same title new', () => { 14 - expect('a').toMatchSnapshot() 15 - }) 16 - 17 - test('same title new', () => { 18 - expect('b').toMatchSnapshot() 19 - expect('c').toMatchSnapshot() 20 - })
-16
test/snapshots/test/fixtures/test-update/same-title-inline.test.js
··· 1 - import { expect, test } from 'vitest' 2 - 3 - test('same title', () => { 4 - expect('new').toMatchInlineSnapshot() 5 - expect('new').toMatchInlineSnapshot() 6 - }) 7 - 8 - test('same title', () => { 9 - expect('a').toMatchInlineSnapshot(`"a"`) 10 - expect('a').toMatchInlineSnapshot(`"a"`) 11 - }) 12 - 13 - test('same title', () => { 14 - expect('b').toMatchInlineSnapshot(`"wrong"`) 15 - expect('b').toMatchInlineSnapshot(`"wrong"`) 16 - })
-7
test/snapshots/test/fixtures/workspace/vitest.config.ts
··· 1 - import { defineConfig } from 'vitest/config' 2 - 3 - export default defineConfig({ 4 - test: { 5 - projects: ['packages/*'], 6 - }, 7 - })
+25
test/e2e/snapshots/fixtures/compare-keys/__snapshots__/basic.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`compareKeys 1`] = ` 4 + { 5 + "a": 1, 6 + "b": 2, 7 + "c": 3, 8 + } 9 + `; 10 + 11 + exports[`compareKeys 2`] = ` 12 + { 13 + "a": 3, 14 + "b": 2, 15 + "c": 1, 16 + } 17 + `; 18 + 19 + exports[`compareKeys 3`] = ` 20 + { 21 + "a": 2, 22 + "b": 1, 23 + "c": 3, 24 + } 25 + `;
+9
test/e2e/snapshots/fixtures/custom-snapshot-environment/test/snapshots.test.ts
··· 1 + import {test, expect} from 'vitest' 2 + 3 + test('regular snapshot', () => { 4 + expect({ a: 1 }).toMatchSnapshot() 5 + }) 6 + 7 + test('inline snapshot', () => { 8 + expect({ a: 1 }).toMatchInlineSnapshot() 9 + })
+6
test/e2e/snapshots/fixtures/domain-error/__snapshots__/basic.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`file 1`] = ` 4 + name=alice 5 + file-broken 6 + `;
+10
test/e2e/snapshots/fixtures/indent/__snapshots__/basic.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`toMatchSnapshot string 1`] = ` 4 + " 5 + 1111 6 + xxxx { 7 + } 8 + 9 + " 10 + `;
test/e2e/snapshots/fixtures/jest-image-snapshot/__image_snapshots__/basic-test-ts-to-match-image-snapshot-1-snap.png

This is a binary file and will not be displayed.

+15
test/e2e/snapshots/fixtures/obsolete/src/test1.test.ts
··· 1 + import { expect, it } from 'vitest' 2 + 3 + it('foo', () => { 4 + if (process.env.TEST_OBSOLETE) return 5 + expect("foo").toMatchSnapshot(); 6 + }) 7 + 8 + it('fuu', () => { 9 + if (process.env.TEST_OBSOLETE) return 10 + expect("fuu").toMatchSnapshot(); 11 + }) 12 + 13 + it('bar', () => { 14 + expect("bar").toMatchSnapshot(); 15 + })
+9
test/e2e/snapshots/fixtures/obsolete/src/test2.test.ts
··· 1 + import { expect, it } from 'vitest' 2 + 3 + it('foo', () => { 4 + expect("foo").toMatchSnapshot(); 5 + }) 6 + 7 + it('bar', () => { 8 + expect("bar").toMatchSnapshot(); 9 + })
+9
test/e2e/snapshots/fixtures/skip-test-custom/__snapshots__/basic.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`custom a > x 1`] = `0`; 4 + 5 + exports[`custom a > y 1`] = `0`; 6 + 7 + exports[`custom b > w 1`] = `0`; 8 + 9 + exports[`custom b > z 1`] = `0`;
+5
test/e2e/snapshots/fixtures/skip-test/__snapshots__/repro.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`repro suite > inner case 1`] = `"hi-1"`; 4 + 5 + exports[`top-level case 1`] = `"hi-2"`;
+19
test/e2e/snapshots/fixtures/summary/__snapshots__/basic.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`file normal 1`] = `"@SNAP4"`; 4 + 5 + exports[`file repeats 1`] = `"@SNAP5"`; 6 + 7 + exports[`file repeats many 1`] = `"@SNAP7"`; 8 + 9 + exports[`file repeats many 2`] = `"@SNAP8"`; 10 + 11 + exports[`file retry 1`] = `"@SNAP6"`; 12 + 13 + exports[`file retry many 1`] = `"@SNAP9"`; 14 + 15 + exports[`file retry many 2`] = `"@SNAP10"`; 16 + 17 + exports[`file retry partial 1`] = `"@SNAP11"`; 18 + 19 + exports[`file retry partial 2`] = `"@SNAP12"`;
+17
test/e2e/snapshots/fixtures/test-update-result/__snapshots__/retry-file.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`file repeats 1`] = `"foo"`; 4 + 5 + exports[`file repeats many 1`] = `"foo"`; 6 + 7 + exports[`file repeats many 2`] = `"bar"`; 8 + 9 + exports[`file retry 1`] = `"foo"`; 10 + 11 + exports[`file retry many 1`] = `"foo"`; 12 + 13 + exports[`file retry many 2`] = `"bar"`; 14 + 15 + exports[`file retry partial 1`] = `"foo"`; 16 + 17 + exports[`file retry partial 2`] = `"bar"`;
+11
test/e2e/snapshots/fixtures/test-update-result/__snapshots__/same-title-file.test.js.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`same title exist 1`] = `"a"`; 4 + 5 + exports[`same title exist 2`] = `"b"`; 6 + 7 + exports[`same title new 1`] = `"a"`; 8 + 9 + exports[`same title new 2`] = `"b"`; 10 + 11 + exports[`same title new 3`] = `"c"`;
+17
test/e2e/snapshots/fixtures/test-update/__snapshots__/retry-file.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`file repeats 1`] = `"foo"`; 4 + 5 + exports[`file repeats many 1`] = `"foo"`; 6 + 7 + exports[`file repeats many 2`] = `"bar"`; 8 + 9 + exports[`file retry 1`] = `"foo"`; 10 + 11 + exports[`file retry many 1`] = `"foo"`; 12 + 13 + exports[`file retry many 2`] = `"bar"`; 14 + 15 + exports[`file retry partial 1`] = `"foo"`; 16 + 17 + exports[`file retry partial 2`] = `"bar"`;
+5
test/e2e/snapshots/fixtures/test-update/__snapshots__/same-title-file.test.js.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`same title exist 1`] = `"a"`; 4 + 5 + exports[`same title exist 2`] = `"wrong"`;
-25
test/snapshots/test/fixtures/compare-keys/__snapshots__/basic.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`compareKeys 1`] = ` 4 - { 5 - "a": 1, 6 - "b": 2, 7 - "c": 3, 8 - } 9 - `; 10 - 11 - exports[`compareKeys 2`] = ` 12 - { 13 - "a": 3, 14 - "b": 2, 15 - "c": 1, 16 - } 17 - `; 18 - 19 - exports[`compareKeys 3`] = ` 20 - { 21 - "a": 2, 22 - "b": 1, 23 - "c": 3, 24 - } 25 - `;
-9
test/snapshots/test/fixtures/custom-snapshot-environment/test/snapshots.test.ts
··· 1 - import {test, expect} from 'vitest' 2 - 3 - test('regular snapshot', () => { 4 - expect({ a: 1 }).toMatchSnapshot() 5 - }) 6 - 7 - test('inline snapshot', () => { 8 - expect({ a: 1 }).toMatchInlineSnapshot() 9 - })
-6
test/snapshots/test/fixtures/domain-error/__snapshots__/basic.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`file 1`] = ` 4 - name=alice 5 - file-broken 6 - `;
-10
test/snapshots/test/fixtures/indent/__snapshots__/basic.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`toMatchSnapshot string 1`] = ` 4 - " 5 - 1111 6 - xxxx { 7 - } 8 - 9 - " 10 - `;
test/snapshots/test/fixtures/jest-image-snapshot/__image_snapshots__/basic-test-ts-to-match-image-snapshot-1-snap.png

This is a binary file and will not be displayed.

-15
test/snapshots/test/fixtures/obsolete/src/test1.test.ts
··· 1 - import { expect, it } from 'vitest' 2 - 3 - it('foo', () => { 4 - if (process.env.TEST_OBSOLETE) return 5 - expect("foo").toMatchSnapshot(); 6 - }) 7 - 8 - it('fuu', () => { 9 - if (process.env.TEST_OBSOLETE) return 10 - expect("fuu").toMatchSnapshot(); 11 - }) 12 - 13 - it('bar', () => { 14 - expect("bar").toMatchSnapshot(); 15 - })
-9
test/snapshots/test/fixtures/obsolete/src/test2.test.ts
··· 1 - import { expect, it } from 'vitest' 2 - 3 - it('foo', () => { 4 - expect("foo").toMatchSnapshot(); 5 - }) 6 - 7 - it('bar', () => { 8 - expect("bar").toMatchSnapshot(); 9 - })
-9
test/snapshots/test/fixtures/skip-test-custom/__snapshots__/basic.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`custom a > x 1`] = `0`; 4 - 5 - exports[`custom a > y 1`] = `0`; 6 - 7 - exports[`custom b > w 1`] = `0`; 8 - 9 - exports[`custom b > z 1`] = `0`;
-5
test/snapshots/test/fixtures/skip-test/__snapshots__/repro.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`repro suite > inner case 1`] = `"hi-1"`; 4 - 5 - exports[`top-level case 1`] = `"hi-2"`;
-19
test/snapshots/test/fixtures/summary/__snapshots__/basic.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`file normal 1`] = `"@SNAP4"`; 4 - 5 - exports[`file repeats 1`] = `"@SNAP5"`; 6 - 7 - exports[`file repeats many 1`] = `"@SNAP7"`; 8 - 9 - exports[`file repeats many 2`] = `"@SNAP8"`; 10 - 11 - exports[`file retry 1`] = `"@SNAP6"`; 12 - 13 - exports[`file retry many 1`] = `"@SNAP9"`; 14 - 15 - exports[`file retry many 2`] = `"@SNAP10"`; 16 - 17 - exports[`file retry partial 1`] = `"@SNAP11"`; 18 - 19 - exports[`file retry partial 2`] = `"@SNAP12"`;
-17
test/snapshots/test/fixtures/test-update-result/__snapshots__/retry-file.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`file repeats 1`] = `"foo"`; 4 - 5 - exports[`file repeats many 1`] = `"foo"`; 6 - 7 - exports[`file repeats many 2`] = `"bar"`; 8 - 9 - exports[`file retry 1`] = `"foo"`; 10 - 11 - exports[`file retry many 1`] = `"foo"`; 12 - 13 - exports[`file retry many 2`] = `"bar"`; 14 - 15 - exports[`file retry partial 1`] = `"foo"`; 16 - 17 - exports[`file retry partial 2`] = `"bar"`;
-11
test/snapshots/test/fixtures/test-update-result/__snapshots__/same-title-file.test.js.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`same title exist 1`] = `"a"`; 4 - 5 - exports[`same title exist 2`] = `"b"`; 6 - 7 - exports[`same title new 1`] = `"a"`; 8 - 9 - exports[`same title new 2`] = `"b"`; 10 - 11 - exports[`same title new 3`] = `"c"`;
-17
test/snapshots/test/fixtures/test-update/__snapshots__/retry-file.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`file repeats 1`] = `"foo"`; 4 - 5 - exports[`file repeats many 1`] = `"foo"`; 6 - 7 - exports[`file repeats many 2`] = `"bar"`; 8 - 9 - exports[`file retry 1`] = `"foo"`; 10 - 11 - exports[`file retry many 1`] = `"foo"`; 12 - 13 - exports[`file retry many 2`] = `"bar"`; 14 - 15 - exports[`file retry partial 1`] = `"foo"`; 16 - 17 - exports[`file retry partial 2`] = `"bar"`;
-5
test/snapshots/test/fixtures/test-update/__snapshots__/same-title-file.test.js.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`same title exist 1`] = `"a"`; 4 - 5 - exports[`same title exist 2`] = `"wrong"`;
+7
test/e2e/snapshots/fixtures/obsolete/src/__snapshots__/test1.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`bar 1`] = `"bar"`; 4 + 5 + exports[`foo 1`] = `"foo"`; 6 + 7 + exports[`fuu 1`] = `"fuu"`;
+5
test/e2e/snapshots/fixtures/obsolete/src/__snapshots__/test2.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`bar 1`] = `"bar"`; 4 + 5 + exports[`foo 1`] = `"foo"`;
+5
test/e2e/snapshots/fixtures/workspace/packages/space/vite.config.ts
··· 1 + import { defineProject } from 'vitest/config' 2 + 3 + export default defineProject({ 4 + test: {}, 5 + })
-7
test/snapshots/test/fixtures/obsolete/src/__snapshots__/test1.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`bar 1`] = `"bar"`; 4 - 5 - exports[`foo 1`] = `"foo"`; 6 - 7 - exports[`fuu 1`] = `"fuu"`;
-5
test/snapshots/test/fixtures/obsolete/src/__snapshots__/test2.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`bar 1`] = `"bar"`; 4 - 5 - exports[`foo 1`] = `"foo"`;
-5
test/snapshots/test/fixtures/workspace/packages/space/vite.config.ts
··· 1 - import { defineProject } from 'vitest/config' 2 - 3 - export default defineProject({ 4 - test: {}, 5 - })
+5
test/e2e/snapshots/fixtures/workspace/packages/space/test/basic.test.ts
··· 1 + import { test, expect } from "vitest" 2 + 3 + test("basic", () => { 4 + expect(1).toMatchSnapshot() 5 + })
-5
test/snapshots/test/fixtures/workspace/packages/space/test/basic.test.ts
··· 1 - import { test, expect } from "vitest" 2 - 3 - test("basic", () => { 4 - expect(1).toMatchSnapshot() 5 - })
+3
test/e2e/snapshots/fixtures/workspace/packages/space/test/__snapshots__/basic.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`basic 1`] = `1`;
-3
test/snapshots/test/fixtures/workspace/packages/space/test/__snapshots__/basic.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`basic 1`] = `1`;