Skip to content

Commit 6a90a2c

Browse files
eps1lonSimenB
andauthoredAug 19, 2022
fix: Allow updating inline snapshots when test includes JSX (#12760)
Co-authored-by: Simen Bekkhus <sbekkhus91@gmail.com>
1 parent 983274a commit 6a90a2c

File tree

5 files changed

+87
-8
lines changed

5 files changed

+87
-8
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- `[@jest/expect-utils]` Fix deep equality of ImmutableJS Record ([#13055](https://github.com/facebook/jest/pull/13055))
2020
- `[jest-haste-map]` Increase the maximum possible file size that jest-haste-map can handle ([#13094](https://github.com/facebook/jest/pull/13094))
2121
- `[jest-snapshot]` Make `prettierPath` optional in `SnapshotState` ([#13149](https://github.com/facebook/jest/pull/13149))
22+
- `[jest-snapshot]` Fix parsing error from inline snapshot files with `JSX` ([#12760](https://github.com/facebook/jest/pull/12760))
2223
- `[jest-worker]` When a process runs out of memory worker exits correctly and doesn't spin indefinitely ([#13054](https://github.com/facebook/jest/pull/13054))
2324

2425
### Chore & Maintenance

‎e2e/__tests__/toMatchInlineSnapshotWithJSX.test.ts

+49
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,52 @@ it('successfully runs the tests with external babel config', () => {
109109
expect(updateSnapshotRun.exitCode).toBe(0);
110110
expect(updateSnapshotRun.stderr).toContain('1 snapshot updated.');
111111
});
112+
113+
it('successfully runs the tests with inline babel config', () => {
114+
writeFiles(DIR, {
115+
'package.json': JSON.stringify({
116+
...pkg,
117+
jest: {
118+
testEnvironment: 'jsdom',
119+
transform: {
120+
'^.+\\.(js|jsx)$': ['babel-jest', babelConfig],
121+
},
122+
},
123+
}),
124+
});
125+
126+
const normalRun = runWithJson(DIR, []);
127+
expect(normalRun.exitCode).toBe(1);
128+
expect(normalRun.stderr).toContain('1 snapshot failed from 1 test suite.');
129+
expect(normalRun.json.testResults[0].message).toMatchInlineSnapshot(`
130+
" ● <div>x</div>
131+
132+
expect(received).toMatchInlineSnapshot(snapshot)
133+
134+
Snapshot name: \`<div>x</div> 1\`
135+
136+
- Snapshot - 1
137+
+ Received + 1
138+
139+
<div>
140+
- y
141+
+ x
142+
</div>
143+
144+
3 |
145+
4 | test('<div>x</div>', () => {
146+
> 5 | expect(renderer.create(<div>x</div>).toJSON()).toMatchInlineSnapshot(\`
147+
| ^
148+
6 | <div>
149+
7 | y
150+
8 | </div>
151+
152+
at Object.toMatchInlineSnapshot (__tests__/MismatchingSnapshot.test.js:5:50)
153+
"
154+
`);
155+
156+
const updateSnapshotRun = runJest(DIR, ['--updateSnapshot']);
157+
158+
expect(updateSnapshotRun.exitCode).toBe(0);
159+
expect(updateSnapshotRun.stderr).toContain('1 snapshot updated.');
160+
});

‎packages/jest-snapshot/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"dependencies": {
2020
"@babel/core": "^7.11.6",
2121
"@babel/generator": "^7.7.2",
22+
"@babel/plugin-syntax-jsx": "^7.7.2",
2223
"@babel/plugin-syntax-typescript": "^7.7.2",
2324
"@babel/traverse": "^7.7.2",
2425
"@babel/types": "^7.3.3",

‎packages/jest-snapshot/src/InlineSnapshots.ts

+34-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
import * as path from 'path';
9-
import type {PluginItem} from '@babel/core';
9+
import type {ParseResult, PluginItem} from '@babel/core';
1010
import {Expression, File, Program, isAwaitExpression} from '@babel/types';
1111
import * as fs from 'graceful-fs';
1212
import type {
@@ -95,12 +95,39 @@ const saveSnapshotsForFile = (
9595
// by one to formatting parser.
9696
const snapshotMatcherNames: Array<string> = [];
9797

98-
const ast = parseSync(sourceFile, {
99-
filename: sourceFilePath,
100-
plugins,
101-
presets,
102-
root: rootDir,
103-
});
98+
let ast: ParseResult | null = null;
99+
100+
try {
101+
ast = parseSync(sourceFile, {
102+
filename: sourceFilePath,
103+
plugins,
104+
presets,
105+
root: rootDir,
106+
});
107+
} catch (error: any) {
108+
// attempt to recover from missing jsx plugin
109+
if (error.message.includes('@babel/plugin-syntax-jsx')) {
110+
try {
111+
const jsxSyntaxPlugin: PluginItem = [
112+
require.resolve('@babel/plugin-syntax-jsx'),
113+
{},
114+
// unique name to make sure Babel does not complain about a possible duplicate plugin.
115+
'JSX syntax plugin added by Jest snapshot',
116+
];
117+
ast = parseSync(sourceFile, {
118+
filename: sourceFilePath,
119+
plugins: [...plugins, jsxSyntaxPlugin],
120+
presets,
121+
root: rootDir,
122+
});
123+
} catch {
124+
throw error;
125+
}
126+
} else {
127+
throw error;
128+
}
129+
}
130+
104131
if (!ast) {
105132
throw new Error(`jest-snapshot: Failed to parse ${sourceFilePath}`);
106133
}

‎yarn.lock

+2-1
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ __metadata:
10301030
languageName: node
10311031
linkType: hard
10321032

1033-
"@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.18.6":
1033+
"@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.18.6, @babel/plugin-syntax-jsx@npm:^7.7.2":
10341034
version: 7.18.6
10351035
resolution: "@babel/plugin-syntax-jsx@npm:7.18.6"
10361036
dependencies:
@@ -12847,6 +12847,7 @@ __metadata:
1284712847
dependencies:
1284812848
"@babel/core": ^7.11.6
1284912849
"@babel/generator": ^7.7.2
12850+
"@babel/plugin-syntax-jsx": ^7.7.2
1285012851
"@babel/plugin-syntax-typescript": ^7.7.2
1285112852
"@babel/preset-flow": ^7.7.2
1285212853
"@babel/preset-react": ^7.12.1

0 commit comments

Comments
 (0)
Please sign in to comment.