Skip to content

Commit

Permalink
refactor(runner): organize code for resolveFixtures (#4716)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Dec 28, 2023
1 parent 578db5e commit 09646f1
Showing 1 changed file with 37 additions and 31 deletions.
68 changes: 37 additions & 31 deletions packages/runner/src/fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,37 +85,7 @@ export function withFixtures(fn: Function, testContext?: TestContext) {
if (fixtureValueMap.has(fixture))
continue

let resolvedValue: unknown
if (fixture.isFn) {
// wait for `use` call to extract fixture value
const useFnArgPromise = createDefer()
let isUseFnArgResolved = false
const fixtureReturn = fixture.value(context, async (useFnArg: unknown) => {
isUseFnArgResolved = true
useFnArgPromise.resolve(useFnArg)
// suspend fixture teardown until cleanup
const useReturnPromise = createDefer<void>()
cleanupFnArray.push(async () => {
// start teardown by resolving `use` Promise
useReturnPromise.resolve()
// wait for finishing teardown
await fixtureReturn
})
await useReturnPromise
}).catch((e: unknown) => {
// treat fixture setup error as test failure
if (!isUseFnArgResolved) {
useFnArgPromise.reject(e)
return
}
// otherwise re-throw to avoid silencing error during cleanup
throw e
})
resolvedValue = await useFnArgPromise
}
else {
resolvedValue = fixture.value
}
const resolvedValue = fixture.isFn ? await resolveFixtureFunction(fixture.value, context, cleanupFnArray) : fixture.value
context![fixture.prop] = resolvedValue
fixtureValueMap.set(fixture, resolvedValue)
cleanupFnArray.unshift(() => {
Expand All @@ -128,6 +98,42 @@ export function withFixtures(fn: Function, testContext?: TestContext) {
}
}

async function resolveFixtureFunction(
fixtureFn: (context: unknown, useFn: (arg: unknown) => Promise<void>) => Promise<void>,
context: unknown,
cleanupFnArray: (() => (void | Promise<void>))[],
): Promise<unknown> {
// wait for `use` call to extract fixture value
const useFnArgPromise = createDefer()
let isUseFnArgResolved = false

const fixtureReturn = fixtureFn(context, async (useFnArg: unknown) => {
// extract `use` argument
isUseFnArgResolved = true
useFnArgPromise.resolve(useFnArg)

// suspend fixture teardown by holding off `useReturnPromise` resolution until cleanup
const useReturnPromise = createDefer<void>()
cleanupFnArray.push(async () => {
// start teardown by resolving `use` Promise
useReturnPromise.resolve()
// wait for finishing teardown
await fixtureReturn
})
await useReturnPromise
}).catch((e: unknown) => {
// treat fixture setup error as test failure
if (!isUseFnArgResolved) {
useFnArgPromise.reject(e)
return
}
// otherwise re-throw to avoid silencing error during cleanup
throw e
})

return useFnArgPromise
}

function resolveDeps(fixtures: FixtureItem[], depSet = new Set<FixtureItem>(), pendingFixtures: FixtureItem[] = []) {
fixtures.forEach((fixture) => {
if (pendingFixtures.includes(fixture))
Expand Down

0 comments on commit 09646f1

Please sign in to comment.