@tapjs/reporter
Version:
Pretty test output reporters for tap
89 lines • 3.87 kB
JavaScript
// 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