intern
Version:
Intern. A next-generation code testing stack for JavaScript.
170 lines • 7.17 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "diff"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var diff_1 = require("diff");
var ErrorFormatter = (function () {
function ErrorFormatter(executor) {
this.executor = executor;
}
ErrorFormatter.prototype.format = function (error, options) {
options = options || {};
var message;
if (typeof error !== 'string' && (error.message || error.stack)) {
message =
(error.name || 'Error') + ': ' + (error.message || 'Unknown error');
var stack = error.stack;
if (stack) {
if (stack.indexOf(message) === 0) {
stack = stack.slice(message.length);
}
else if (stack.indexOf(error.message) === 0) {
stack = stack.slice(String(error.message).length);
}
else if (stack.indexOf('Error\n') === 0) {
stack = stack.slice('Error'.length);
}
stack = this._normalizeStackTrace(stack);
}
var anyError = error;
if ((anyError.showDiff &&
(typeof anyError.actual === 'object' &&
typeof anyError.expected === 'object')) ||
(typeof anyError.actual === 'string' &&
typeof anyError.expected === 'string')) {
var diff = this._createDiff(anyError.actual, anyError.expected);
if (diff) {
message += '\n\n' + diff + '\n';
}
}
if (stack && /\S/.test(stack)) {
message += stack;
}
else if (anyError.fileName) {
message += '\n at ' + anyError.fileName;
if (anyError.lineNumber != null) {
message += ':' + anyError.lineNumber;
if (anyError.columnNumber != null) {
message += ':' + anyError.columnNumber;
}
}
message += '\nNo stack';
}
else {
message += '\nNo stack or location';
}
}
else {
message = String(error);
}
var space = options.space;
if (space != null) {
var lines = message.split('\n');
message = [lines[0]]
.concat(lines.slice(1).map(function (line) {
return space + line;
}))
.join('\n');
}
return message;
};
ErrorFormatter.prototype._getSource = function (tracepath) {
if (tracepath === '<anonymous>') {
return 'anonymous';
}
return tracepath;
};
ErrorFormatter.prototype._createDiff = function (actual, expected) {
var diff = diff_1.diffJson(actual, expected, {
undefinedReplacement: null
});
if (diff.length === 1 && !diff[0].added && !diff[0].removed) {
return '';
}
return diff.reduce(function (d, _a) {
var value = _a.value, added = _a.added, removed = _a.removed;
var lastChar = value[value.length - 1] === '\n' ? '\n' : '';
var lines = value.split('\n');
if (lastChar === '\n') {
lines.pop();
}
var prefix = '';
if (d.length > 0 && d[d.length - 1] !== '\n') {
prefix = '\n';
}
var char = added ? 'E' : removed ? 'A' : ' ';
return d + ("" + prefix + char + " ") + lines.join("\n" + char + " ") + lastChar;
}, '');
};
ErrorFormatter.prototype._formatLine = function (data) {
if (!data.func) {
return ' @ ' + this._getSource(data.source);
}
return ' at ' + data.func + ' @ ' + this._getSource(data.source);
};
ErrorFormatter.prototype._normalizeStackTrace = function (stack) {
var lines = stack.replace(/\s+$/, '').split('\n');
var firstLine = '';
while (/^\s*$/.test(lines[0])) {
lines = lines.slice(1);
}
var stackLines = /^\s*at /.test(lines[0])
? this._processChromeTrace(lines)
: this._processSafariTrace(lines);
if (this.executor.config.filterErrorStack) {
stackLines = stackLines.filter(function (line) {
return !(/\binternal\/process\//.test(line) ||
/\bnode_modules\/(?!digdug|leadfoot)/.test(line) ||
/\/__intern\//.test(line) ||
/\bModule\.(?:runMain|load)/.test(line) ||
/\bModule\._\w+/.test(line) ||
/\bbootstrap_node\.js/.test(line) ||
/<module.js[:>]/.test(line) ||
/<anonymous>$/.test(line) ||
/<native>$/.test(line));
});
}
return '\n' + firstLine + stackLines.join('\n');
};
ErrorFormatter.prototype._processChromeTrace = function (lines) {
var _this = this;
return lines.map(function (line) {
var match;
if ((match = /^\s*at (.+?) \(([^)]+)\)$/.exec(line))) {
return _this._formatLine({ func: match[1], source: match[2] });
}
else if ((match = /^\s*at (.*)/.exec(line))) {
return _this._formatLine({ source: match[1] });
}
else {
return line;
}
});
};
ErrorFormatter.prototype._processSafariTrace = function (lines) {
var _this = this;
return lines.map(function (line) {
var match;
if ((match = /^([^@]+)@(.*)/.exec(line))) {
return _this._formatLine({ func: match[1], source: match[2] });
}
else if ((match = /^(\w+:\/\/.*)/.exec(line))) {
return _this._formatLine({ source: match[1] });
}
else {
return line;
}
});
};
return ErrorFormatter;
}());
exports.default = ErrorFormatter;
});
//# sourceMappingURL=ErrorFormatter.js.map