jest-allure2-reporter
Version:
Idiomatic Jest reporter for Allure Framework
100 lines (86 loc) • 3.58 kB
text/typescript
import type {
AllureTestItemSourceLocation,
SourceCodePluginCustomizer,
} from 'jest-allure2-reporter';
import { extract, parseWithComments } from 'jest-docblock';
import { autoIndent, importFrom } from '../../utils';
import { detectJS } from '../common';
import { ASTHelper } from './ASTHelper';
export interface TypescriptPluginOptions {
enabled: boolean;
extractDocblock: boolean;
}
function resolveOptions(value: unknown): TypescriptPluginOptions {
if (typeof value === 'boolean') {
return { enabled: value, extractDocblock: value };
}
return {
enabled: true,
extractDocblock: false,
...(value as TypescriptPluginOptions | undefined),
};
}
export const typescript: SourceCodePluginCustomizer = async ({ globalConfig, $, value }) => {
const options = resolveOptions(value);
const ts = options.enabled
? await importFrom('typescript', globalConfig.rootDir).then(
(resolution) => resolution.exports,
() => null,
)
: null;
function canProcess(
location: AllureTestItemSourceLocation,
): location is Required<AllureTestItemSourceLocation> {
const { fileName, lineNumber, columnNumber } = location;
return Boolean(fileName && lineNumber && columnNumber && detectJS(fileName));
}
const helper = new ASTHelper(ts);
return {
name: 'typescript',
extractSourceCode(location, includeComments) {
return ts && canProcess(location)
? $.getFileNavigator(location.fileName).then((navigator) => {
if (!navigator) return;
if (!navigator.jump(location.lineNumber)) return;
const lineNumber = location.lineNumber;
const columnNumber = Math.min(location.columnNumber, navigator.readLine().length);
const ast =
helper.getAST(location.fileName) ||
helper.parseAST(location.fileName, navigator.getContent());
const expression = helper.findNodeInAST(ast, lineNumber, columnNumber);
const codeStart = includeComments ? expression.getFullStart() : expression.getStart();
const code = autoIndent(ast.text.slice(codeStart, expression.getEnd()).trim());
navigator.jumpToPosition(codeStart);
const [startLine] = navigator.getPosition();
navigator.jumpToPosition(expression.getEnd());
const [endLine] = navigator.getPosition();
return {
code,
language: detectJS(location.fileName),
fileName: location.fileName,
startLine,
endLine,
};
})
: undefined;
},
extractDocblock(context) {
return ts && options.extractDocblock && canProcess(context)
? $.getFileNavigator(context.fileName).then((navigator) => {
if (!navigator) return;
if (!navigator.jump(context.lineNumber)) return;
const lineNumber = context.lineNumber;
const columnNumber = Math.min(context.columnNumber, navigator.readLine().length);
const ast =
helper.getAST(context.fileName) ||
helper.parseAST(context.fileName, navigator.getContent());
const expression = helper.findNodeInAST(ast, lineNumber, columnNumber);
const fullStart = expression.getFullStart();
const start = expression.getStart();
const docblock = extract(ast.text.slice(fullStart, start).trim());
return docblock ? parseWithComments(docblock) : undefined;
})
: undefined;
},
};
};