Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(jest-each, @jest/globals): allow passing ReadonlyArray type of a table to describe.each and test.each #12297

Merged
merged 2 commits into from Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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