From b864f2ae3e21092e6388f8a31834b19a398cc53b Mon Sep 17 00:00:00 2001 From: Matt Phillips Date: Fri, 10 Jan 2020 13:12:55 +0000 Subject: [PATCH] Add concurrent support to jest-each --- .../jestAdapterInit.ts | 13 ++++++--- packages/jest-each/src/bind.ts | 26 ++++++++++-------- packages/jest-each/src/index.ts | 27 +++++++++++++++---- packages/jest-jasmine2/src/each.ts | 13 +++++++++ packages/jest-types/src/Global.ts | 19 ++++++++----- 5 files changed, 72 insertions(+), 26 deletions(-) diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts index 0b0f92095ba3..ebf271d9cb61 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -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; @@ -71,7 +72,7 @@ export const initialize = ({ nodeGlobal.test.concurrent = (test => { const concurrent = ( testName: string, - testFn: () => Promise, + testFn: Global.ConcurrentTestFn, timeout?: number, ) => { // For concurrent tests we first run the function that returns promise, and then register a @@ -84,9 +85,9 @@ export const initialize = ({ nodeGlobal.test(testName, () => promise, timeout); }; - concurrent.only = ( + const only = ( testName: string, - testFn: () => Promise, + testFn: Global.ConcurrentTestFn, timeout?: number, ) => { const promise = mutex(() => testFn()); @@ -94,8 +95,14 @@ export const initialize = ({ 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); diff --git a/packages/jest-each/src/bind.ts b/packages/jest-each/src/bind.ts index c32542e9ea41..4b11e4c225b4 100644 --- a/packages/jest-each/src/bind.ts +++ b/packages/jest-each/src/bind.ts @@ -18,16 +18,20 @@ export type EachTests = Array<{ arguments: Array; }>; -type TestFn = (done?: Global.DoneFn) => Promise | void | undefined; -type GlobalCallback = (testName: string, fn: TestFn, timeout?: number) => void; +type ErrorCallback = () => never; +type GlobalCallback = ( + testName: string, + fn: A | ErrorCallback, + timeout?: number, +) => void; -export default (cb: GlobalCallback, supportsDone: boolean = true) => ( - table: Global.EachTable, - ...taggedTemplateData: Global.TemplateData -) => +export default ( + cb: GlobalCallback, + supportsDone: boolean = true, +) => (table: Global.EachTable, ...taggedTemplateData: Global.TemplateData) => function eachBind( title: string, - test: Global.EachTestFn, + test: Global.EachTestFn, timeout?: number, ): void { try { @@ -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, ), ); @@ -70,11 +74,11 @@ const buildTemplateTests = ( const getHeadingKeys = (headings: string): Array => headings.replace(/\s/g, '').split('|'); -const applyArguments = ( +const applyArguments = ( supportsDone: boolean, params: Array, - test: Global.EachTestFn, -): Global.EachTestFn => + test: Global.EachTestFn, +): Global.EachTestFn => supportsDone && params.length < test.length ? (done: Global.DoneFn) => test(...params, done) : () => test(...params); diff --git a/packages/jest-each/src/index.ts b/packages/jest-each/src/index.ts index 016e5f60293c..b4125d22f13f 100644 --- a/packages/jest-each/src/index.ts +++ b/packages/jest-each/src/index.ts @@ -15,15 +15,32 @@ 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, + 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, + 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, + 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); @@ -31,7 +48,7 @@ const install = ( const describe = ( title: string, - suite: Global.EachTestFn, + suite: Global.EachTestFn, timeout?: number, ) => bind(g.describe, false)(table, ...data)(title, suite, timeout); describe.skip = bind(g.describe.skip, false)(table, ...data); diff --git a/packages/jest-jasmine2/src/each.ts b/packages/jest-jasmine2/src/each.ts index 05bc252304a6..e4babf2adcde 100644 --- a/packages/jest-jasmine2/src/each.ts +++ b/packages/jest-jasmine2/src/each.ts @@ -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, + ) }; diff --git a/packages/jest-types/src/Global.ts b/packages/jest-types/src/Global.ts index f43daaed8ed3..d66edd76423e 100644 --- a/packages/jest-types/src/Global.ts +++ b/packages/jest-types/src/Global.ts @@ -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 | void | undefined; +export type ConcurrentTestFn = () => Promise; export type BlockFn = () => void; export type BlockName = string; @@ -20,21 +21,24 @@ export type ArrayTable = Table | Row; export type TemplateTable = TemplateStringsArray; export type TemplateData = Array; export type EachTable = ArrayTable | TemplateTable; -export type EachTestFn = ( + +export type TestCallback = BlockFn | TestFn | ConcurrentTestFn; + +export type EachTestFn = ( ...args: Array -) => Promise | void | undefined; +) => ReturnType; // TODO: Get rid of this at some point type Jasmine = {_DEFAULT_TIMEOUT_INTERVAL?: number; addMatchers: Function}; -type Each = ( +type Each = ( table: EachTable, ...taggedTemplateData: Array -) => (title: string, test: EachTestFn, timeout?: number) => void; +) => (title: string, test: EachTestFn, timeout?: number) => void; export interface ItBase { (testName: TestName, fn: TestFn, timeout?: number): void; - each: Each; + each: Each; } export interface It extends ItBase { @@ -44,7 +48,8 @@ export interface It extends ItBase { } export interface ItConcurrentBase { - (testName: string, testFn: () => Promise, timeout?: number): void; + (testName: string, testFn: ConcurrentTestFn, timeout?: number): void; + each: Each; } export interface ItConcurrentExtended extends ItConcurrentBase { @@ -58,7 +63,7 @@ export interface ItConcurrent extends It { export interface DescribeBase { (blockName: BlockName, blockFn: BlockFn): void; - each: Each; + each: Each; } export interface Describe extends DescribeBase {