UNPKG

@tapjs/reporter

Version:

Pretty test output reporters for tap

69 lines 2.84 kB
// @tapjs/stack makes stack traces a bit nicer, but we can do even better // with some colors and highlighting. import { CallSiteLike, parseStack } from '@tapjs/stack'; import chalk from 'chalk'; import { Box, Text } from 'ink'; import { isAbsolute } from 'path'; import React from 'react'; import { stringify } from 'tap-yaml'; import { HangingIndent } from './hanging-indent.js'; // only show generated callsite info if it's not ours // it's useful to know where to start throwing console.logs, but // if it's our own code, it's just noise. // Treat ./node_modules as "absolute" for this purpose, since deps // aren't "local" in the same sense, even though they live in cwd. const relativeOrMissing = (p) => !p || !(isAbsolute(p) || p.startsWith('node_modules')); const removeRelativeGenerated = (c) => { if (c && relativeOrMissing(c.fileName)) c.generated = undefined; }; // Only highlight *our* filenames, not those from deps or outside paths. // We use chalk.dim() directly here, because neighboring Text nodes get // squashed together. const highlightFilename = (s, f) => { if (!f || f === 'native' || f === '<anonymous>' || isAbsolute(f) || f.startsWith('..') || !s.includes(f)) { return React.createElement(Text, null, chalk.dim(s)); } const split = s.split(f); const last = split[split.length - 1]; split.pop(); return (React.createElement(Text, null, split .map(s => `${chalk.dim(s)}${chalk.yellowBright(f)}`) .join('') + chalk.dim(last))); }; const isUseful = (c) => !!c.lineNumber || !!c.columnNumber || !!c.fileName; export const Stack = ({ stack }) => { if (!stack?.trim()) return React.createElement(React.Fragment, null); const p = parseStack(stack); if (!p.length) return React.createElement(React.Fragment, null); const st = p .map(c => String(c)) .join('\n') .replace(/\n+$/, '') .split('\n') .map(l => { const c = new CallSiteLike(null, l); removeRelativeGenerated(c); removeRelativeGenerated(c.evalOrigin); if (!isUseful(c)) return undefined; return c; }) .filter(c => !!c) .map(c => highlightFilename(String(c), c?.evalOrigin ? c?.evalOrigin.fileName : c?.fileName)); // if nothing useful was found, just show the string const showRaw = !st.length && { stack }; return (React.createElement(Box, { flexDirection: "column" }, st.length ? st.map((line, key) => (React.createElement(HangingIndent, { key: key }, line))) : showRaw ? React.createElement(Text, { dimColor: true }, stringify(showRaw).trimEnd()) : /* c8 ignore next - impossible */ React.createElement(React.Fragment, null))); }; //# sourceMappingURL=stack.js.map