diff --git a/CHANGELOG.md b/CHANGELOG.md index da9dba4496f1..447f0baadf95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - `[expect]` Add a fix for `.toHaveProperty('')` ([#12251](https://github.com/facebook/jest/pull/12251)) +- `[jest-each, @jest/globals]` Allow passing `ReadonlyArray` type of a table to `describe.each` and `test.each` ([#12297](https://github.com/facebook/jest/pull/12297)) - `[@jest/globals]` Add missing `options` argument to `jest.doMock` typing ([#12292](https://github.com/facebook/jest/pull/12292)) - `[jest-environment-node]` Add `atob` and `btoa` ([#12269](https://github.com/facebook/jest/pull/12269)) - `[jest-matcher-utils]` Correct diff for expected asymmetric matchers ([#12264](https://github.com/facebook/jest/pull/12264)) diff --git a/packages/jest-each/src/bind.ts b/packages/jest-each/src/bind.ts index 8ac7f186c60f..81e65ce6d14d 100644 --- a/packages/jest-each/src/bind.ts +++ b/packages/jest-each/src/bind.ts @@ -16,9 +16,9 @@ import { validateTemplateTableArguments, } from './validation'; -export type EachTests = Array<{ +export type EachTests = ReadonlyArray<{ title: string; - arguments: Array; + arguments: ReadonlyArray; }>; // type TestFn = (done?: Global.DoneFn) => Promise | void | undefined; @@ -80,7 +80,7 @@ const getHeadingKeys = (headings: string): Array => const applyArguments = ( supportsDone: boolean, - params: Array, + params: ReadonlyArray, test: Global.EachTestFn, ): Global.EachTestFn => supportsDone && params.length < test.length diff --git a/packages/jest-types/__typechecks__/globals.test.ts b/packages/jest-types/__typechecks__/globals.test.ts index 5aad8daabf5a..f1d843419a88 100644 --- a/packages/jest-types/__typechecks__/globals.test.ts +++ b/packages/jest-types/__typechecks__/globals.test.ts @@ -24,7 +24,13 @@ const asyncFn = async () => {}; const genFn = function* () {}; const timeout = 5; const testName = 'Test name'; -const testTable = [[1, 2]]; + +const list = [1, 2, 3]; +const table = [ + [1, 2], + [3, 4], +]; +const readonlyTable = [[1, 2], 'one'] as const; // https://jestjs.io/docs/api#methods expectType(afterAll(fn)); @@ -84,25 +90,234 @@ expectError( expectType(test(testName, fn)); expectType(test(testName, asyncFn)); expectType(test(testName, genFn)); -expectType(test.each(testTable)(testName, fn)); -expectType(test.each(testTable)(testName, fn, timeout)); -expectType(test.only.each(testTable)(testName, fn)); -expectType(test.only.each(testTable)(testName, fn, timeout)); -expectType(test.skip.each(testTable)(testName, fn)); -expectType(test.skip.each(testTable)(testName, fn, timeout)); -expectType(test.concurrent.each(testTable)(testName, asyncFn)); -expectType(test.concurrent.each(testTable)(testName, asyncFn, timeout)); -expectType(test.concurrent.only.each(testTable)(testName, asyncFn)); -expectType( - test.concurrent.only.each(testTable)(testName, asyncFn, timeout), -); -expectType(test.concurrent.skip.each(testTable)(testName, asyncFn)); -expectType( - test.concurrent.skip.each(testTable)(testName, asyncFn, timeout), -); -expectType(describe.each(testTable)(testName, fn)); -expectType(describe.each(testTable)(testName, fn, timeout)); -expectType(describe.only.each(testTable)(testName, fn)); -expectType(describe.only.each(testTable)(testName, fn, timeout)); -expectType(describe.skip.each(testTable)(testName, fn)); -expectType(describe.skip.each(testTable)(testName, fn, timeout)); + +expectType(test.each(list)(testName, fn)); +expectType(test.each(list)(testName, fn, timeout)); +expectType(test.each(table)(testName, fn)); +expectType(test.each(table)(testName, fn, timeout)); +expectType(test.each(readonlyTable)(testName, fn)); +expectType(test.each(readonlyTable)(testName, fn, timeout)); + +expectType(test.only.each(list)(testName, fn)); +expectType(test.only.each(list)(testName, fn, timeout)); +expectType(test.only.each(table)(testName, fn)); +expectType(test.only.each(table)(testName, fn, timeout)); +expectType(test.only.each(readonlyTable)(testName, fn)); +expectType(test.only.each(readonlyTable)(testName, fn, timeout)); + +expectType(test.skip.each(list)(testName, fn)); +expectType(test.skip.each(list)(testName, fn, timeout)); +expectType(test.skip.each(table)(testName, fn)); +expectType(test.skip.each(table)(testName, fn, timeout)); +expectType(test.skip.each(readonlyTable)(testName, fn)); +expectType(test.skip.each(readonlyTable)(testName, fn, timeout)); + +expectType( + test.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn), +); + +expectType( + test.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn, timeout), +); + +expectType( + test.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn), +); + +expectType( + test.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn, timeout), +); + +expectType( + test.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn), +); + +expectType( + test.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn, timeout), +); + +expectType(test.concurrent.each(list)(testName, asyncFn)); +expectType(test.concurrent.each(list)(testName, asyncFn, timeout)); +expectType(test.concurrent.each(table)(testName, asyncFn)); +expectType(test.concurrent.each(table)(testName, asyncFn, timeout)); +expectType(test.concurrent.each(readonlyTable)(testName, asyncFn)); +expectType( + test.concurrent.each(readonlyTable)(testName, asyncFn, timeout), +); + +expectType(test.concurrent.only.each(list)(testName, asyncFn)); +expectType(test.concurrent.only.each(list)(testName, asyncFn, timeout)); +expectType(test.concurrent.only.each(table)(testName, asyncFn)); +expectType(test.concurrent.only.each(table)(testName, asyncFn, timeout)); +expectType(test.concurrent.only.each(readonlyTable)(testName, asyncFn)); +expectType( + test.concurrent.only.each(readonlyTable)(testName, asyncFn, timeout), +); + +expectType(test.concurrent.skip.each(list)(testName, asyncFn)); +expectType(test.concurrent.skip.each(list)(testName, asyncFn, timeout)); +expectType(test.concurrent.skip.each(table)(testName, asyncFn)); +expectType(test.concurrent.skip.each(table)(testName, asyncFn, timeout)); +expectType(test.concurrent.skip.each(readonlyTable)(testName, asyncFn)); +expectType( + test.concurrent.skip.each(readonlyTable)(testName, asyncFn, timeout), +); + +expectType( + test.concurrent.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`(testName, asyncFn), +); + +expectType( + test.concurrent.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`(testName, asyncFn, timeout), +); + +expectType( + test.concurrent.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`(testName, asyncFn), +); + +expectType( + test.concurrent.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`(testName, asyncFn, timeout), +); + +expectType( + test.concurrent.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`(testName, asyncFn), +); + +expectType( + test.concurrent.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`(testName, asyncFn, timeout), +); + +expectType(describe.each(list)(testName, fn)); +expectType(describe.each(list)(testName, fn, timeout)); +expectType(describe.each(table)(testName, fn)); +expectType(describe.each(table)(testName, fn, timeout)); +expectType(describe.each(readonlyTable)(testName, fn)); +expectType(describe.each(readonlyTable)(testName, fn, timeout)); + +expectType(describe.only.each(list)(testName, fn)); +expectType(describe.only.each(list)(testName, fn, timeout)); +expectType(describe.only.each(table)(testName, fn)); +expectType(describe.only.each(table)(testName, fn, timeout)); +expectType(describe.only.each(readonlyTable)(testName, fn)); +expectType(describe.only.each(readonlyTable)(testName, fn, timeout)); + +expectType(describe.skip.each(list)(testName, fn)); +expectType(describe.skip.each(list)(testName, fn, timeout)); +expectType(describe.skip.each(table)(testName, fn)); +expectType(describe.skip.each(table)(testName, fn, timeout)); +expectType(describe.skip.each(readonlyTable)(testName, fn)); +expectType(describe.skip.each(readonlyTable)(testName, fn, timeout)); + +expectType( + describe.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn), +); + +expectType( + describe.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn, timeout), +); + +expectType( + describe.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn), +); + +expectType( + describe.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn, timeout), +); + +expectType( + describe.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn), +); + +expectType( + describe.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} + `(testName, fn, timeout), +); diff --git a/packages/jest-types/src/Global.ts b/packages/jest-types/src/Global.ts index 010624038707..024d5777ca98 100644 --- a/packages/jest-types/src/Global.ts +++ b/packages/jest-types/src/Global.ts @@ -38,17 +38,17 @@ export type BlockName = string; export type HookFn = TestFn; export type Col = unknown; -export type Row = Array; -export type Table = Array; +export type Row = ReadonlyArray; +export type Table = ReadonlyArray; export type ArrayTable = Table | Row; export type TemplateTable = TemplateStringsArray; -export type TemplateData = Array; +export type TemplateData = ReadonlyArray; export type EachTable = ArrayTable | TemplateTable; export type TestCallback = BlockFn | TestFn | ConcurrentTestFn; export type EachTestFn = ( - ...args: Array + ...args: ReadonlyArray ) => ReturnType; // TODO: Get rid of this at some point @@ -60,9 +60,9 @@ type Jasmine = { type Each = | (( table: EachTable, - ...taggedTemplateData: Array + ...taggedTemplateData: TemplateData ) => ( - title: string, + name: BlockName | TestName, test: EachTestFn, timeout?: number, ) => void) @@ -84,7 +84,7 @@ export interface It extends ItBase { } export interface ItConcurrentBase { - (testName: string, testFn: ConcurrentTestFn, timeout?: number): void; + (testName: TestName, testFn: ConcurrentTestFn, timeout?: number): void; each: Each; }