Skip to content

Commit a9c4c30

Browse files
committed
fix: use parsed source text for Prettier formatting
In Prettier's `parse` function, the input source text is preprocessed using `normalizeInputAndOptions`. This normalizes line endings and therefore affects the AST positions if CLRF was replaced with LF, typically in Windows environments. Consequently, formatting the parsed AST has to use the preprocessed source text in order for the AST positions to align, as otherwise the formatted output is likely to be mangled.
1 parent fe7f28c commit a9c4c30

File tree

5 files changed

+113
-8
lines changed

5 files changed

+113
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## main
22

3+
### Fixes
4+
5+
- `[jest-snapshot]` Fix mangled inline snapshot updates when used with Prettier 3 and CRLF line endings
6+
37
## 30.0.5
48

59
### Features
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import * as path from 'path';
9+
import * as fs from 'graceful-fs';
10+
import {cleanup, runYarnInstall, writeFiles} from '../Utils';
11+
import runJest from '../runJest';
12+
13+
const DIR = path.resolve(__dirname, '../to-match-inline-snapshot-crlf');
14+
const TESTS_DIR = path.resolve(DIR, '__tests__');
15+
const JEST_CONFIG_PATH = path.resolve(DIR, 'jest.config.js');
16+
const PRETTIER_RC_PATH = path.resolve(DIR, '.prettierrc');
17+
18+
const readFile = (filename: string) =>
19+
fs.readFileSync(path.join(TESTS_DIR, filename), 'utf8');
20+
21+
beforeAll(() => {
22+
runYarnInstall(DIR);
23+
});
24+
beforeEach(() => {
25+
cleanup(TESTS_DIR);
26+
cleanup(JEST_CONFIG_PATH);
27+
cleanup(PRETTIER_RC_PATH);
28+
});
29+
afterAll(() => {
30+
cleanup(TESTS_DIR);
31+
cleanup(JEST_CONFIG_PATH);
32+
cleanup(PRETTIER_RC_PATH);
33+
});
34+
35+
test('prettier with crlf newlines', () => {
36+
writeFiles(DIR, {
37+
'jest.config.js': `
38+
module.exports = {prettierPath: require.resolve('prettier')};
39+
`,
40+
});
41+
writeFiles(DIR, {
42+
'.prettierrc': '{"endOfLine": "crlf"}',
43+
});
44+
writeFiles(TESTS_DIR, {
45+
'test.ts': `\r
46+
test('snapshots', () => {\r
47+
expect({test: 1}).toMatchInlineSnapshot();\r
48+
\r
49+
expect({test: 2}).toMatchInlineSnapshot();\r
50+
});\r
51+
`,
52+
});
53+
const {stderr, exitCode} = runJest(DIR, ['--ci=false']);
54+
expect(stderr).toContain('Snapshots: 2 written, 2 total');
55+
expect(exitCode).toBe(0);
56+
57+
const fileAfter = readFile('test.ts');
58+
expect(fileAfter).toBe(`test("snapshots", () => {\r
59+
expect({ test: 1 }).toMatchInlineSnapshot(\`\r
60+
{\r
61+
"test": 1,\r
62+
}\r
63+
\`);\r
64+
\r
65+
expect({ test: 2 }).toMatchInlineSnapshot(\`\r
66+
{\r
67+
"test": 2,\r
68+
}\r
69+
\`);\r
70+
});\r
71+
`);
72+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"devDependencies": {
3+
"prettier": "^3.0.0"
4+
}
5+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This file is generated by running "yarn install" inside your project.
2+
# Manual changes might be lost - proceed with caution!
3+
4+
__metadata:
5+
version: 8
6+
cacheKey: 10
7+
8+
"prettier@npm:^3.0.0":
9+
version: 3.5.3
10+
resolution: "prettier@npm:3.5.3"
11+
bin:
12+
prettier: bin/prettier.cjs
13+
checksum: 10/7050c08f674d9e49fbd9a4c008291d0715471f64e94cc5e4b01729affce221dfc6875c8de7e66b728c64abc9352eefb7eaae071b5f79d30081be207b53774b78
14+
languageName: node
15+
linkType: hard
16+
17+
"root-workspace-0b6124@workspace:.":
18+
version: 0.0.0-use.local
19+
resolution: "root-workspace-0b6124@workspace:."
20+
dependencies:
21+
prettier: "npm:^3.0.0"
22+
languageName: unknown
23+
linkType: soft

packages/jest-snapshot/src/worker.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,14 @@ runAsWorker(
4949
parser: inferredParser,
5050
});
5151

52-
// @ts-expect-error private API
53-
const {ast} = await prettier.__debug.parse(sourceFileWithSnapshots, {
54-
...config,
55-
filepath,
56-
originalText: sourceFileWithSnapshots,
57-
parser: inferredParser,
58-
});
52+
const {ast, text: parsedSourceFileWithSnapshots} =
53+
// @ts-expect-error private API
54+
await prettier.__debug.parse(sourceFileWithSnapshots, {
55+
...config,
56+
filepath,
57+
originalText: sourceFileWithSnapshots,
58+
parser: inferredParser,
59+
});
5960
processPrettierAst(ast, config, snapshotMatcherNames, true);
6061
// Snapshots have now been inserted. Run prettier to make sure that the code is
6162
// formatted, except snapshot indentation. Snapshots cannot be formatted until
@@ -66,7 +67,7 @@ runAsWorker(
6667
const formatAST = await prettier.__debug.formatAST(ast, {
6768
...config,
6869
filepath,
69-
originalText: sourceFileWithSnapshots,
70+
originalText: parsedSourceFileWithSnapshots,
7071
parser: inferredParser,
7172
});
7273
return formatAST.formatted;

0 commit comments

Comments
 (0)