Skip to content

Commit 7b740a2

Browse files
authored
fix(snapshots): update inline snapshot correctly (#3887)
1 parent e94044d commit 7b740a2

File tree

5 files changed

+118
-6
lines changed

5 files changed

+118
-6
lines changed

packages/snapshot/src/port/inlineSnapshot.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,47 @@ export async function saveInlineSnapshots(
3434
const startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*({)/m
3535

3636
function replaceObjectSnap(code: string, s: MagicString, index: number, newSnap: string) {
37-
code = code.slice(index)
38-
const startMatch = startObjectRegex.exec(code)
37+
let _code = code.slice(index)
38+
const startMatch = startObjectRegex.exec(_code)
3939
if (!startMatch)
4040
return false
4141

42-
code = code.slice(startMatch.index)
43-
const charIndex = getCallLastIndex(code)
44-
if (charIndex === null)
42+
_code = _code.slice(startMatch.index)
43+
44+
let callEnd = getCallLastIndex(_code)
45+
if (callEnd === null)
4546
return false
47+
callEnd += index + startMatch.index
48+
49+
const shapeStart = index + startMatch.index + startMatch[0].length
50+
const shapeEnd = getObjectShapeEndIndex(code, shapeStart)
51+
const snap = `, ${prepareSnapString(newSnap, code, index)}`
4652

47-
s.appendLeft(index + startMatch.index + charIndex, `, ${prepareSnapString(newSnap, code, index)}`)
53+
if (shapeEnd === callEnd) {
54+
// toMatchInlineSnapshot({ foo: expect.any(String) })
55+
s.appendLeft(callEnd, snap)
56+
}
57+
else {
58+
// toMatchInlineSnapshot({ foo: expect.any(String) }, ``)
59+
s.overwrite(shapeEnd, callEnd, snap)
60+
}
4861

4962
return true
5063
}
5164

65+
function getObjectShapeEndIndex(code: string, index: number) {
66+
let startBraces = 1
67+
let endBraces = 0
68+
while (startBraces !== endBraces && index < code.length) {
69+
const s = code[index++]
70+
if (s === '{')
71+
startBraces++
72+
else if (s === '}')
73+
endBraces++
74+
}
75+
return index
76+
}
77+
5278
function prepareSnapString(snap: string, source: string, index: number) {
5379
const lineNumber = offsetToLineNumber(source, index)
5480
const line = source.split(lineSplitRE)[lineNumber - 1]

test/core/test/inline-snap.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,44 @@ ${indent}}\`)
146146
"
147147
`)
148148
})
149+
150+
describe('replaceObjectSnap()', () => {
151+
it('without snapshot', async () => {
152+
const code = 'expect({ foo: \'bar\' }).toMatchInlineSnapshot({ foo: expect.any(String) })'
153+
154+
const s = new MagicString(code)
155+
replaceInlineSnap(code, s, 23, `
156+
{
157+
"foo": Any<String>,
158+
}
159+
`)
160+
161+
expect(s.toString()).toMatchInlineSnapshot(`
162+
"expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
163+
{
164+
\\"foo\\": Any<String>,
165+
}
166+
\`)"
167+
`)
168+
})
169+
170+
it('with snapshot', async () => {
171+
const code = 'expect({ foo: \'bar\' }).toMatchInlineSnapshot({ foo: expect.any(String) }, `{ }`)'
172+
173+
const s = new MagicString(code)
174+
replaceInlineSnap(code, s, 23, `
175+
{
176+
"foo": Any<String>,
177+
}
178+
`)
179+
180+
expect(s.toString()).toMatchInlineSnapshot(`
181+
"expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
182+
{
183+
\\"foo\\": Any<String>,
184+
}
185+
\`)"
186+
`)
187+
})
188+
})
149189
})

test/snapshots/test-update/snapshots-inline-js.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,21 @@ describe('snapshots are generated in correct order', async () => {
2323
`)
2424
})
2525
})
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({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, `
38+
Object {
39+
"foo": Any<String>,
40+
}
41+
`)
42+
})
43+
})

test/snapshots/test/__snapshots__/shapshots.test.ts.snap

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@ describe('snapshots are generated in correct order', async () => {
2626
\`)
2727
})
2828
})
29+
30+
describe('snapshots with properties', () => {
31+
test('without snapshot', () => {
32+
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
33+
Object {
34+
\\"foo\\": Any<String>,
35+
}
36+
\`)
37+
})
38+
39+
test('with snapshot', () => {
40+
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
41+
Object {
42+
\\"foo\\": Any<String>,
43+
}
44+
\`)
45+
})
46+
})
2947
"
3048
`;
3149

test/snapshots/tools/inline-test-template.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,13 @@ describe('snapshots are generated in correct order', async () => {
1111
expect({ foo: ['zed'] }).toMatchInlineSnapshot()
1212
})
1313
})
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({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, '')
22+
})
23+
})

0 commit comments

Comments
 (0)