From 4bf45c8be1e5615fde1bc6593f9404572dfa031b Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Wed, 1 Nov 2023 20:44:57 +0900 Subject: [PATCH 1/2] fix: catch errors in hooks --- src/create-test.ts | 20 +++++++++++++++----- tests/index.ts | 30 ++++++++++++++++++++++++------ tests/specs/hooks.ts | 18 +++++++++++++++--- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/create-test.ts b/src/create-test.ts index 6203cc4..15732df 100644 --- a/src/create-test.ts +++ b/src/create-test.ts @@ -74,15 +74,25 @@ const runTest = async (testMeta: TestMeta) => { process.exitCode = 1; for (const onTestFail of callbacks.onTestFail) { - await onTestFail(error as Error); + try { + await onTestFail(error as Error); + } catch (error) { + consoleError('[onTestFail]', testMeta.title); + consoleError(error); + } } } finally { - testMeta.endTime = Date.now(); - logTestResult(testMeta); - for (const onTestFinish of callbacks.onTestFinish) { - await onTestFinish(); + try { + await onTestFinish(); + } catch (error) { + consoleError('[onTestFinish]', testMeta.title); + consoleError(error); + } } + + testMeta.endTime = Date.now(); + logTestResult(testMeta); } }; diff --git a/tests/index.ts b/tests/index.ts index da12799..b863bdb 100644 --- a/tests/index.ts +++ b/tests/index.ts @@ -5,12 +5,20 @@ const expectMatchInOrder = ( stdout: string, expectedOrder: string[], ) => { - const matches = expectedOrder - .map(line => [line, stdout.indexOf(line)] as const) - .sort((lineA, lineB) => lineA[1] - lineB[1]) - .map(([line]) => line); - - expect(matches).toStrictEqual(expectedOrder); + let remainingStdout = stdout; + for (let i = 0; i < expectedOrder.length; i += 1) { + const previousElement = i > 0 ? expectedOrder[i - 1] : undefined; + const currentElement = expectedOrder[i]; + const index = remainingStdout.indexOf(currentElement); + if (index === -1) { + console.log({ + remainingStdout, + stdout, + }); + throw new Error(`Expected ${JSON.stringify(currentElement)} ${previousElement ? 'to be after ' + JSON.stringify(previousElement) : ''}`); + } + remainingStdout = remainingStdout.slice(index + currentElement.length); + } }; const env = { NODE_DISABLE_COLORS: '0' }; @@ -111,4 +119,14 @@ test('hooks', async () => { 'describe finish', 'test suite finish', ]); + expectMatchInOrder(testProcess.stderr, [ + 'Error: hello\n', + '✖ describe › hooks\n', + 'Error: hello\n', + '[onTestFail] describe › failing hooks\n', + 'Error: hello\n', + '[onTestFinish] describe › failing hooks\n', + 'Error: goodbye\n', + '✖ describe › failing hooks', + ]); }); diff --git a/tests/specs/hooks.ts b/tests/specs/hooks.ts index fd8da08..4a8cc1e 100644 --- a/tests/specs/hooks.ts +++ b/tests/specs/hooks.ts @@ -1,11 +1,11 @@ import { describe, testSuite } from '#manten'; -describe('describe', ({ test, onFinish, runTestSuite }) => { +describe('describe', async ({ test, onFinish, runTestSuite }) => { onFinish(() => { console.log('describe finish'); }); - test('hooks', ({ onTestFail, onTestFinish }) => { + await test('hooks', ({ onTestFail, onTestFinish }) => { console.log('test start'); onTestFail((error) => { console.log('test error', error.message); @@ -18,7 +18,19 @@ describe('describe', ({ test, onFinish, runTestSuite }) => { throw new Error('hello'); }); - runTestSuite(testSuite(({ describe, onFinish }) => { + await test('failing hooks', ({ onTestFail, onTestFinish }) => { + onTestFail((error) => { + throw error; + }); + + onTestFinish(() => { + throw new Error('goodbye'); + }); + + throw new Error('hello'); + }); + + await runTestSuite(testSuite(({ describe, onFinish }) => { console.log('test suite start'); onFinish(() => { From c52f37bdec4d5851585c184292aca46bfd0389d5 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Sun, 5 Nov 2023 22:05:34 +0900 Subject: [PATCH 2/2] wip --- src/create-test.ts | 52 ++++++++++++++++++++++++++-------------------- tests/index.ts | 4 ++-- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/create-test.ts b/src/create-test.ts index 15732df..959ae7b 100644 --- a/src/create-test.ts +++ b/src/create-test.ts @@ -42,24 +42,7 @@ const runTest = async (testMeta: TestMeta) => { }, }; - testMeta.startTime = Date.now(); - try { - if (timeout) { - const controller = { timeoutId: undefined }; - try { - await Promise.race([ - testFunction(api), - throwOnTimeout(timeout, controller), - ]); - } finally { - clearTimeout(controller.timeoutId); - } - } else { - await testFunction(api); - } - } catch (error) { - testMeta.error = error as Error; - + const handleError = async (error: Error) => { // Remove "jest assertion error" matcherResult object if ( error @@ -76,18 +59,41 @@ const runTest = async (testMeta: TestMeta) => { for (const onTestFail of callbacks.onTestFail) { try { await onTestFail(error as Error); - } catch (error) { + } catch (hookError) { consoleError('[onTestFail]', testMeta.title); - consoleError(error); + consoleError(hookError); + } + } + + return error; + }; + + testMeta.startTime = Date.now(); + try { + if (timeout) { + const controller = { timeoutId: undefined }; + try { + await Promise.race([ + testFunction(api), + throwOnTimeout(timeout, controller), + ]); + } finally { + clearTimeout(controller.timeoutId); } + } else { + await testFunction(api); } + } catch (error) { + testMeta.error = await handleError(error as Error); } finally { for (const onTestFinish of callbacks.onTestFinish) { try { await onTestFinish(); - } catch (error) { - consoleError('[onTestFinish]', testMeta.title); - consoleError(error); + } catch (_error) { + const error = await handleError(_error as Error); + if (!testMeta.error) { + testMeta.error = error; + } } } diff --git a/tests/index.ts b/tests/index.ts index b863bdb..2955ec3 100644 --- a/tests/index.ts +++ b/tests/index.ts @@ -15,7 +15,7 @@ const expectMatchInOrder = ( remainingStdout, stdout, }); - throw new Error(`Expected ${JSON.stringify(currentElement)} ${previousElement ? 'to be after ' + JSON.stringify(previousElement) : ''}`); + throw new Error(`Expected ${JSON.stringify(currentElement)} ${previousElement ? `to be after ${JSON.stringify(previousElement)}` : ''}`); } remainingStdout = remainingStdout.slice(index + currentElement.length); } @@ -125,8 +125,8 @@ test('hooks', async () => { 'Error: hello\n', '[onTestFail] describe › failing hooks\n', 'Error: hello\n', - '[onTestFinish] describe › failing hooks\n', 'Error: goodbye\n', + '[onTestFail] describe › failing hooks\n', '✖ describe › failing hooks', ]); });