Skip to content

Commit

Permalink
feat: test.concurrent (only block-level)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChALkeR committed Jul 15, 2024
1 parent b0f6d71 commit 5f4feac
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
35 changes: 35 additions & 0 deletions __test__/jest/concurrent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

describe('concurrent', () => {
let i = 0
test.concurrent(async () => {
i++
await sleep(50)
expect(i).toBe(2)
await sleep(50)
i--
})
test.concurrent(async () => {
i++
await sleep(50)
expect(i).toBe(2)
await sleep(50)
i--
})

let j = 0
test.concurrent(async () => {
j++
await sleep(50)
expect(j).toBe(1)
await sleep(50)
j--
})
test.concurrent(async () => {
j++
await sleep(50)
expect(j).toBe(1)
await sleep(50)
j--
})
})
31 changes: 30 additions & 1 deletion src/jest.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const { getCallerLocation, installLocationInNextTest } = createCallerLocationHoo
expect.extend(matchers)

let defaultTimeout = jestConfig().testTimeout // overridable via jest.setTimeout()
const defaultConcurrency = jestConfig().maxConcurrency

function parseArgs(list, targs) {
if (!(Object.isFrozen(list) && list.length === targs.length + 1)) return list // template check
Expand Down Expand Up @@ -79,7 +80,33 @@ const makeEach =

const forceExit = process.execArgv.map((x) => x.replaceAll('_', '-')).includes('--test-force-exit')

const describe = (...args) => nodeDescribe(...args)
const inConcurrent = []
const concurrent = []
const describe = (...args) => {
const fn = args.pop()
const optionsConcurrent = args?.at(-1)?.concurrency > 1
if (optionsConcurrent) inConcurrent.push(fn)
const result = nodeDescribe(...args, async () => {
const res = fn()

// We do only block-level concurrency, not file-level
if (concurrent.length === 1) {
test(...concurrent[0])
concurrent.length = 0
} else if (concurrent.length > 0) {
const queue = [...concurrent]
concurrent.length = 0
describe('concurrent', { concurrency: defaultConcurrency }, () => {
for (const args of queue) test(...args)
})
}

return res
})
if (optionsConcurrent) inConcurrent.pop()
return result
}

const test = (name, fn, testTimeout) => {
const timeout = testTimeout ?? defaultTimeout
installLocationInNextTest(getCallerLocation())
Expand All @@ -99,6 +126,8 @@ Also, using expect.assertions() to ensure the planned number of assertions is be

describe.each = makeEach(describe)
test.each = makeEach(test)
test.concurrent = (...args) => (inConcurrent.length > 0 ? test(...args) : concurrent.push(args))
test.concurrent.each = makeEach(test.concurrent)
describe.skip = (...args) => nodeDescribe.skip(...args)
test.skip = (...args) => nodeTest.skip(...args)

Expand Down

0 comments on commit 5f4feac

Please sign in to comment.