95 lines
2.3 KiB
JavaScript
95 lines
2.3 KiB
JavaScript
'use strict';
|
|
const path = require('path');
|
|
const cleanYamlObject = require('clean-yaml-object');
|
|
const StackUtils = require('stack-utils');
|
|
const assert = require('./assert');
|
|
const beautifyStack = require('./beautify-stack');
|
|
const extractStack = require('./extract-stack');
|
|
|
|
function isAvaAssertionError(source) {
|
|
return source instanceof assert.AssertionError;
|
|
}
|
|
|
|
function filter(propertyName, isRoot) {
|
|
return !isRoot || (propertyName !== 'message' && propertyName !== 'name' && propertyName !== 'stack');
|
|
}
|
|
|
|
const stackUtils = new StackUtils();
|
|
function extractSource(stack) {
|
|
if (!stack) {
|
|
return null;
|
|
}
|
|
|
|
const firstStackLine = extractStack(stack).split('\n')[0];
|
|
return stackUtils.parseLine(firstStackLine);
|
|
}
|
|
function buildSource(source) {
|
|
if (!source) {
|
|
return null;
|
|
}
|
|
|
|
// Assume the CWD is the project directory. This holds since this function
|
|
// is only called in test workers, which are created with their working
|
|
// directory set to the project directory.
|
|
const projectDir = process.cwd();
|
|
|
|
const file = path.resolve(projectDir, source.file.trim());
|
|
const rel = path.relative(projectDir, file);
|
|
|
|
const isWithinProject = rel.split(path.sep)[0] !== '..';
|
|
const isDependency = isWithinProject && path.dirname(rel).split(path.sep).indexOf('node_modules') > -1;
|
|
|
|
return {
|
|
isDependency,
|
|
isWithinProject,
|
|
file,
|
|
line: source.line
|
|
};
|
|
}
|
|
|
|
module.exports = error => {
|
|
const stack = typeof error.stack === 'string' ?
|
|
beautifyStack(error.stack) :
|
|
null;
|
|
|
|
const retval = {
|
|
avaAssertionError: isAvaAssertionError(error),
|
|
source: buildSource(extractSource(stack))
|
|
};
|
|
if (stack) {
|
|
retval.stack = stack;
|
|
}
|
|
|
|
if (retval.avaAssertionError) {
|
|
retval.improperUsage = error.improperUsage;
|
|
retval.message = error.message;
|
|
retval.name = error.name;
|
|
retval.statements = error.statements;
|
|
retval.values = error.values;
|
|
|
|
if (error.fixedSource) {
|
|
const source = buildSource(error.fixedSource);
|
|
if (source) {
|
|
retval.source = source;
|
|
}
|
|
}
|
|
|
|
if (error.assertion) {
|
|
retval.assertion = error.assertion;
|
|
}
|
|
if (error.operator) {
|
|
retval.operator = error.operator;
|
|
}
|
|
} else {
|
|
retval.object = cleanYamlObject(error, filter); // Cleanly copy non-standard properties
|
|
if (typeof error.message === 'string') {
|
|
retval.message = error.message;
|
|
}
|
|
if (typeof error.name === 'string') {
|
|
retval.name = error.name;
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
};
|