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

Add concurrent mode capability to jest-each types #9390

Closed
wants to merge 1 commit into from
Closed
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
Expand Up @@ -31,6 +31,7 @@ import {
import {getTestID} from '../utils';
import run from '../run';
import globals from '..';
import { bind } from 'jest-each/src';

type Process = NodeJS.Process;

Expand Down Expand Up @@ -71,7 +72,7 @@ export const initialize = ({
nodeGlobal.test.concurrent = (test => {
const concurrent = (
testName: string,
testFn: () => Promise<any>,
testFn: Global.ConcurrentTestFn,
timeout?: number,
) => {
// For concurrent tests we first run the function that returns promise, and then register a
Expand All @@ -84,18 +85,24 @@ export const initialize = ({
nodeGlobal.test(testName, () => promise, timeout);
};

concurrent.only = (
const only = (
testName: string,
testFn: () => Promise<any>,
testFn: Global.ConcurrentTestFn,
timeout?: number,
) => {
const promise = mutex(() => testFn());
// eslint-disable-next-line jest/no-focused-tests
test.only(testName, () => promise, timeout);
};

concurrent.only = only;

concurrent.skip = test.skip;

concurrent.each = bind(concurrent, false);
concurrent.skip.each = bind(concurrent.skip, false);
only.each = bind(concurrent.only, false);

return concurrent;
})(nodeGlobal.test);

Expand Down
26 changes: 15 additions & 11 deletions packages/jest-each/src/bind.ts
Expand Up @@ -18,16 +18,20 @@ export type EachTests = Array<{
arguments: Array<unknown>;
}>;

type TestFn = (done?: Global.DoneFn) => Promise<any> | void | undefined;
type GlobalCallback = (testName: string, fn: TestFn, timeout?: number) => void;
type ErrorCallback = () => never;
type GlobalCallback<A extends Global.TestCallback> = (
testName: string,
fn: A | ErrorCallback,
timeout?: number,
) => void;

export default (cb: GlobalCallback, supportsDone: boolean = true) => (
table: Global.EachTable,
...taggedTemplateData: Global.TemplateData
) =>
export default <A extends Global.TestCallback>(
cb: GlobalCallback<A>,
supportsDone: boolean = true,
) => (table: Global.EachTable, ...taggedTemplateData: Global.TemplateData) =>
function eachBind(
title: string,
test: Global.EachTestFn,
test: Global.EachTestFn<A>,
timeout?: number,
): void {
try {
Expand All @@ -38,7 +42,7 @@ export default (cb: GlobalCallback, supportsDone: boolean = true) => (
return tests.forEach(row =>
cb(
row.title,
applyArguments(supportsDone, row.arguments, test),
applyArguments(supportsDone, row.arguments, test) as A,
timeout,
),
);
Expand Down Expand Up @@ -70,11 +74,11 @@ const buildTemplateTests = (
const getHeadingKeys = (headings: string): Array<string> =>
headings.replace(/\s/g, '').split('|');

const applyArguments = (
const applyArguments = <A extends Global.TestCallback>(
supportsDone: boolean,
params: Array<unknown>,
test: Global.EachTestFn,
): Global.EachTestFn =>
test: Global.EachTestFn<A>,
): Global.EachTestFn<any> =>
supportsDone && params.length < test.length
? (done: Global.DoneFn) => test(...params, done)
: () => test(...params);
27 changes: 22 additions & 5 deletions packages/jest-each/src/index.ts
Expand Up @@ -15,23 +15,40 @@ const install = (
table: Global.EachTable,
...data: Global.TemplateData
) => {
const test = (title: string, test: Global.EachTestFn, timeout?: number) =>
bind(g.test)(table, ...data)(title, test, timeout);
const test = (
title: string,
test: Global.EachTestFn<Global.TestFn>,
timeout?: number,
) => bind(g.test)(table, ...data)(title, test, timeout);
test.skip = bind(g.test.skip)(table, ...data);
test.only = bind(g.test.only)(table, ...data);

const it = (title: string, test: Global.EachTestFn, timeout?: number) =>
bind(g.it)(table, ...data)(title, test, timeout);
const testConcurrent = (
title: string,
test: Global.EachTestFn<Global.ConcurrentTestFn>,
timeout?: number,
) => bind(g.test.concurrent)(table, ...data)(title, test, timeout);

test.concurrent = testConcurrent;
testConcurrent.only = bind(g.test.concurrent.only)(table, ...data);
testConcurrent.skip = bind(g.test.concurrent.skip)(table, ...data);

const it = (
title: string,
test: Global.EachTestFn<Global.TestFn>,
timeout?: number,
) => bind(g.it)(table, ...data)(title, test, timeout);
it.skip = bind(g.it.skip)(table, ...data);
it.only = bind(g.it.only)(table, ...data);
it.concurrent = testConcurrent;

const xit = bind(g.xit)(table, ...data);
const fit = bind(g.fit)(table, ...data);
const xtest = bind(g.xtest)(table, ...data);

const describe = (
title: string,
suite: Global.EachTestFn,
suite: Global.EachTestFn<Global.BlockFn>,
timeout?: number,
) => bind(g.describe, false)(table, ...data)(title, suite, timeout);
describe.skip = bind(g.describe.skip, false)(table, ...data);
Expand Down
13 changes: 13 additions & 0 deletions packages/jest-jasmine2/src/each.ts
Expand Up @@ -24,4 +24,17 @@ export default (environment: JestEnvironment): void => {
environment.global.fdescribe,
false,
);

environment.global.it.concurrent.each = bindEach(
environment.global.it.concurrent,
false,
)
environment.global.it.concurrent.only.each = bindEach(
environment.global.it.concurrent.only,
false,
)
environment.global.it.concurrent.skip.each = bindEach(
environment.global.it.concurrent.skip,
false,
)
};
19 changes: 12 additions & 7 deletions packages/jest-types/src/Global.ts
Expand Up @@ -10,6 +10,7 @@ import {CoverageMapData} from 'istanbul-lib-coverage';
export type DoneFn = (reason?: string | Error) => void;
export type TestName = string;
export type TestFn = (done?: DoneFn) => Promise<any> | void | undefined;
export type ConcurrentTestFn = () => Promise<any>;
export type BlockFn = () => void;
export type BlockName = string;

Expand All @@ -20,21 +21,24 @@ export type ArrayTable = Table | Row;
export type TemplateTable = TemplateStringsArray;
export type TemplateData = Array<unknown>;
export type EachTable = ArrayTable | TemplateTable;
export type EachTestFn = (

export type TestCallback = BlockFn | TestFn | ConcurrentTestFn;

export type EachTestFn<A extends TestCallback> = (
...args: Array<any>
) => Promise<any> | void | undefined;
) => ReturnType<A>;

// TODO: Get rid of this at some point
type Jasmine = {_DEFAULT_TIMEOUT_INTERVAL?: number; addMatchers: Function};

type Each = (
type Each<A extends TestCallback> = (
table: EachTable,
...taggedTemplateData: Array<unknown>
) => (title: string, test: EachTestFn, timeout?: number) => void;
) => (title: string, test: EachTestFn<A>, timeout?: number) => void;

export interface ItBase {
(testName: TestName, fn: TestFn, timeout?: number): void;
each: Each;
each: Each<TestFn>;
}

export interface It extends ItBase {
Expand All @@ -44,7 +48,8 @@ export interface It extends ItBase {
}

export interface ItConcurrentBase {
(testName: string, testFn: () => Promise<any>, timeout?: number): void;
(testName: string, testFn: ConcurrentTestFn, timeout?: number): void;
each: Each<ConcurrentTestFn>;
}

export interface ItConcurrentExtended extends ItConcurrentBase {
Expand All @@ -58,7 +63,7 @@ export interface ItConcurrent extends It {

export interface DescribeBase {
(blockName: BlockName, blockFn: BlockFn): void;
each: Each;
each: Each<BlockFn>;
}

export interface Describe extends DescribeBase {
Expand Down