mirror of
https://github.com/hanzoai/vitest.git
synced 2026-09-24 17:04:25 +00:00
557 lines
14 KiB
TypeScript
557 lines
14 KiB
TypeScript
import fs, { readFileSync } from 'node:fs'
|
||
import { join } from 'node:path'
|
||
import { playwright } from '@vitest/browser-playwright'
|
||
import { expect, test } from 'vitest'
|
||
import { editFile, runInlineTests, runVitest } from '../../test-utils'
|
||
import { extractInlineSnaphsots } from './utils'
|
||
|
||
test('custom snapshot matcher', async () => {
|
||
const root = join(import.meta.dirname, 'fixtures/custom-matcher')
|
||
const testFile = join(root, 'basic.test.ts')
|
||
const snapshotFile = join(root, '__snapshots__/basic.test.ts.snap')
|
||
const rawSnapshotFile = join(root, '__snapshots__/raw.txt')
|
||
|
||
// remove snapshots
|
||
fs.rmSync(join(root, '__snapshots__'), { recursive: true, force: true })
|
||
editFile(testFile, s => s.replace(/(toMatchCustom(?:Async)?InlineSnapshot)\(`[^`]*`\)/g, '$1()'))
|
||
|
||
// create snapshots from scratch
|
||
let result = await runVitest({ root, update: 'new' })
|
||
expect(result.stderr).toMatchInlineSnapshot(`""`)
|
||
expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(`
|
||
"// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||
|
||
exports[\`file 1\`] = \`
|
||
{
|
||
"length": 6,
|
||
"reversed": "ahahah",
|
||
}
|
||
\`;
|
||
|
||
exports[\`properties 1 1\`] = \`
|
||
{
|
||
"length": 6,
|
||
"reversed": "opopop",
|
||
}
|
||
\`;
|
||
|
||
exports[\`properties 2 1\`] = \`
|
||
{
|
||
"length": toSatisfy<[Function lessThan10]>,
|
||
"reversed": "epepep",
|
||
}
|
||
\`;
|
||
"
|
||
`)
|
||
expect(readFileSync(rawSnapshotFile, 'utf-8')).toMatchInlineSnapshot(`
|
||
"{
|
||
"length": 6,
|
||
"reversed": "ihihih",
|
||
}"
|
||
`)
|
||
expect(extractInlineSnaphsots(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(`
|
||
"
|
||
expect(\`hehehe\`).toMatchCustomInlineSnapshot(\`
|
||
{
|
||
"length": 6,
|
||
"reversed": "eheheh",
|
||
}
|
||
\`)
|
||
|
||
expect(\`huhuhu\`).toMatchCustomAsyncInlineSnapshot(\`
|
||
{
|
||
"length": 6,
|
||
"reversed": "uhuhuh",
|
||
}
|
||
\`)
|
||
"
|
||
`)
|
||
expect(result.errorTree()).toMatchInlineSnapshot(`
|
||
{
|
||
"basic.test.ts": {
|
||
"async inline": "passed",
|
||
"file": "passed",
|
||
"inline": "passed",
|
||
"properties 1": "passed",
|
||
"properties 2": "passed",
|
||
"raw": "passed",
|
||
},
|
||
}
|
||
`)
|
||
|
||
// edit tests to introduce snapshot errors
|
||
editFile(testFile, s => s
|
||
.replace('`hahaha`', '`hahaha-edit`')
|
||
.replace('`popopo`', '`popopo-edit`')
|
||
.replace('`pepepe`', '`pepepe-edit`')
|
||
.replace('`hihihi`', '`hihihi-edit`')
|
||
.replace('`huhuhu`', '`huhuhu-edit`')
|
||
.replace('`hehehe`', '`hehehe-edit`'))
|
||
|
||
result = await runVitest({ root, update: 'none' })
|
||
expect(result.stderr).toMatchInlineSnapshot(`
|
||
"
|
||
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯
|
||
|
||
FAIL basic.test.ts > file
|
||
Error: [custom error] Snapshot \`file 1\` mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": 6,
|
||
+ "length": 11,
|
||
- "reversed": "ahahah",
|
||
+ "reversed": "tide-ahahah",
|
||
}
|
||
|
||
❯ basic.test.ts:66:25
|
||
64|
|
||
65| test('file', () => {
|
||
66| expect(\`hahaha-edit\`).toMatchCustomSnapshot()
|
||
| ^
|
||
67| })
|
||
68|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯
|
||
|
||
FAIL basic.test.ts > properties 1
|
||
Error: [custom error] Snapshot properties mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": 6,
|
||
+ "length": 11,
|
||
+ "reversed": "tide-opopop",
|
||
}
|
||
|
||
❯ basic.test.ts:70:25
|
||
68|
|
||
69| test('properties 1', () => {
|
||
70| expect(\`popopo-edit\`).toMatchCustomSnapshot({ length: 6 })
|
||
| ^
|
||
71| })
|
||
72|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯
|
||
|
||
FAIL basic.test.ts > properties 2
|
||
Error: [custom error] Snapshot properties mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": toSatisfy<[Function lessThan10]>,
|
||
+ "length": 11,
|
||
+ "reversed": "tide-epepep",
|
||
}
|
||
|
||
❯ basic.test.ts:74:25
|
||
72|
|
||
73| test('properties 2', () => {
|
||
74| expect(\`pepepe-edit\`).toMatchCustomSnapshot({ length: expect.toSatis…
|
||
| ^
|
||
75| })
|
||
76|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯
|
||
|
||
FAIL basic.test.ts > raw
|
||
Error: [custom error] Snapshot \`raw 1\` mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": 6,
|
||
+ "length": 11,
|
||
- "reversed": "ihihih",
|
||
+ "reversed": "tide-ihihih",
|
||
}
|
||
|
||
❯ basic.test.ts:78:3
|
||
76|
|
||
77| test('raw', async () => {
|
||
78| await expect(\`hihihi-edit\`).toMatchCustomFileSnapshot('./__snapshots…
|
||
| ^
|
||
79| })
|
||
80|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯
|
||
|
||
FAIL basic.test.ts > inline
|
||
Error: [custom error] Snapshot \`inline 1\` mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": 6,
|
||
+ "length": 11,
|
||
- "reversed": "eheheh",
|
||
+ "reversed": "tide-eheheh",
|
||
}
|
||
|
||
❯ basic.test.ts:82:25
|
||
80|
|
||
81| test('inline', () => {
|
||
82| expect(\`hehehe-edit\`).toMatchCustomInlineSnapshot(\`
|
||
| ^
|
||
83| {
|
||
84| "length": 6,
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯
|
||
|
||
FAIL basic.test.ts > async inline
|
||
Error: [custom error] Snapshot \`async inline 1\` mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": 6,
|
||
+ "length": 11,
|
||
- "reversed": "uhuhuh",
|
||
+ "reversed": "tide-uhuhuh",
|
||
}
|
||
|
||
❯ basic.test.ts:91:3
|
||
89|
|
||
90| test('async inline', async () => {
|
||
91| await expect(\`huhuhu-edit\`).toMatchCustomAsyncInlineSnapshot(\`
|
||
| ^
|
||
92| {
|
||
93| "length": 6,
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯
|
||
|
||
"
|
||
`)
|
||
expect(result.errorTree()).toMatchInlineSnapshot(`
|
||
{
|
||
"basic.test.ts": {
|
||
"async inline": [
|
||
"[custom error] Snapshot \`async inline 1\` mismatched",
|
||
],
|
||
"file": [
|
||
"[custom error] Snapshot \`file 1\` mismatched",
|
||
],
|
||
"inline": [
|
||
"[custom error] Snapshot \`inline 1\` mismatched",
|
||
],
|
||
"properties 1": [
|
||
"[custom error] Snapshot properties mismatched",
|
||
],
|
||
"properties 2": [
|
||
"[custom error] Snapshot properties mismatched",
|
||
],
|
||
"raw": [
|
||
"[custom error] Snapshot \`raw 1\` mismatched",
|
||
],
|
||
},
|
||
}
|
||
`)
|
||
|
||
// run with update
|
||
result = await runVitest({ root, update: 'all' })
|
||
expect(result.stderr).toMatchInlineSnapshot(`
|
||
"
|
||
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯
|
||
|
||
FAIL basic.test.ts > properties 1
|
||
Error: [custom error] Snapshot properties mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": 6,
|
||
+ "length": 11,
|
||
+ "reversed": "tide-opopop",
|
||
}
|
||
|
||
❯ basic.test.ts:70:25
|
||
68|
|
||
69| test('properties 1', () => {
|
||
70| expect(\`popopo-edit\`).toMatchCustomSnapshot({ length: 6 })
|
||
| ^
|
||
71| })
|
||
72|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯
|
||
|
||
FAIL basic.test.ts > properties 2
|
||
Error: [custom error] Snapshot properties mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "length": toSatisfy<[Function lessThan10]>,
|
||
+ "length": 11,
|
||
+ "reversed": "tide-epepep",
|
||
}
|
||
|
||
❯ basic.test.ts:74:25
|
||
72|
|
||
73| test('properties 2', () => {
|
||
74| expect(\`pepepe-edit\`).toMatchCustomSnapshot({ length: expect.toSatis…
|
||
| ^
|
||
75| })
|
||
76|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯
|
||
|
||
"
|
||
`)
|
||
expect(readFileSync(snapshotFile, 'utf-8')).toMatchInlineSnapshot(`
|
||
"// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||
|
||
exports[\`file 1\`] = \`
|
||
{
|
||
"length": 11,
|
||
"reversed": "tide-ahahah",
|
||
}
|
||
\`;
|
||
|
||
exports[\`properties 1 1\`] = \`
|
||
{
|
||
"length": 6,
|
||
"reversed": "opopop",
|
||
}
|
||
\`;
|
||
|
||
exports[\`properties 2 1\`] = \`
|
||
{
|
||
"length": toSatisfy<[Function lessThan10]>,
|
||
"reversed": "epepep",
|
||
}
|
||
\`;
|
||
"
|
||
`)
|
||
expect(readFileSync(rawSnapshotFile, 'utf-8')).toMatchInlineSnapshot(`
|
||
"{
|
||
"length": 11,
|
||
"reversed": "tide-ihihih",
|
||
}"
|
||
`)
|
||
expect(extractInlineSnaphsots(readFileSync(testFile, 'utf-8'))).toMatchInlineSnapshot(`
|
||
"
|
||
expect(\`hehehe-edit\`).toMatchCustomInlineSnapshot(\`
|
||
{
|
||
"length": 11,
|
||
"reversed": "tide-eheheh",
|
||
}
|
||
\`)
|
||
|
||
expect(\`huhuhu-edit\`).toMatchCustomAsyncInlineSnapshot(\`
|
||
{
|
||
"length": 11,
|
||
"reversed": "tide-uhuhuh",
|
||
}
|
||
\`)
|
||
"
|
||
`)
|
||
expect(result.errorTree()).toMatchInlineSnapshot(`
|
||
{
|
||
"basic.test.ts": {
|
||
"async inline": "passed",
|
||
"file": "passed",
|
||
"inline": "passed",
|
||
"properties 1": [
|
||
"[custom error] Snapshot properties mismatched",
|
||
],
|
||
"properties 2": [
|
||
"[custom error] Snapshot properties mismatched",
|
||
],
|
||
"raw": "passed",
|
||
},
|
||
}
|
||
`)
|
||
})
|
||
|
||
test('browser', async () => {
|
||
const result = await runInlineTests({
|
||
'basic.test.ts': `
|
||
import { test, expect, Snapshots } from 'vitest'
|
||
|
||
const {
|
||
toMatchFileSnapshot,
|
||
toMatchInlineSnapshot,
|
||
toMatchSnapshot,
|
||
} = Snapshots
|
||
|
||
expect.extend({
|
||
toMatchTrimmedSnapshot(received: string) {
|
||
return toMatchSnapshot.call(this, received.slice(0, 10))
|
||
},
|
||
toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) {
|
||
return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot)
|
||
},
|
||
async toMatchTrimmedFileSnapshot(received: string, filepath: string) {
|
||
return toMatchFileSnapshot.call(this, received.slice(0, 10), filepath)
|
||
},
|
||
})
|
||
|
||
test('file snapshot', () => {
|
||
expect('extra long string oh my gerd').toMatchTrimmedSnapshot()
|
||
})
|
||
|
||
test('inline snapshot', () => {
|
||
expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot()
|
||
})
|
||
|
||
test('raw file snapshot', async () => {
|
||
await expect('crazy long string oh my gerd').toMatchTrimmedFileSnapshot('./raw.txt')
|
||
})
|
||
`,
|
||
}, {
|
||
update: 'all',
|
||
browser: {
|
||
enabled: true,
|
||
headless: true,
|
||
screenshotFailures: false,
|
||
provider: playwright(),
|
||
instances: [
|
||
{
|
||
browser: 'chromium',
|
||
},
|
||
],
|
||
},
|
||
})
|
||
expect(result.stderr).toMatchInlineSnapshot(`""`)
|
||
expect(result.errorTree()).toMatchInlineSnapshot(`
|
||
{
|
||
"basic.test.ts": {
|
||
"file snapshot": "passed",
|
||
"inline snapshot": "passed",
|
||
"raw file snapshot": "passed",
|
||
},
|
||
}
|
||
`)
|
||
expect(result.fs.readFile('__snapshots__/basic.test.ts.snap')).toMatchInlineSnapshot(`
|
||
"// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||
|
||
exports[\`file snapshot 1\`] = \`"extra long"\`;
|
||
"
|
||
`)
|
||
expect(extractInlineSnaphsots(result.fs.readFile('basic.test.ts'))).toMatchInlineSnapshot(`
|
||
"
|
||
expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot(\`"super long"\`)
|
||
"
|
||
`)
|
||
expect(result.fs.readFile('raw.txt')).toMatchInlineSnapshot(`"crazy long"`)
|
||
})
|
||
|
||
test('outer expect message is prefixed by jest-extend for Snapshots wrappers', async () => {
|
||
const result = await runInlineTests({
|
||
'basic.test.ts': `
|
||
import { test, expect, Snapshots } from 'vitest'
|
||
|
||
const {
|
||
toMatchInlineSnapshot,
|
||
} = Snapshots
|
||
|
||
expect.extend({
|
||
toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) {
|
||
return toMatchInlineSnapshot.call(this, received.slice(0, 5), inlineSnapshot)
|
||
},
|
||
})
|
||
|
||
test('custom snapshot matcher', () => {
|
||
expect('abcdefghij', 'outer message').toMatchTrimmedInlineSnapshot(\`"wrong"\`)
|
||
})
|
||
|
||
test('builtin', () => {
|
||
expect('abcdefghij', 'outer message').toMatchInlineSnapshot(\`"wrong"\`)
|
||
})
|
||
|
||
test('builtin properties mismatch', () => {
|
||
expect({ value: 1 }, 'outer message').toMatchSnapshot({
|
||
value: expect.any(String),
|
||
})
|
||
})
|
||
`,
|
||
}, {
|
||
update: 'none',
|
||
})
|
||
expect(result.stderr).toMatchInlineSnapshot(`
|
||
"
|
||
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯
|
||
|
||
FAIL basic.test.ts > custom snapshot matcher
|
||
Error: outer message: Snapshot \`custom snapshot matcher 1\` mismatched
|
||
|
||
Expected: ""wrong""
|
||
Received: ""abcde""
|
||
|
||
❯ basic.test.ts:15:41
|
||
13|
|
||
14| test('custom snapshot matcher', () => {
|
||
15| expect('abcdefghij', 'outer message').toMatchTrimmedInlineSnapshot(\`…
|
||
| ^
|
||
16| })
|
||
17|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯
|
||
|
||
FAIL basic.test.ts > builtin
|
||
Error: outer message: Snapshot \`builtin 1\` mismatched
|
||
|
||
Expected: ""wrong""
|
||
Received: ""abcdefghij""
|
||
|
||
❯ basic.test.ts:19:41
|
||
17|
|
||
18| test('builtin', () => {
|
||
19| expect('abcdefghij', 'outer message').toMatchInlineSnapshot(\`"wrong"…
|
||
| ^
|
||
20| })
|
||
21|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯
|
||
|
||
FAIL basic.test.ts > builtin properties mismatch
|
||
Error: outer message: Snapshot properties mismatched
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
{
|
||
- "value": Any<String>,
|
||
+ "value": 1,
|
||
}
|
||
|
||
❯ basic.test.ts:23:41
|
||
21|
|
||
22| test('builtin properties mismatch', () => {
|
||
23| expect({ value: 1 }, 'outer message').toMatchSnapshot({
|
||
| ^
|
||
24| value: expect.any(String),
|
||
25| })
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯
|
||
|
||
"
|
||
`)
|
||
expect(result.errorTree()).toMatchInlineSnapshot(`
|
||
{
|
||
"basic.test.ts": {
|
||
"builtin": [
|
||
"outer message: Snapshot \`builtin 1\` mismatched",
|
||
],
|
||
"builtin properties mismatch": [
|
||
"outer message: Snapshot properties mismatched",
|
||
],
|
||
"custom snapshot matcher": [
|
||
"outer message: Snapshot \`custom snapshot matcher 1\` mismatched",
|
||
],
|
||
},
|
||
}
|
||
`)
|
||
})
|