UNPKG

@tapjs/reporter

Version:

Pretty test output reporters for tap

89 lines 3.87 kB
// Syntax-highlighted source code tag import { parseStack } from '@tapjs/stack'; import { highlightFileSync } from 'prismjs-terminal'; import chalk from 'chalk'; import { Box, Text } from 'ink'; import React from 'react'; import stringLength from 'string-length'; /** * Pass in a test result.diag that has a source and callsite, * and it'll return a prettied up source line with the callsite * highlighted */ export const Source = ({ source, at, errorOrigin, stack, location, isErrorOrigin = false, }) => { if (errorOrigin && typeof errorOrigin === 'object') { return (React.createElement(React.Fragment, null, React.createElement(Source, { source: source, at: at }), React.createElement(Source, { ...errorOrigin, isErrorOrigin: true }))); } if (location && !stack) { return (React.createElement(Source, { source, at, errorOrigin, stack: location, isErrorOrigin })); } if (stack && !at) { if (location) { return (React.createElement(React.Fragment, null, React.createElement(Source, { stack: location }), React.createElement(Source, { stack: stack, isErrorOrigin: true }))); } const parsed = parseStack(stack); for (const p of parsed) { if (p.fileName) { at = p; break; } } } if (at && at.lineNumber && at.columnNumber && at.fileName) { try { const lines = highlightFileSync(at.fileName, { lineNumbers: true, theme: 'moria', padding: 0, /* c8 ignore start */ maxWidth: process.stdout.columns && process.stdout.columns - 5, /* c8 ignore stop */ }).split('\n'); const lastLine = lines[lines.length - 1]; if (lastLine && stringLength(lastLine) === 0) lines.pop(); const ctx = 4; const startLine = Math.max(at.lineNumber - ctx, 0); const endLine = Math.min(at.lineNumber + ctx, lines.length); const numLen = at.lineNumber.toString().length; const maxNumLen = lines.length.toString().length; const excess = maxNumLen - numLen; const atLine = lines[at.lineNumber - 1]; const before = lines.slice(startLine, at.lineNumber - 1); const after = lines.slice(at.lineNumber, endLine); const len = Math.min(...before.map(l => stringLength(l))); const msg = (isErrorOrigin ? 'error origin: ' : '') + at.fileName; const title = chalk.bgAnsi256(234).dim(msg.padEnd(len)); const caret = (at.columnNumber && at.columnNumber < stringLength(atLine) && at.columnNumber > 0) ? chalk.ansi256(252).bgAnsi256(234)(chalk.red(' '.repeat(excess) + '━'.repeat(numLen + at.columnNumber) + chalk.bold('┛') + ' '.repeat(len - (numLen + at.columnNumber) - 1 - excess))) : ''; const context = [title]; if (!caret) { context.push(...before.map(b => ' ' + b), chalk.bold.red('▶') + atLine, ...after.map(l => ' ' + l)); } else { context.push(...before, atLine, caret, ...after); } return (React.createElement(Box, { flexDirection: "column", paddingTop: isErrorOrigin ? 1 : 0 }, context.map((l, key) => (React.createElement(Text, { key: key }, l))))); } catch { } } return source ? React.createElement(Box, null, React.createElement(Text, null, source)) : React.createElement(React.Fragment, null); }; //# sourceMappingURL=source.js.map