diff --git a/CHANGELOG.md b/CHANGELOG.md index 179398c50251..f295501337d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - `[jest-snapshot]` [**BREAKING**] Add support for [Error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) in snapshots ([#13965](https://github.com/facebook/jest/pull/13965)) - `[jest-snapshot]` Support Prettier 3 ([#14566](https://github.com/facebook/jest/pull/14566)) - `[pretty-format]` [**BREAKING**] Do not render empty string children (`''`) in React plugin ([#14470](https://github.com/facebook/jest/pull/14470)) +- `[jest-each]` Introduce `%$` option to add number of the test to its title ([#14710](https://github.com/jestjs/jest/pull/14710)) ### Fixes diff --git a/docs/GlobalAPI.md b/docs/GlobalAPI.md index 99bfdc092b53..6d40690337db 100644 --- a/docs/GlobalAPI.md +++ b/docs/GlobalAPI.md @@ -248,6 +248,7 @@ Use `describe.each` if you keep duplicating the same test suites with different - `%j` - JSON. - `%o` - Object. - `%#` - Index of the test case. + - `%$` - Number of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - Or generate unique test titles by injecting properties of test case object with `$variable` - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` @@ -550,6 +551,7 @@ Use `test.concurrent.each` if you keep duplicating the same test with different - `%j` - JSON. - `%o` - Object. - `%#` - Index of the test case. + - `%$` - Number of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - `fn`: `Function` the test to be run, this is the function that will receive the parameters in each row as function arguments, **this will have to be an asynchronous function**. - Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. @@ -692,6 +694,7 @@ Use `test.each` if you keep duplicating the same test with different data. `test - `%j` - JSON. - `%o` - Object. - `%#` - Index of the test case. + - `%$` - Number of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - Or generate unique test titles by injecting properties of test case object with `$variable` - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` diff --git a/packages/jest-each/README.md b/packages/jest-each/README.md index 3b4384387ca4..fd4be0917eed 100644 --- a/packages/jest-each/README.md +++ b/packages/jest-each/README.md @@ -40,6 +40,7 @@ jest-each allows you to provide multiple arguments to your `test`/`describe` whi - `%j` - JSON. - `%o` - Object. - `%#` - Index of the test case. + - `%$` - Number of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - Unique test titles by injecting properties of test case object - 🖖 Spock like data tables with [Tagged Template Literals](#tagged-template-literal-of-rows) @@ -118,6 +119,7 @@ const each = require('jest-each').default; - `%j` - JSON. - `%o` - Object. - `%#` - Index of the test case. + - `%$` - Number of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - Or generate unique test titles by injecting properties of test case object with `$variable` - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` @@ -144,6 +146,7 @@ const each = require('jest-each').default; - `%j` - JSON. - `%o` - Object. - `%#` - Index of the test case. + - `%$` - Number of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - Or generate unique test titles by injecting properties of test case object with `$variable` - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` diff --git a/packages/jest-each/src/__tests__/array.test.ts b/packages/jest-each/src/__tests__/array.test.ts index 69d99c359fd2..4c2ecb940f77 100644 --- a/packages/jest-each/src/__tests__/array.test.ts +++ b/packages/jest-each/src/__tests__/array.test.ts @@ -144,7 +144,7 @@ describe('jest-each', () => { ]); const testFunction = get(eachObject, keyPath); testFunction( - 'expected string: %% %%s %s %d %s %s %d %j %s %j %d %d %#', + 'expected string: %% %%s %s %d %s %s %d %j %s %j %d %d %# %$', noop, ); @@ -153,14 +153,14 @@ describe('jest-each', () => { expect(globalMock).toHaveBeenCalledWith( `expected string: % %s hello 1 null undefined 1.2 ${JSON.stringify({ foo: 'bar', - })} () => {} [] Infinity NaN 0`, + })} () => {} [] Infinity NaN 0 1`, expectFunction, undefined, ); expect(globalMock).toHaveBeenCalledWith( `expected string: % %s world 1 null undefined 1.2 ${JSON.stringify({ baz: 'qux', - })} () => {} [] Infinity NaN 1`, + })} () => {} [] Infinity NaN 1 2`, expectFunction, undefined, ); diff --git a/packages/jest-each/src/table/array.ts b/packages/jest-each/src/table/array.ts index e411ff9cd9f1..77fa7d883779 100644 --- a/packages/jest-each/src/table/array.ts +++ b/packages/jest-each/src/table/array.ts @@ -15,6 +15,7 @@ import {type Templates, interpolateVariables} from './interpolation'; const SUPPORTED_PLACEHOLDERS = /%[#Odfijops]/g; const PRETTY_PLACEHOLDER = '%p'; const INDEX_PLACEHOLDER = '%#'; +const NUMBER_PLACEHOLDER = '%$'; const PLACEHOLDER_PREFIX = '%'; const ESCAPED_PLACEHOLDER_PREFIX = /%%/g; const JEST_EACH_PLACEHOLDER_ESCAPE = '@@__JEST_EACH_PLACEHOLDER_ESCAPE__@@'; @@ -71,7 +72,10 @@ const formatTitle = ( return util.format(formattedTitle, normalisedValue); }, - interpolateTitleIndex(interpolateEscapedPlaceholders(title), rowIndex), + interpolateTitleIndexAndNumber( + interpolateEscapedPlaceholders(title), + rowIndex, + ), ) .replaceAll( new RegExp(JEST_EACH_PLACEHOLDER_ESCAPE, 'g'), @@ -92,8 +96,10 @@ const getMatchingPlaceholders = (title: string) => const interpolateEscapedPlaceholders = (title: string) => title.replaceAll(ESCAPED_PLACEHOLDER_PREFIX, JEST_EACH_PLACEHOLDER_ESCAPE); -const interpolateTitleIndex = (title: string, index: number) => - title.replace(INDEX_PLACEHOLDER, index.toString()); +const interpolateTitleIndexAndNumber = (title: string, index: number) => + title + .replace(INDEX_PLACEHOLDER, index.toString()) + .replace(NUMBER_PLACEHOLDER, (index + 1).toString()); const interpolatePrettyPlaceholder = (title: string, value: unknown) => title.replace(PRETTY_PLACEHOLDER, pretty(value, {maxDepth: 1, min: true}));