diff --git a/CHANGELOG.md b/CHANGELOG.md index 13752c82a913..b357758570eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ - `[jest-config]` Support `testTimeout` in project config ([#14697](https://github.com/jestjs/jest/pull/14697)) - `[jest-config]` Support `coverageReporters` in project config ([#14697](https://github.com/jestjs/jest/pull/14830)) - `[jest-config]` Allow `reporters` in project config ([#14768](https://github.com/jestjs/jest/pull/14768)) +- `[jest-each]` Allow `$keypath` templates with `null` or `undefined` values ([#14831](https://github.com/jestjs/jest/pull/14831)) - `[@jest/expect-utils]` Fix comparison of `DataView` ([#14408](https://github.com/jestjs/jest/pull/14408)) - `[@jest/expect-utils]` [**BREAKING**] exclude non-enumerable in object matching ([#14670](https://github.com/jestjs/jest/pull/14670)) - `[@jest/expect-utils]` Fix comparison of `URL` ([#14672](https://github.com/jestjs/jest/pull/14672)) diff --git a/e2e/__tests__/__snapshots__/each.test.ts.snap b/e2e/__tests__/__snapshots__/each.test.ts.snap index 4a45f6442fe8..d805b210717e 100644 --- a/e2e/__tests__/__snapshots__/each.test.ts.snap +++ b/e2e/__tests__/__snapshots__/each.test.ts.snap @@ -1,5 +1,15 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`allows nullable or undefined args when templating object each args 1`] = ` +"PASS __tests__/eachTemplate.test.js + ✓ allows templating "value" + ✓ allows templating "null" + ✓ allows templating "undefined" + ✓ allows templating "1" + ✓ allows templating "null" + ✓ allows templating "undefined"" +`; + exports[`formats args with pretty format when given %p 1`] = ` "PASS __tests__/pretty.test.js array diff --git a/e2e/__tests__/each.test.ts b/e2e/__tests__/each.test.ts index c0205f039ab7..582d5432ef95 100644 --- a/e2e/__tests__/each.test.ts +++ b/e2e/__tests__/each.test.ts @@ -60,3 +60,10 @@ test('formats args with pretty format when given %p', () => { expect(rest).toMatchSnapshot(); expect(result.exitCode).toBe(0); }); + +test('allows nullable or undefined args when templating object each args', () => { + const result = runJest(dir, ['eachTemplate.test.js']); + const {rest} = extractSummary(result.stderr); + expect(rest).toMatchSnapshot(); + expect(result.exitCode).toBe(0); +}); diff --git a/e2e/each/__tests__/eachTemplate.test.js b/e2e/each/__tests__/eachTemplate.test.js new file mode 100644 index 000000000000..9f8aaa3db8d7 --- /dev/null +++ b/e2e/each/__tests__/eachTemplate.test.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +it.each([ + {something: {nested: 'value'}}, + {something: null}, + {something: undefined}, +])('allows templating "$something.nested"', value => { + expect(value).toBe(value); +}); + +it.each([{array: ['some value']}, {array: null}, {array: undefined}])( + 'allows templating "$array.length"', + value => { + expect(value).toBe(value); + }, +); diff --git a/packages/jest-each/src/__tests__/template.test.ts b/packages/jest-each/src/__tests__/template.test.ts index b4d726558deb..15469b6da4c2 100644 --- a/packages/jest-each/src/__tests__/template.test.ts +++ b/packages/jest-each/src/__tests__/template.test.ts @@ -417,6 +417,30 @@ describe('jest-each', () => { ); }); + test.each([null, undefined])( + 'calls global with title containing $key.path for %s', + value => { + const globalTestMocks = getGlobalTestMocks(); + const eachObject = each.withGlobal(globalTestMocks)` + a + ${{foo: value}} + `; + const testFunction = get(eachObject, keyPath); + testFunction( + 'interpolates object keyPath to value: $a.foo.bar', + noop, + ); + + const globalMock = get(globalTestMocks, keyPath); + expect(globalMock).toHaveBeenCalledTimes(1); + expect(globalMock).toHaveBeenCalledWith( + `interpolates object keyPath to value: ${value}`, + expectFunction, + undefined, + ); + }, + ); + test('calls global with title containing last seen object when $key.path is invalid', () => { const globalTestMocks = getGlobalTestMocks(); const eachObject = each.withGlobal(globalTestMocks)` diff --git a/packages/jest-each/src/table/interpolation.ts b/packages/jest-each/src/table/interpolation.ts index 194dea97c655..0ab3049592e0 100644 --- a/packages/jest-each/src/table/interpolation.ts +++ b/packages/jest-each/src/table/interpolation.ts @@ -71,6 +71,8 @@ export function getPath( template: Template, [head, ...tail]: Array, ): unknown { + if (template === null) return 'null'; + if (template === undefined) return 'undefined'; if (!head || !Object.prototype.hasOwnProperty.call(template, head)) return template; return getPath(template[head] as Template, tail);