Skip to content

Commit

Permalink
fix: Error if prettier@3 is used for inline snapshots (#14367)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Jul 27, 2023
1 parent e7d991c commit 2092927
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@
- `[jest-circus]` Fix snapshot matchers in concurrent tests when nr of tests exceeds `maxConcurrency` ([#14335](https://github.com/jestjs/jest/pull/14335))
- `[@jest/core]` When running global setup and teardown, do not try to change the `message` property of the thrown error object when the `message` property is unwritable ([#14113](https://github.com/jestjs/jest/pull/14113))
- `[jest-snapshot]` Move `@types/prettier` from `dependencies` to `devDependencies` ([#14328](https://github.com/jestjs/jest/pull/14328))
- `[jest-snapshot]` Throw an explicit error if Prettier v3 is used ([#14367](https://github.com/jestjs/jest/pull/14367))
- `[jest-reporters]` Add "skipped" and "todo" symbols to Github Actions Reporter ([#14309](https://github.com/jestjs/jest/pull/14309))

### Chore & Maintenance
Expand Down
35 changes: 35 additions & 0 deletions docs/Configuration.md
Expand Up @@ -1144,6 +1144,41 @@ Default: `'prettier'`

Sets the path to the [`prettier`](https://prettier.io/) node module used to update inline snapshots.

<details>
<summary>Prettier version 3 is not supported!</summary>

You can either pass `prettierPath: null` in your config to disable using prettier if you don't need it, or use v2 of Prettier solely for Jest.

```json title="package.json"
{
"devDependencies": {
"prettier-2": "npm:prettier@^2"
}
}
```

```js tab
/** @type {import('jest').Config} */
const config = {
prettierPath: require.resolve('prettier-2'),
};

module.exports = config;
```

```ts tab
import type {Config} from 'jest';

const config: Config = {
prettierPath: require.resolve('prettier-2'),
};

export default config;
```

We hope to support Prettier v3 seamlessly out of the box in a future version of Jest. See [this](https://github.com/jestjs/jest/issues/14305) tracking issue.
</details>

### `projects` \[array&lt;string | ProjectConfig&gt;]

Default: `undefined`
Expand Down
85 changes: 85 additions & 0 deletions e2e/__tests__/toMatchInlineSnapshotWithPretttier3.test.ts
@@ -0,0 +1,85 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import * as path from 'path';
import {cleanup, runYarnInstall, writeFiles} from '../Utils';
import runJest from '../runJest';

const DIR = path.resolve(
__dirname,
'../to-match-inline-snapshot-with-prettier-3',
);
const TESTS_DIR = path.resolve(DIR, '__tests__');
const JEST_CONFIG_PATH = path.resolve(DIR, 'jest.config.js');

beforeAll(() => {
runYarnInstall(DIR);
});
beforeEach(() => {
cleanup(TESTS_DIR);
cleanup(JEST_CONFIG_PATH);
});
afterAll(() => {
cleanup(TESTS_DIR);
cleanup(JEST_CONFIG_PATH);
});

test('throws correct error', () => {
writeFiles(DIR, {
'jest.config.js': `
module.exports = {prettierPath: require.resolve('prettier')};
`,
});
writeFiles(TESTS_DIR, {
'test.js': `
test('snapshots', () => {
expect(3).toMatchInlineSnapshot();
});
`,
});
const {stderr, exitCode} = runJest(DIR, ['--ci=false']);
expect(stderr).toContain(
'Jest: Inline Snapshots are not supported when using Prettier 3.0.0 or above.',
);
expect(exitCode).toBe(1);
});

test('supports passing `null` as `prettierPath`', () => {
writeFiles(DIR, {
'jest.config.js': `
module.exports = {prettierPath: null};
`,
});
writeFiles(TESTS_DIR, {
'test.js': `
test('snapshots', () => {
expect(3).toMatchInlineSnapshot();
});
`,
});
const {stderr, exitCode} = runJest(DIR, ['--ci=false']);
expect(stderr).toContain('Snapshots: 1 written, 1 total');
expect(exitCode).toBe(0);
});

test('supports passing `prettier-2` as `prettierPath`', () => {
writeFiles(DIR, {
'jest.config.js': `
module.exports = {prettierPath: require.resolve('prettier-2')};
`,
});
writeFiles(TESTS_DIR, {
'test.js': `
test('snapshots', () => {
expect(3).toMatchInlineSnapshot();
});
`,
});
const {stderr, exitCode} = runJest(DIR, ['--ci=false']);
expect(stderr).toContain('Snapshots: 1 written, 1 total');
expect(exitCode).toBe(0);
});
6 changes: 6 additions & 0 deletions e2e/to-match-inline-snapshot-with-prettier-3/package.json
@@ -0,0 +1,6 @@
{
"devDependencies": {
"prettier": "^3.0.0",
"prettier-2": "npm:prettier@^2"
}
}
33 changes: 33 additions & 0 deletions e2e/to-match-inline-snapshot-with-prettier-3/yarn.lock
@@ -0,0 +1,33 @@
# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!

__metadata:
version: 6
cacheKey: 8

"prettier-2@npm:prettier@^2":
version: 2.8.8
resolution: "prettier@npm:2.8.8"
bin:
prettier: bin-prettier.js
checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8
languageName: node
linkType: hard

"prettier@npm:^3.0.0":
version: 3.0.0
resolution: "prettier@npm:3.0.0"
bin:
prettier: bin/prettier.cjs
checksum: 6a832876a1552dc58330d2467874e5a0b46b9ccbfc5d3531eb69d15684743e7f83dc9fbd202db6270446deba9c82b79d24383d09924c462b457136a759425e33
languageName: node
linkType: hard

"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
prettier: ^3.0.0
prettier-2: "npm:prettier@^2"
languageName: unknown
linkType: soft
17 changes: 15 additions & 2 deletions packages/jest-snapshot/src/InlineSnapshots.ts
Expand Up @@ -6,6 +6,7 @@
*/

import * as path from 'path';
import {types} from 'util';
import type {ParseResult, PluginItem} from '@babel/core';
import type {
Expression,
Expand Down Expand Up @@ -60,8 +61,20 @@ export function saveInlineSnapshots(
try {
// @ts-expect-error requireOutside Babel transform
prettier = requireOutside(prettierPath) as Prettier;
} catch {
// Continue even if prettier is not installed.

if (semver.gte(prettier.version, '3.0.0')) {
throw new Error(
'Jest: Inline Snapshots are not supported when using Prettier 3.0.0 or above.\nSee https://jestjs.io/docs/configuration/#prettierpath-string for alternatives.',
);
}
} catch (error) {
if (!types.isNativeError(error)) {
throw error;
}

if ((error as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') {
throw error;
}
}
}

Expand Down

0 comments on commit 2092927

Please sign in to comment.