@tapjs/reporter
Version:
Pretty test output reporters for tap
93 lines • 3.6 kB
JavaScript
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');
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));
cleanup.push(listenCleanup(p, '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,
});
}));
};
onChild(test.parser);
}
}
}, [logs, tests]);
return logs;
};
//# sourceMappingURL=use-log.js.map