Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds options for configuring the snapshot and inline snapshot serializers #11654

Merged
merged 16 commits into from Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

### Features

- `[jest-cli]` Adds a new config options `snapshotFormat` which offers a way to override any of the formatting settings which come with [pretty-format](https://www.npmjs.com/package/pretty-format#usage-with-options). ([#11654](https://github.com/facebook/jest/pull/11654))

### Fixes

- `[jest-environment-node]` Add `Event` and `EventTarget` to node global environment. ([#11705](https://github.com/facebook/jest/issues/11705))
Expand Down
35 changes: 35 additions & 0 deletions docs/Configuration.md
Expand Up @@ -945,6 +945,41 @@ Default: `5`

The number of seconds after which a test is considered as slow and reported as such in the results.

### `snapshotFormat` \[object]

Default: `undefined`

Allows overriding specific snapshot formatting options documented in the [pretty-format readme](https://www.npmjs.com/package/pretty-format#usage-with-options). For example, this config would have the snapshot formatter not print a prefix for "Object" and "Array":

```json
{
"jest": {
"snapshotFormat": {
"printBasicPrototype": false
}
}
}
```

```ts
import {expect, test} from '@jest/globals';

test('does not show prototypes for object and array inline', () => {
const object = {
array: [{hello: 'Danger'}],
};
expect(object).toMatchInlineSnapshot(`
{
"array": [
{
"hello": "Danger",
},
],
}
`);
});
```

### `snapshotResolver` \[string]

Default: `undefined`
Expand Down
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`snapshot serializer uses 8 chars for indent, and shows no prototypes for object and array in a snapshot: no prototypes 1`] = `
{
"array": [
{
"hello": "Danger",
},
],
}
`;
32 changes: 32 additions & 0 deletions e2e/snapshot-formatting-changes/__tests__/snapshot.test.js
@@ -0,0 +1,32 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use strict';

describe('snapshot serializer', () => {
it('does not show prototypes for object and array inline', () => {
const object = {
array: [{hello: 'Danger'}],
};
expect(object).toMatchInlineSnapshot(`
{
"array": [
{
"hello": "Danger",
},
],
}
`);
});

it('uses 8 chars for indent, and shows no prototypes for object and array in a snapshot', () => {
const object = {
array: [{hello: 'Danger'}],
};
expect(object).toMatchSnapshot('no prototypes');
});
});
9 changes: 9 additions & 0 deletions e2e/snapshot-formatting-changes/package.json
@@ -0,0 +1,9 @@
{
"jest": {
"testEnvironment": "node",
"snapshotFormat": {
"printBasicPrototype": false,
"indent": 8
}
}
}
Expand Up @@ -156,6 +156,7 @@ export const initialize = async ({
const snapshotState = new SnapshotState(snapshotPath, {
expand,
prettierPath: config.prettierPath,
snapshotFormat: config.snapshotFormat,
updateSnapshot,
});
// @ts-expect-error: snapshotState is a jest extension of `expect`
Expand Down
2 changes: 2 additions & 0 deletions packages/jest-config/src/ValidConfig.ts
Expand Up @@ -8,6 +8,7 @@
import type {Config} from '@jest/types';
import {replacePathSepForRegex} from 'jest-regex-util';
import {multipleValidOptions} from 'jest-validate';
import {DEFAULT_OPTIONS as PRETTY_FORMAT_DEFAULTS} from 'pretty-format';
import {NODE_MODULES} from './constants';

const NODE_MODULES_REGEXP = replacePathSepForRegex(NODE_MODULES);
Expand Down Expand Up @@ -109,6 +110,7 @@ const initialOptions: Config.InitialOptions = {
skipFilter: false,
skipNodeResolution: false,
slowTestThreshold: 5,
snapshotFormat: PRETTY_FORMAT_DEFAULTS,
snapshotResolver: '<rootDir>/snapshotResolver.js',
snapshotSerializers: ['my-serializer-module'],
testEnvironment: 'jest-environment-jsdom',
Expand Down
2 changes: 2 additions & 0 deletions packages/jest-config/src/index.ts
Expand Up @@ -149,6 +149,7 @@ const groupOptions = (
runTestsByPath: options.runTestsByPath,
silent: options.silent,
skipFilter: options.skipFilter,
snapshotFormat: options.snapshotFormat,
testFailureExitCode: options.testFailureExitCode,
testNamePattern: options.testNamePattern,
testPathPattern: options.testPathPattern,
Expand Down Expand Up @@ -204,6 +205,7 @@ const groupOptions = (
skipFilter: options.skipFilter,
skipNodeResolution: options.skipNodeResolution,
slowTestThreshold: options.slowTestThreshold,
snapshotFormat: options.snapshotFormat,
snapshotResolver: options.snapshotResolver,
snapshotSerializers: options.snapshotSerializers,
testEnvironment: options.testEnvironment,
Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/normalize.ts
Expand Up @@ -997,6 +997,7 @@ export default async function normalize(
case 'skipFilter':
case 'skipNodeResolution':
case 'slowTestThreshold':
case 'snapshotFormat':
case 'testEnvironment':
case 'testEnvironmentOptions':
case 'testFailureExitCode':
Expand Down
Expand Up @@ -41,6 +41,7 @@ exports[`prints the config object 1`] = `
"skipFilter": false,
"skipNodeResolution": false,
"slowTestThreshold": 5,
"snapshotFormat": {},
"snapshotSerializers": [],
"testEnvironment": "node",
"testEnvironmentOptions": {},
Expand Down Expand Up @@ -94,6 +95,7 @@ exports[`prints the config object 1`] = `
"runTestsByPath": false,
"silent": false,
"skipFilter": false,
"snapshotFormat": {},
"testFailureExitCode": 1,
"testNamePattern": "",
"testPathPattern": "",
Expand Down
3 changes: 2 additions & 1 deletion packages/jest-jasmine2/src/setup_jest_globals.ts
Expand Up @@ -106,12 +106,13 @@ export default async ({

patchJasmine();
const {expand, updateSnapshot} = globalConfig;
const {prettierPath} = config;
const {prettierPath, snapshotFormat} = config;
const snapshotResolver = await buildSnapshotResolver(config, localRequire);
const snapshotPath = snapshotResolver.resolveSnapshotPath(testPath);
const snapshotState = new SnapshotState(snapshotPath, {
expand,
prettierPath,
snapshotFormat,
updateSnapshot,
});
// @ts-expect-error: snapshotState is a jest extension of `expect`
Expand Down
8 changes: 7 additions & 1 deletion packages/jest-snapshot/src/State.ts
Expand Up @@ -8,6 +8,7 @@
import * as fs from 'graceful-fs';
import type {Config} from '@jest/types';
import {getStackTraceLines, getTopFrame} from 'jest-message-util';
import type {OptionsReceived as PrettyFormatOptions} from 'pretty-format';
import {InlineSnapshot, saveInlineSnapshots} from './InlineSnapshots';
import type {SnapshotData} from './types';
import {
Expand All @@ -25,6 +26,7 @@ export type SnapshotStateOptions = {
updateSnapshot: Config.SnapshotUpdateState;
prettierPath: Config.Path;
expand?: boolean;
snapshotFormat: PrettyFormatOptions;
};

export type SnapshotMatchOptions = {
Expand Down Expand Up @@ -61,6 +63,7 @@ export default class SnapshotState {
private _inlineSnapshots: Array<InlineSnapshot>;
private _uncheckedKeys: Set<string>;
private _prettierPath: Config.Path;
private _snapshotFormat: PrettyFormatOptions;

added: number;
expand: boolean;
Expand Down Expand Up @@ -88,6 +91,7 @@ export default class SnapshotState {
this.unmatched = 0;
this._updateSnapshot = options.updateSnapshot;
this.updated = 0;
this._snapshotFormat = options.snapshotFormat;
}

markSnapshotsAsCheckedForTest(testName: string): void {
Expand Down Expand Up @@ -201,7 +205,9 @@ export default class SnapshotState {
this._uncheckedKeys.delete(key);
}

const receivedSerialized = addExtraLineBreaks(serialize(received));
const receivedSerialized = addExtraLineBreaks(
serialize(received, undefined, this._snapshotFormat),
);
const expected = isInline ? inlineSnapshot : this._snapshotData[key];
const pass = expected === receivedSerialized;
const hasSnapshot = expected !== undefined;
Expand Down
12 changes: 10 additions & 2 deletions packages/jest-snapshot/src/utils.ts
Expand Up @@ -10,7 +10,10 @@ import chalk = require('chalk');
import * as fs from 'graceful-fs';
import naturalCompare = require('natural-compare');
import type {Config} from '@jest/types';
import {format as prettyFormat} from 'pretty-format';
import {
OptionsReceived as PrettyFormatOptions,
format as prettyFormat,
} from 'pretty-format';
import {getSerializers} from './plugins';
import type {SnapshotData} from './types';

Expand Down Expand Up @@ -152,13 +155,18 @@ export const removeLinesBeforeExternalMatcherTrap = (stack: string): string => {
const escapeRegex = true;
const printFunctionName = false;

export const serialize = (val: unknown, indent = 2): string =>
export const serialize = (
val: unknown,
indent = 2,
formatOverrides: PrettyFormatOptions = {},
): string =>
normalizeNewlines(
prettyFormat(val, {
escapeRegex,
indent,
plugins: getSerializers(),
printFunctionName,
...formatOverrides,
}),
);

Expand Down