From 09646f107b6e99a61da412270c8abe8c4fcd17de Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Fri, 29 Dec 2023 00:55:39 +0900 Subject: [PATCH] refactor(runner): organize code for `resolveFixtures` (#4716) --- packages/runner/src/fixture.ts | 68 ++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/packages/runner/src/fixture.ts b/packages/runner/src/fixture.ts index d0ec39152296..9faeb012e6aa 100644 --- a/packages/runner/src/fixture.ts +++ b/packages/runner/src/fixture.ts @@ -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() - 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(() => { @@ -128,6 +98,42 @@ export function withFixtures(fn: Function, testContext?: TestContext) { } } +async function resolveFixtureFunction( + fixtureFn: (context: unknown, useFn: (arg: unknown) => Promise) => Promise, + context: unknown, + cleanupFnArray: (() => (void | Promise))[], +): Promise { + // 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() + 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(), pendingFixtures: FixtureItem[] = []) { fixtures.forEach((fixture) => { if (pendingFixtures.includes(fixture))