Skip to content

Commit

Permalink
fix(snapshots): update inline snapshot correctly (#3887)
Browse files Browse the repository at this point in the history
  • Loading branch information
fenghan34 authored Aug 15, 2023
1 parent e94044d commit 7b740a2
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 6 deletions.
38 changes: 32 additions & 6 deletions packages/snapshot/src/port/inlineSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,47 @@ export async function saveInlineSnapshots(
const startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\S\s]*\*\/\s*|\/\/.*\s+)*\s*({)/m

function replaceObjectSnap(code: string, s: MagicString, index: number, newSnap: string) {
code = code.slice(index)
const startMatch = startObjectRegex.exec(code)
let _code = code.slice(index)
const startMatch = startObjectRegex.exec(_code)
if (!startMatch)
return false

code = code.slice(startMatch.index)
const charIndex = getCallLastIndex(code)
if (charIndex === null)
_code = _code.slice(startMatch.index)

let callEnd = getCallLastIndex(_code)
if (callEnd === null)
return false
callEnd += index + startMatch.index

const shapeStart = index + startMatch.index + startMatch[0].length
const shapeEnd = getObjectShapeEndIndex(code, shapeStart)
const snap = `, ${prepareSnapString(newSnap, code, index)}`

s.appendLeft(index + startMatch.index + charIndex, `, ${prepareSnapString(newSnap, code, index)}`)
if (shapeEnd === callEnd) {
// toMatchInlineSnapshot({ foo: expect.any(String) })
s.appendLeft(callEnd, snap)
}
else {
// toMatchInlineSnapshot({ foo: expect.any(String) }, ``)
s.overwrite(shapeEnd, callEnd, snap)
}

return true
}

function getObjectShapeEndIndex(code: string, index: number) {
let startBraces = 1
let endBraces = 0
while (startBraces !== endBraces && index < code.length) {
const s = code[index++]
if (s === '{')
startBraces++
else if (s === '}')
endBraces++
}
return index
}

function prepareSnapString(snap: string, source: string, index: number) {
const lineNumber = offsetToLineNumber(source, index)
const line = source.split(lineSplitRE)[lineNumber - 1]
Expand Down
40 changes: 40 additions & 0 deletions test/core/test/inline-snap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,44 @@ ${indent}}\`)
"
`)
})

describe('replaceObjectSnap()', () => {
it('without snapshot', async () => {
const code = 'expect({ foo: \'bar\' }).toMatchInlineSnapshot({ foo: expect.any(String) })'

const s = new MagicString(code)
replaceInlineSnap(code, s, 23, `
{
"foo": Any<String>,
}
`)

expect(s.toString()).toMatchInlineSnapshot(`
"expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
{
\\"foo\\": Any<String>,
}
\`)"
`)
})

it('with snapshot', async () => {
const code = 'expect({ foo: \'bar\' }).toMatchInlineSnapshot({ foo: expect.any(String) }, `{ }`)'

const s = new MagicString(code)
replaceInlineSnap(code, s, 23, `
{
"foo": Any<String>,
}
`)

expect(s.toString()).toMatchInlineSnapshot(`
"expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
{
\\"foo\\": Any<String>,
}
\`)"
`)
})
})
})
18 changes: 18 additions & 0 deletions test/snapshots/test-update/snapshots-inline-js.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,21 @@ describe('snapshots are generated in correct order', async () => {
`)
})
})

describe('snapshots with properties', () => {
test('without snapshot', () => {
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, `
Object {
"foo": Any<String>,
}
`)
})

test('with snapshot', () => {
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, `
Object {
"foo": Any<String>,
}
`)
})
})
18 changes: 18 additions & 0 deletions test/snapshots/test/__snapshots__/shapshots.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ describe('snapshots are generated in correct order', async () => {
\`)
})
})
describe('snapshots with properties', () => {
test('without snapshot', () => {
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
Object {
\\"foo\\": Any<String>,
}
\`)
})
test('with snapshot', () => {
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, \`
Object {
\\"foo\\": Any<String>,
}
\`)
})
})
"
`;
Expand Down
10 changes: 10 additions & 0 deletions test/snapshots/tools/inline-test-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@ describe('snapshots are generated in correct order', async () => {
expect({ foo: ['zed'] }).toMatchInlineSnapshot()
})
})

describe('snapshots with properties', () => {
test('without snapshot', () => {
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) })
})

test('with snapshot', () => {
expect({ foo: 'bar' }).toMatchInlineSnapshot({ foo: expect.any(String) }, '')
})
})

0 comments on commit 7b740a2

Please sign in to comment.