From 896d89c401c4bc9a001d6f284568ec6771763688 Mon Sep 17 00:00:00 2001 From: Tetsuro Aoki Date: Fri, 30 Apr 2021 01:24:59 +0900 Subject: [PATCH 1/2] fix(jest-each): interpolate `%%` correctly --- CHANGELOG.md | 1 + packages/jest-each/src/__tests__/array.test.ts | 9 ++++++--- packages/jest-each/src/table/array.ts | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba07e937f8fc..4697a0a1282e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ - `[jest-core]` Use `WeakRef` to hold timers when detecting open handles ([#11277](https://github.com/facebook/jest/pull/11277)) - `[jest-each]` [**BREAKING**] Ignore excess words in headings ([#8766](https://github.com/facebook/jest/pull/8766)) - `[jest-each]` Support array index with template strings ([#10763](https://github.com/facebook/jest/pull/10763)) +- `[jest-each]` Interpolate `%%` correctly ([#11364](https://github.com/facebook/jest/pull/11364)) - `[jest-environment]` [**BREAKING**] Drop support for `runScript` for test environments ([#11155](https://github.com/facebook/jest/pull/11155)) - `[jest-environment-jsdom]` Use inner realm’s `ArrayBuffer` constructor ([#10885](https://github.com/facebook/jest/pull/10885)) - `[jest-environment-jsdom]` [**BREAKING**] Remove Node globals `setImmediate` and `clearImmediate` [#11222](https://github.com/facebook/jest/pull/11222) diff --git a/packages/jest-each/src/__tests__/array.test.ts b/packages/jest-each/src/__tests__/array.test.ts index e95b8e4e701d..471dd172c88f 100644 --- a/packages/jest-each/src/__tests__/array.test.ts +++ b/packages/jest-each/src/__tests__/array.test.ts @@ -143,19 +143,22 @@ describe('jest-each', () => { ], ]); const testFunction = get(eachObject, keyPath); - testFunction('expected string: %s %d %s %s %d %j %s %j %d %d %#', noop); + testFunction( + 'expected string: %% %%s %s %d %s %s %d %j %s %j %d %d %#', + noop, + ); const globalMock = get(globalTestMocks, keyPath); expect(globalMock).toHaveBeenCalledTimes(2); expect(globalMock).toHaveBeenCalledWith( - `expected string: hello 1 null undefined 1.2 ${JSON.stringify({ + `expected string: % %s hello 1 null undefined 1.2 ${JSON.stringify({ foo: 'bar', })} () => {} [] Infinity NaN 0`, expectFunction, undefined, ); expect(globalMock).toHaveBeenCalledWith( - `expected string: world 1 null undefined 1.2 ${JSON.stringify({ + `expected string: % %s world 1 null undefined 1.2 ${JSON.stringify({ baz: 'qux', })} () => {} [] Infinity NaN 1`, expectFunction, diff --git a/packages/jest-each/src/table/array.ts b/packages/jest-each/src/table/array.ts index d8b3daf9661c..4fc272982976 100644 --- a/packages/jest-each/src/table/array.ts +++ b/packages/jest-each/src/table/array.ts @@ -11,10 +11,11 @@ import type {Global} from '@jest/types'; import {format as pretty} from 'pretty-format'; import type {EachTests} from '../bind'; -const SUPPORTED_PLACEHOLDERS = /%[sdifjoOp%]/g; +const SUPPORTED_PLACEHOLDERS = /%[sdifjoOp]/g; const PRETTY_PLACEHOLDER = '%p'; const INDEX_PLACEHOLDER = '%#'; const PLACEHOLDER_PREFIX = '%'; +const ESCAPED_PLACEHOLDER_PREFIX = /%%/g; const JEST_EACH_PLACEHOLDER_ESCAPE = '@@__JEST_EACH_PLACEHOLDER_ESCAPE__@@'; export default (title: string, arrayTable: Global.ArrayTable): EachTests => @@ -46,7 +47,7 @@ const formatTitle = ( return interpolatePrettyPlaceholder(formattedTitle, normalisedValue); return util.format(formattedTitle, normalisedValue); - }, interpolateTitleIndex(title, rowIndex)) + }, interpolateTitleIndex(interpolateEscapedPlaceholders(title), rowIndex)) .replace(new RegExp(JEST_EACH_PLACEHOLDER_ESCAPE, 'g'), PLACEHOLDER_PREFIX); const normalisePlaceholderValue = (value: unknown) => @@ -57,6 +58,9 @@ const normalisePlaceholderValue = (value: unknown) => const getMatchingPlaceholders = (title: string) => title.match(SUPPORTED_PLACEHOLDERS) || []; +const interpolateEscapedPlaceholders = (title: string) => + title.replace(ESCAPED_PLACEHOLDER_PREFIX, JEST_EACH_PLACEHOLDER_ESCAPE); + const interpolateTitleIndex = (title: string, index: number) => title.replace(INDEX_PLACEHOLDER, index.toString()); From dc8cdab5a8b2135bf19d35a9feb17d4db1046dd5 Mon Sep 17 00:00:00 2001 From: Tetsuro Aoki Date: Sat, 1 May 2021 13:48:31 +0900 Subject: [PATCH 2/2] fix(jest-each): fix wrong interpolation --- CHANGELOG.md | 1 + packages/jest-each/src/__tests__/array.test.ts | 8 +++++++- packages/jest-each/src/table/array.ts | 7 +++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4697a0a1282e..37513c8a5370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ - `[jest-each]` [**BREAKING**] Ignore excess words in headings ([#8766](https://github.com/facebook/jest/pull/8766)) - `[jest-each]` Support array index with template strings ([#10763](https://github.com/facebook/jest/pull/10763)) - `[jest-each]` Interpolate `%%` correctly ([#11364](https://github.com/facebook/jest/pull/11364)) +- `[jest-each]` Fix wrong interpolation when the value of array contains multiple `%` ([#11364](https://github.com/facebook/jest/pull/11364)) - `[jest-environment]` [**BREAKING**] Drop support for `runScript` for test environments ([#11155](https://github.com/facebook/jest/pull/11155)) - `[jest-environment-jsdom]` Use inner realm’s `ArrayBuffer` constructor ([#10885](https://github.com/facebook/jest/pull/10885)) - `[jest-environment-jsdom]` [**BREAKING**] Remove Node globals `setImmediate` and `clearImmediate` [#11222](https://github.com/facebook/jest/pull/11222) diff --git a/packages/jest-each/src/__tests__/array.test.ts b/packages/jest-each/src/__tests__/array.test.ts index 471dd172c88f..c76609d80505 100644 --- a/packages/jest-each/src/__tests__/array.test.ts +++ b/packages/jest-each/src/__tests__/array.test.ts @@ -403,12 +403,13 @@ describe('jest-each', () => { const eachObject = each.withGlobal(globalTestMocks)([ ['hello', '%d', 10, '%s', {foo: 'bar'}], ['world', '%i', 1991, '%p', {foo: 'bar'}], + ['joe', '%d %d', 10, '%%s', {foo: 'bar'}], ]); const testFunction = get(eachObject, keyPath); testFunction('expected string: %s %s %d %s %p', () => {}); const globalMock = get(globalTestMocks, keyPath); - expect(globalMock).toHaveBeenCalledTimes(2); + expect(globalMock).toHaveBeenCalledTimes(3); expect(globalMock).toHaveBeenCalledWith( 'expected string: hello %d 10 %s {"foo": "bar"}', expectFunction, @@ -419,6 +420,11 @@ describe('jest-each', () => { expectFunction, undefined, ); + expect(globalMock).toHaveBeenCalledWith( + 'expected string: joe %d %d 10 %%s {"foo": "bar"}', + expectFunction, + undefined, + ); }); }); }); diff --git a/packages/jest-each/src/table/array.ts b/packages/jest-each/src/table/array.ts index 4fc272982976..fe245e8e77bd 100644 --- a/packages/jest-each/src/table/array.ts +++ b/packages/jest-each/src/table/array.ts @@ -51,8 +51,11 @@ const formatTitle = ( .replace(new RegExp(JEST_EACH_PLACEHOLDER_ESCAPE, 'g'), PLACEHOLDER_PREFIX); const normalisePlaceholderValue = (value: unknown) => - typeof value === 'string' && SUPPORTED_PLACEHOLDERS.test(value) - ? value.replace(PLACEHOLDER_PREFIX, JEST_EACH_PLACEHOLDER_ESCAPE) + typeof value === 'string' + ? value.replace( + new RegExp(PLACEHOLDER_PREFIX, 'g'), + JEST_EACH_PLACEHOLDER_ESCAPE, + ) : value; const getMatchingPlaceholders = (title: string) =>