diff --git a/CHANGELOG.md b/CHANGELOG.md index cbaba47a64e5..2fa452bf7523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - `[jest-core]` Don't report PerformanceObserver as open handle ([#11123](https://github.com/facebook/jest/pull/11123)) - `[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-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/docs/GlobalAPI.md b/docs/GlobalAPI.md index 1e6b66056ac0..ec9f27633c91 100644 --- a/docs/GlobalAPI.md +++ b/docs/GlobalAPI.md @@ -275,7 +275,7 @@ describe.each([ - `table`: `Tagged Template Literal` - First row of variable name column headings separated with `|` - One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax. -- `name`: `String` the title of the test suite, use `$variable` to inject test data into the suite title from the tagged template expressions. +- `name`: `String` the title of the test suite, use `$variable` to inject test data into the suite title from the tagged template expressions, and `$#` for the index of the row. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` - `fn`: `Function` the suite of tests to be ran, this is the function that will receive the test data object. - Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ diff --git a/packages/jest-each/README.md b/packages/jest-each/README.md index 16c845c7e41a..c06a6ad2b589 100644 --- a/packages/jest-each/README.md +++ b/packages/jest-each/README.md @@ -338,6 +338,7 @@ each` - name: `String` the title of the `test`, use `$variable` in the name string to inject test values into the test title from the tagged template expressions - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` + - You can use `$#` to inject the index of the table row. - testFn: `Function` the test logic, this is the function that will receive the parameters of each row as function arguments #### `each[tagged template].describe(name, suiteFn)` diff --git a/packages/jest-each/src/__tests__/template.test.ts b/packages/jest-each/src/__tests__/template.test.ts index e185c52e0886..5fc5d657d780 100644 --- a/packages/jest-each/src/__tests__/template.test.ts +++ b/packages/jest-each/src/__tests__/template.test.ts @@ -288,17 +288,20 @@ describe('jest-each', () => { ${1} | ${1} | ${2} `; const testFunction = get(eachObject, keyPath); - testFunction('expected string: a=$a, b=$b, expected=$expected', noop); + testFunction( + 'expected string: a=$a, b=$b, expected=$expected index=$#', + noop, + ); const globalMock = get(globalTestMocks, keyPath); expect(globalMock).toHaveBeenCalledTimes(2); expect(globalMock).toHaveBeenCalledWith( - 'expected string: a=0, b=1, expected=1', + 'expected string: a=0, b=1, expected=1 index=0', expectFunction, undefined, ); expect(globalMock).toHaveBeenCalledWith( - 'expected string: a=1, b=1, expected=2', + 'expected string: a=1, b=1, expected=2 index=1', expectFunction, undefined, ); @@ -313,19 +316,19 @@ describe('jest-each', () => { `; const testFunction = get(eachObject, keyPath); testFunction( - 'add($a, $b) expected string: a=$a, b=$b, expected=$expected', + 'add($a, $b) expected string: a=$a, b=$b, expected=$expected index=$#', noop, ); const globalMock = get(globalTestMocks, keyPath); expect(globalMock).toHaveBeenCalledTimes(2); expect(globalMock).toHaveBeenCalledWith( - 'add(0, 1) expected string: a=0, b=1, expected=1', + 'add(0, 1) expected string: a=0, b=1, expected=1 index=0', expectFunction, undefined, ); expect(globalMock).toHaveBeenCalledWith( - 'add(1, 1) expected string: a=1, b=1, expected=2', + 'add(1, 1) expected string: a=1, b=1, expected=2 index=1', expectFunction, undefined, ); @@ -543,17 +546,20 @@ describe('jest-each', () => { ${1} | ${1} | ${2} `; const testFunction = get(eachObject, keyPath); - testFunction('expected string: a=$a, b=$b, expected=$expected', noop); + testFunction( + 'expected string: a=$a, b=$b, expected=$expected index=$#', + noop, + ); const globalMock = get(globalTestMocks, keyPath); expect(globalMock).toHaveBeenCalledTimes(2); expect(globalMock).toHaveBeenCalledWith( - 'expected string: a=0, b=1, expected=1', + 'expected string: a=0, b=1, expected=1 index=0', expectFunction, undefined, ); expect(globalMock).toHaveBeenCalledWith( - 'expected string: a=1, b=1, expected=2', + 'expected string: a=1, b=1, expected=2 index=1', expectFunction, undefined, ); diff --git a/packages/jest-each/src/table/template.ts b/packages/jest-each/src/table/template.ts index c3cf5d22830b..ad0cacca28fc 100644 --- a/packages/jest-each/src/table/template.ts +++ b/packages/jest-each/src/table/template.ts @@ -22,9 +22,9 @@ export default ( ): EachTests => { const table = convertRowToTable(row, headings); const templates = convertTableToTemplates(table, headings); - return templates.map(template => ({ + return templates.map((template, index) => ({ arguments: [template], - title: interpolate(title, template), + title: interpolate(title, template, index), })); }; @@ -47,10 +47,11 @@ const convertTableToTemplates = ( ), ); -const interpolate = (title: string, template: Template) => +const interpolate = (title: string, template: Template, index: number) => Object.keys(template) .reduce(getMatchingKeyPaths(title), []) // aka flatMap - .reduce(replaceKeyPathWithValue(template), title); + .reduce(replaceKeyPathWithValue(template), title) + .replace('$#', '' + index); const getMatchingKeyPaths = (title: string) => ( matches: Headings,