UNPKG

@tapjs/reporter

Version:
97 lines 3.82 kB
import { Base } from '@tapjs/core'; import patchConsole from 'patch-console'; import { useState } from 'react'; import { listenCleanup } from '../listen-cleanup.js'; import { useCleanup } from './use-cleanup.js'; import { useSubtests } from './use-subtests.js'; const isBase = (o) => !!o && typeof o === 'object' && // only relevant when mocking the import in our own tests /* c8 ignore start */ (o instanceof Base || (typeof o.name === 'string' && !!o.parser && typeof o.parser === 'object')); /* c8 ignore stop */ const proceduralComment = /^# Subtest(?:\n?$|: )/; export const isTestLog = (p) => !!p && isBase(p.test); export const isConsoleLog = (p) => !!p && typeof p.text === 'string' && !isBase(p.test); export const isStdioLog = (p) => isConsoleLog(p) && typeof p.name === 'string' && typeof p.fd === 'number'; // prevent same-tick state updates from clobbering each other // by keeping a persistent copy of the logs for any given test. const LOGS = new Map(); export const useLog = (test, config, includeTests = false) => { const fromCache = LOGS.get(test) || []; LOGS.set(test, fromCache); const [logs, updateLogs] = useState(fromCache); const appendLog = (l) => { const logs = LOGS.get(test); const previous = logs[logs.length - 1]; l.previous = previous; const newLogs = logs.concat(l); LOGS.set(test, newLogs); updateLogs(newLogs); }; const tests = useSubtests(test, 'all'); const [parsersSeen, updateParsersSeen] = useState([]); useCleanup(cleanup => { cleanup.push(patchConsole((_stream, text) => { appendLog({ text }); })); for (const test of tests) { // stdout that isn't tap is "extra" cleanup.push(listenCleanup(test.parser, 'extra', (c) => { appendLog({ name: test.name, fd: 1, text: c, }); })); // the terse report does not show log lines for tests // completing, just the other stuff. if (includeTests) { cleanup.push(listenCleanup(test, 'complete', () => appendLog({ test }))); } const { proc } = test; if (proc) { cleanup.push(listenCleanup(proc.stderr, 'data', c => { appendLog({ name: test.name, fd: 2, text: String(c), }); })); } // treat comments a little like a stdio log if (config.get('comments')) { const onChild = (p) => { cleanup.push(listenCleanup(p, 'child', onChild)); if (!parsersSeen.includes(p)) { p.on('comment', c => { // just a precaution, we don't actually listen in time // to get these, because we're not hooking onto the parser // until it's already been emitted. /* c8 ignore start */ if (proceduralComment.test(c)) return; /* c8 ignore stop */ appendLog({ name: p.fullname, fd: 0, text: c, }); }); updateParsersSeen([...parsersSeen, p]); } }; onChild(test.parser); } } }, [logs, tests]); return logs; }; //# sourceMappingURL=use-log.js.map