Skip to content

Commit

Permalink
fix(jest-each, @jest/globals): allow passing ReadonlyArray type of …
Browse files Browse the repository at this point in the history
…a table to `describe.each` and `test.each` (#12297)

* fix: each typings

* add changelog entry
  • Loading branch information
mrazauskas committed Feb 3, 2022
1 parent 71c1e93 commit 7509d25
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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))
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-each/src/bind.ts
Expand Up @@ -16,9 +16,9 @@ import {
validateTemplateTableArguments,
} from './validation';

export type EachTests = Array<{
export type EachTests = ReadonlyArray<{
title: string;
arguments: Array<unknown>;
arguments: ReadonlyArray<unknown>;
}>;

// type TestFn = (done?: Global.DoneFn) => Promise<any> | void | undefined;
Expand Down Expand Up @@ -80,7 +80,7 @@ const getHeadingKeys = (headings: string): Array<string> =>

const applyArguments = <EachCallback extends Global.TestCallback>(
supportsDone: boolean,
params: Array<unknown>,
params: ReadonlyArray<unknown>,
test: Global.EachTestFn<EachCallback>,
): Global.EachTestFn<any> =>
supportsDone && params.length < test.length
Expand Down
261 changes: 238 additions & 23 deletions packages/jest-types/__typechecks__/globals.test.ts
Expand Up @@ -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<void>(afterAll(fn));
Expand Down Expand Up @@ -84,25 +90,234 @@ expectError(
expectType<void>(test(testName, fn));
expectType<void>(test(testName, asyncFn));
expectType<void>(test(testName, genFn));
expectType<void>(test.each(testTable)(testName, fn));
expectType<void>(test.each(testTable)(testName, fn, timeout));
expectType<void>(test.only.each(testTable)(testName, fn));
expectType<void>(test.only.each(testTable)(testName, fn, timeout));
expectType<void>(test.skip.each(testTable)(testName, fn));
expectType<void>(test.skip.each(testTable)(testName, fn, timeout));
expectType<void>(test.concurrent.each(testTable)(testName, asyncFn));
expectType<void>(test.concurrent.each(testTable)(testName, asyncFn, timeout));
expectType<void>(test.concurrent.only.each(testTable)(testName, asyncFn));
expectType<void>(
test.concurrent.only.each(testTable)(testName, asyncFn, timeout),
);
expectType<void>(test.concurrent.skip.each(testTable)(testName, asyncFn));
expectType<void>(
test.concurrent.skip.each(testTable)(testName, asyncFn, timeout),
);
expectType<void>(describe.each(testTable)(testName, fn));
expectType<void>(describe.each(testTable)(testName, fn, timeout));
expectType<void>(describe.only.each(testTable)(testName, fn));
expectType<void>(describe.only.each(testTable)(testName, fn, timeout));
expectType<void>(describe.skip.each(testTable)(testName, fn));
expectType<void>(describe.skip.each(testTable)(testName, fn, timeout));

expectType<void>(test.each(list)(testName, fn));
expectType<void>(test.each(list)(testName, fn, timeout));
expectType<void>(test.each(table)(testName, fn));
expectType<void>(test.each(table)(testName, fn, timeout));
expectType<void>(test.each(readonlyTable)(testName, fn));
expectType<void>(test.each(readonlyTable)(testName, fn, timeout));

expectType<void>(test.only.each(list)(testName, fn));
expectType<void>(test.only.each(list)(testName, fn, timeout));
expectType<void>(test.only.each(table)(testName, fn));
expectType<void>(test.only.each(table)(testName, fn, timeout));
expectType<void>(test.only.each(readonlyTable)(testName, fn));
expectType<void>(test.only.each(readonlyTable)(testName, fn, timeout));

expectType<void>(test.skip.each(list)(testName, fn));
expectType<void>(test.skip.each(list)(testName, fn, timeout));
expectType<void>(test.skip.each(table)(testName, fn));
expectType<void>(test.skip.each(table)(testName, fn, timeout));
expectType<void>(test.skip.each(readonlyTable)(testName, fn));
expectType<void>(test.skip.each(readonlyTable)(testName, fn, timeout));

expectType<void>(
test.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn),
);

expectType<void>(
test.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn, timeout),
);

expectType<void>(
test.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn),
);

expectType<void>(
test.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn, timeout),
);

expectType<void>(
test.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn),
);

expectType<void>(
test.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn, timeout),
);

expectType<void>(test.concurrent.each(list)(testName, asyncFn));
expectType<void>(test.concurrent.each(list)(testName, asyncFn, timeout));
expectType<void>(test.concurrent.each(table)(testName, asyncFn));
expectType<void>(test.concurrent.each(table)(testName, asyncFn, timeout));
expectType<void>(test.concurrent.each(readonlyTable)(testName, asyncFn));
expectType<void>(
test.concurrent.each(readonlyTable)(testName, asyncFn, timeout),
);

expectType<void>(test.concurrent.only.each(list)(testName, asyncFn));
expectType<void>(test.concurrent.only.each(list)(testName, asyncFn, timeout));
expectType<void>(test.concurrent.only.each(table)(testName, asyncFn));
expectType<void>(test.concurrent.only.each(table)(testName, asyncFn, timeout));
expectType<void>(test.concurrent.only.each(readonlyTable)(testName, asyncFn));
expectType<void>(
test.concurrent.only.each(readonlyTable)(testName, asyncFn, timeout),
);

expectType<void>(test.concurrent.skip.each(list)(testName, asyncFn));
expectType<void>(test.concurrent.skip.each(list)(testName, asyncFn, timeout));
expectType<void>(test.concurrent.skip.each(table)(testName, asyncFn));
expectType<void>(test.concurrent.skip.each(table)(testName, asyncFn, timeout));
expectType<void>(test.concurrent.skip.each(readonlyTable)(testName, asyncFn));
expectType<void>(
test.concurrent.skip.each(readonlyTable)(testName, asyncFn, timeout),
);

expectType<void>(
test.concurrent.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, asyncFn),
);

expectType<void>(
test.concurrent.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, asyncFn, timeout),
);

expectType<void>(
test.concurrent.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, asyncFn),
);

expectType<void>(
test.concurrent.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, asyncFn, timeout),
);

expectType<void>(
test.concurrent.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, asyncFn),
);

expectType<void>(
test.concurrent.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, asyncFn, timeout),
);

expectType<void>(describe.each(list)(testName, fn));
expectType<void>(describe.each(list)(testName, fn, timeout));
expectType<void>(describe.each(table)(testName, fn));
expectType<void>(describe.each(table)(testName, fn, timeout));
expectType<void>(describe.each(readonlyTable)(testName, fn));
expectType<void>(describe.each(readonlyTable)(testName, fn, timeout));

expectType<void>(describe.only.each(list)(testName, fn));
expectType<void>(describe.only.each(list)(testName, fn, timeout));
expectType<void>(describe.only.each(table)(testName, fn));
expectType<void>(describe.only.each(table)(testName, fn, timeout));
expectType<void>(describe.only.each(readonlyTable)(testName, fn));
expectType<void>(describe.only.each(readonlyTable)(testName, fn, timeout));

expectType<void>(describe.skip.each(list)(testName, fn));
expectType<void>(describe.skip.each(list)(testName, fn, timeout));
expectType<void>(describe.skip.each(table)(testName, fn));
expectType<void>(describe.skip.each(table)(testName, fn, timeout));
expectType<void>(describe.skip.each(readonlyTable)(testName, fn));
expectType<void>(describe.skip.each(readonlyTable)(testName, fn, timeout));

expectType<void>(
describe.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn),
);

expectType<void>(
describe.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn, timeout),
);

expectType<void>(
describe.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn),
);

expectType<void>(
describe.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn, timeout),
);

expectType<void>(
describe.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn),
);

expectType<void>(
describe.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`(testName, fn, timeout),
);
14 changes: 7 additions & 7 deletions packages/jest-types/src/Global.ts
Expand Up @@ -38,17 +38,17 @@ export type BlockName = string;
export type HookFn = TestFn;

export type Col = unknown;
export type Row = Array<Col>;
export type Table = Array<Row>;
export type Row = ReadonlyArray<Col>;
export type Table = ReadonlyArray<Row>;
export type ArrayTable = Table | Row;
export type TemplateTable = TemplateStringsArray;
export type TemplateData = Array<unknown>;
export type TemplateData = ReadonlyArray<unknown>;
export type EachTable = ArrayTable | TemplateTable;

export type TestCallback = BlockFn | TestFn | ConcurrentTestFn;

export type EachTestFn<EachCallback extends TestCallback> = (
...args: Array<any>
...args: ReadonlyArray<any>
) => ReturnType<EachCallback>;

// TODO: Get rid of this at some point
Expand All @@ -60,9 +60,9 @@ type Jasmine = {
type Each<EachCallback extends TestCallback> =
| ((
table: EachTable,
...taggedTemplateData: Array<unknown>
...taggedTemplateData: TemplateData
) => (
title: string,
name: BlockName | TestName,
test: EachTestFn<EachCallback>,
timeout?: number,
) => void)
Expand All @@ -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<ConcurrentTestFn>;
}

Expand Down

0 comments on commit 7509d25

Please sign in to comment.