From f8e6d51c8ebdb931f0fd6e9c68737d175e7f3fb2 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Mon, 12 Jul 2021 12:04:01 +0100 Subject: [PATCH] Lets the user override any of the snapshot formatting options --- .../__snapshots__/snapshot.test.js.snap | 11 +++++++++++ .../__tests__/snapshot.test.js | 11 +++++++++-- e2e/snapshot-formatting-changes/package.json | 12 ++++++++++++ .../package.json | 6 ------ .../jestAdapterInit.ts | 3 ++- packages/jest-config/src/ValidConfig.ts | 7 +++---- packages/jest-config/src/index.ts | 6 ++++-- packages/jest-config/src/normalize.ts | 3 +++ packages/jest-snapshot/src/State.ts | 19 ++++++++++++------- packages/jest-snapshot/src/utils.ts | 9 ++++++--- packages/jest-types/src/Config.ts | 10 +++++++--- packages/pretty-format/src/index.ts | 2 +- packages/test-utils/src/config.ts | 6 ++++-- 13 files changed, 74 insertions(+), 31 deletions(-) create mode 100644 e2e/snapshot-formatting-changes/__tests__/__snapshots__/snapshot.test.js.snap rename e2e/{snapshot-inline-basic-formatting => snapshot-formatting-changes}/__tests__/snapshot.test.js (59%) create mode 100644 e2e/snapshot-formatting-changes/package.json delete mode 100644 e2e/snapshot-inline-basic-formatting/package.json diff --git a/e2e/snapshot-formatting-changes/__tests__/__snapshots__/snapshot.test.js.snap b/e2e/snapshot-formatting-changes/__tests__/__snapshots__/snapshot.test.js.snap new file mode 100644 index 000000000000..204310e54dfe --- /dev/null +++ b/e2e/snapshot-formatting-changes/__tests__/__snapshots__/snapshot.test.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`snapshot serializer prototypes for object and array: no prototypes 1`] = ` +{ + "array": [ + { + "hello": "Danger", + }, + ], +} +`; diff --git a/e2e/snapshot-inline-basic-formatting/__tests__/snapshot.test.js b/e2e/snapshot-formatting-changes/__tests__/snapshot.test.js similarity index 59% rename from e2e/snapshot-inline-basic-formatting/__tests__/snapshot.test.js rename to e2e/snapshot-formatting-changes/__tests__/snapshot.test.js index 59801e13e7ef..194fab1ab137 100644 --- a/e2e/snapshot-inline-basic-formatting/__tests__/snapshot.test.js +++ b/e2e/snapshot-formatting-changes/__tests__/snapshot.test.js @@ -7,8 +7,8 @@ */ 'use strict'; -describe('inline snapshot serializer', () => { - it('does not show prototypes for object and array', () => { +describe('snapshot serializer', () => { + it('does not show prototypes for object and array inline', () => { const object = { array: [{hello: 'Danger'}], }; @@ -22,4 +22,11 @@ describe('inline snapshot serializer', () => { } `); }); + + it('prototypes for object and array', () => { + const object = { + array: [{hello: 'Danger'}], + }; + expect(object).toMatchSnapshot('no prototypes'); + }); }); diff --git a/e2e/snapshot-formatting-changes/package.json b/e2e/snapshot-formatting-changes/package.json new file mode 100644 index 000000000000..f47aed15e05f --- /dev/null +++ b/e2e/snapshot-formatting-changes/package.json @@ -0,0 +1,12 @@ +{ + "jest": { + "testEnvironment": "node", + "inlineSnapshotFormat": { + "printBasicPrototype": false + }, + "snapshotFormat": { + "printBasicPrototype": false, + "indent": 8 + } + } +} diff --git a/e2e/snapshot-inline-basic-formatting/package.json b/e2e/snapshot-inline-basic-formatting/package.json deleted file mode 100644 index 522b300e4599..000000000000 --- a/e2e/snapshot-inline-basic-formatting/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "jest": { - "testEnvironment": "node", - "inlineSnapshotFormatter": "simple" - } -} diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts index 7413dc3bec1b..8e7b18624a30 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -155,8 +155,9 @@ export const initialize = async ({ const snapshotPath = snapshotResolver.resolveSnapshotPath(testPath); const snapshotState = new SnapshotState(snapshotPath, { expand, - preferSimpleForInline: config.inlineSnapshotFormatter === 'simple', + inlineSnapshotFormat: config.inlineSnapshotFormat, prettierPath: config.prettierPath, + snapshotFormat: config.snapshotFormat, updateSnapshot, }); // @ts-expect-error: snapshotState is a jest extension of `expect` diff --git a/packages/jest-config/src/ValidConfig.ts b/packages/jest-config/src/ValidConfig.ts index 1a1db0209681..2e92084aee14 100644 --- a/packages/jest-config/src/ValidConfig.ts +++ b/packages/jest-config/src/ValidConfig.ts @@ -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); @@ -66,10 +67,7 @@ const initialOptions: Config.InitialOptions = { throwOnModuleCollision: false, }, injectGlobals: true, - inlineSnapshotFormatter: multipleValidOptions( - 'exposed prototypes', - 'simple', - ) as any, + inlineSnapshotFormat: PRETTY_FORMAT_DEFAULTS, json: false, lastCommit: false, listTests: false, @@ -113,6 +111,7 @@ const initialOptions: Config.InitialOptions = { skipFilter: false, skipNodeResolution: false, slowTestThreshold: 5, + snapshotFormat: PRETTY_FORMAT_DEFAULTS, snapshotResolver: '/snapshotResolver.js', snapshotSerializers: ['my-serializer-module'], testEnvironment: 'jest-environment-jsdom', diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index 79208ee50a87..071ac60e1ad3 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -127,7 +127,7 @@ const groupOptions = ( forceExit: options.forceExit, globalSetup: options.globalSetup, globalTeardown: options.globalTeardown, - inlineSnapshotFormatter: options.inlineSnapshotFormatter, + inlineSnapshotFormat: options.inlineSnapshotFormat, json: options.json, lastCommit: options.lastCommit, listTests: options.listTests, @@ -150,6 +150,7 @@ const groupOptions = ( runTestsByPath: options.runTestsByPath, silent: options.silent, skipFilter: options.skipFilter, + snapshotFormat: options.snapshotFormat, testFailureExitCode: options.testFailureExitCode, testNamePattern: options.testNamePattern, testPathPattern: options.testPathPattern, @@ -185,7 +186,7 @@ const groupOptions = ( globals: options.globals, haste: options.haste, injectGlobals: options.injectGlobals, - inlineSnapshotFormatter: options.inlineSnapshotFormatter, + inlineSnapshotFormat: options.inlineSnapshotFormat, moduleDirectories: options.moduleDirectories, moduleFileExtensions: options.moduleFileExtensions, moduleLoader: options.moduleLoader, @@ -206,6 +207,7 @@ const groupOptions = ( skipFilter: options.skipFilter, skipNodeResolution: options.skipNodeResolution, slowTestThreshold: options.slowTestThreshold, + snapshotFormat: options.snapshotFormat, snapshotResolver: options.snapshotResolver, snapshotSerializers: options.snapshotSerializers, testEnvironment: options.testEnvironment, diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index ecab7666b5d1..d2fb805a906f 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -27,6 +27,7 @@ import { tryRealpath, } from 'jest-util'; import {ValidationError, validate} from 'jest-validate'; +import {DEFAULT_OPTIONS as PRETTY_FORMAT_DEFAULTS} from 'pretty-format'; import DEFAULT_CONFIG from './Defaults'; import DEPRECATED_CONFIG from './Deprecated'; import {validateReporters} from './ReporterValidationErrors'; @@ -970,6 +971,7 @@ export default async function normalize( case 'extensionsToTreatAsEsm': case 'extraGlobals': case 'globals': + case 'inlineSnapshotFormat': case 'findRelatedTests': case 'forceCoverageMatch': case 'forceExit': @@ -997,6 +999,7 @@ export default async function normalize( case 'skipFilter': case 'skipNodeResolution': case 'slowTestThreshold': + case 'snapshotFormat': case 'testEnvironment': case 'testEnvironmentOptions': case 'testFailureExitCode': diff --git a/packages/jest-snapshot/src/State.ts b/packages/jest-snapshot/src/State.ts index 1072491e828d..dd431aaeea86 100644 --- a/packages/jest-snapshot/src/State.ts +++ b/packages/jest-snapshot/src/State.ts @@ -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 { @@ -26,6 +27,8 @@ export type SnapshotStateOptions = { prettierPath: Config.Path; expand?: boolean; preferSimpleForInline?: boolean; + snapshotFormat: PrettyFormatOptions; + inlineSnapshotFormat: PrettyFormatOptions; }; export type SnapshotMatchOptions = { @@ -62,7 +65,8 @@ export default class SnapshotState { private _inlineSnapshots: Array; private _uncheckedKeys: Set; private _prettierPath: Config.Path; - private _preferSimpleInlineSnapshots: boolean; + private _snapshotFormat: PrettyFormatOptions; + private _inlineSnapshotFormat: PrettyFormatOptions; added: number; expand: boolean; @@ -90,7 +94,9 @@ export default class SnapshotState { this.unmatched = 0; this._updateSnapshot = options.updateSnapshot; this.updated = 0; - this._preferSimpleInlineSnapshots = options.preferSimpleForInline || false; + + this._snapshotFormat = options.snapshotFormat; + this._inlineSnapshotFormat = options.inlineSnapshotFormat; } markSnapshotsAsCheckedForTest(testName: string): void { @@ -204,13 +210,12 @@ export default class SnapshotState { this._uncheckedKeys.delete(key); } - // There is an option to allow for not showing 'Object' and 'Array' on - // snapshots, which we'd like to allow for opting into with inline snapshots. - const hasOptedInToSimpleInline = - isInline && this._preferSimpleInlineSnapshots; + const customFormat = isInline + ? this._inlineSnapshotFormat + : this._snapshotFormat; const receivedSerialized = addExtraLineBreaks( - serialize(received, undefined, hasOptedInToSimpleInline), + serialize(received, undefined, customFormat), ); const expected = isInline ? inlineSnapshot : this._snapshotData[key]; const pass = expected === receivedSerialized; diff --git a/packages/jest-snapshot/src/utils.ts b/packages/jest-snapshot/src/utils.ts index 7eb6c45b3383..0c3b2ff132f8 100644 --- a/packages/jest-snapshot/src/utils.ts +++ b/packages/jest-snapshot/src/utils.ts @@ -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'; @@ -155,15 +158,15 @@ const printFunctionName = false; export const serialize = ( val: unknown, indent = 2, - printBasicPrototype: boolean = true, + formatOverrides: PrettyFormatOptions = {}, ): string => normalizeNewlines( prettyFormat(val, { escapeRegex, indent, plugins: getSerializers(), - printBasicPrototype, printFunctionName, + ...formatOverrides, }), ); diff --git a/packages/jest-types/src/Config.ts b/packages/jest-types/src/Config.ts index e0df4c9fbeb9..fafa474efcf8 100644 --- a/packages/jest-types/src/Config.ts +++ b/packages/jest-types/src/Config.ts @@ -8,6 +8,7 @@ import type {ForegroundColor} from 'chalk'; import type {ReportOptions} from 'istanbul-reports'; import type {Arguments} from 'yargs'; +import type {OptionsReceived as PrettyFormatOptions} from 'pretty-format'; type CoverageProvider = 'babel' | 'v8'; @@ -171,7 +172,7 @@ export type InitialOptions = Partial<{ globalTeardown: string | null | undefined; haste: HasteConfig; injectGlobals: boolean; - inlineSnapshotFormatter: 'exposed prototypes' | 'simple'; + inlineSnapshotFormat: PrettyFormatOptions; reporters: Array; logHeapUsage: boolean; lastCommit: boolean; @@ -217,6 +218,7 @@ export type InitialOptions = Partial<{ slowTestThreshold: number; snapshotResolver: Path; snapshotSerializers: Array; + snapshotFormat: PrettyFormatOptions; errorOnDeprecated: boolean; testEnvironment: string; testEnvironmentOptions: Record; @@ -293,7 +295,7 @@ export type GlobalConfig = { json: boolean; globalSetup?: string; globalTeardown?: string; - inlineSnapshotFormatter: 'exposed prototypes' | 'simple'; + inlineSnapshotFormat: PrettyFormatOptions; lastCommit: boolean; logHeapUsage: boolean; listTests: boolean; @@ -315,6 +317,7 @@ export type GlobalConfig = { rootDir: Path; silent?: boolean; skipFilter: boolean; + snapshotFormat: PrettyFormatOptions; errorOnDeprecated: boolean; testFailureExitCode: number; testNamePattern?: string; @@ -354,7 +357,7 @@ export type ProjectConfig = { globalTeardown?: string; globals: ConfigGlobals; haste: HasteConfig; - inlineSnapshotFormatter: 'exposed prototypes' | 'simple'; + inlineSnapshotFormat: PrettyFormatOptions; injectGlobals: boolean; moduleDirectories: Array; moduleFileExtensions: Array; @@ -378,6 +381,7 @@ export type ProjectConfig = { slowTestThreshold: number; snapshotResolver?: Path; snapshotSerializers: Array; + snapshotFormat: PrettyFormatOptions; testEnvironment: string; testEnvironmentOptions: Record; testMatch: Array; diff --git a/packages/pretty-format/src/index.ts b/packages/pretty-format/src/index.ts index e2f5f0326270..b497aa324df7 100644 --- a/packages/pretty-format/src/index.ts +++ b/packages/pretty-format/src/index.ts @@ -394,7 +394,7 @@ const DEFAULT_THEME_KEYS = Object.keys(DEFAULT_THEME) as Array< keyof typeof DEFAULT_THEME >; -const DEFAULT_OPTIONS: Options = { +export const DEFAULT_OPTIONS: Options = { callToJSON: true, escapeRegex: false, escapeString: true, diff --git a/packages/test-utils/src/config.ts b/packages/test-utils/src/config.ts index d4de7a34af8c..2182428494be 100644 --- a/packages/test-utils/src/config.ts +++ b/packages/test-utils/src/config.ts @@ -27,7 +27,7 @@ const DEFAULT_GLOBAL_CONFIG: Config.GlobalConfig = { forceExit: false, globalSetup: undefined, globalTeardown: undefined, - inlineSnapshotFormatter: 'exposed prototypes', + inlineSnapshotFormat: {}, json: false, lastCommit: false, listTests: false, @@ -50,6 +50,7 @@ const DEFAULT_GLOBAL_CONFIG: Config.GlobalConfig = { runTestsByPath: false, silent: false, skipFilter: false, + snapshotFormat: {}, testFailureExitCode: 1, testNamePattern: '', testPathPattern: '', @@ -85,7 +86,7 @@ const DEFAULT_PROJECT_CONFIG: Config.ProjectConfig = { globals: {}, haste: {}, injectGlobals: true, - inlineSnapshotFormatter: 'exposed prototypes', + inlineSnapshotFormat: {}, moduleDirectories: [], moduleFileExtensions: ['js'], moduleLoader: '/test_module_loader_path', @@ -106,6 +107,7 @@ const DEFAULT_PROJECT_CONFIG: Config.ProjectConfig = { skipFilter: false, skipNodeResolution: false, slowTestThreshold: 5, + snapshotFormat: {}, snapshotResolver: undefined, snapshotSerializers: [], testEnvironment: 'node',