UNPKG

formaterrors

Version:

API that provides formatting and highlight options for errors and their stack trace

439 lines (389 loc) 18.9 kB
var assert = require("assert"); var loadModule = require("./testHelpers/moduleLoader.js").loadModule; var should = require("should"); var util = require("util"); var formatErrorsModule = loadModule("./lib/formatErrors.js"); var formatErrorsExports = formatErrorsModule.module.exports; exports.testStackRange = function (test) { try { throw new Error("an error"); } catch (error) { var formatted = formatErrorsExports.stackRange(error.stack, 0, 5); var lines = formatted.split('\n'); should.equal(6, lines.length); should.equal("Error: an error", lines[0]); lines[1].should.include("testFormatError"); formatted = formatErrorsExports.stackRange(error.stack, 1); lines = formatted.split('\n'); lines[1].should.not.include("testFormatError"); lines.length.should.be.above(5); lines[lines.length - 2].should.include("nodeunit"); var another = formatErrorsExports.stackRange(error.stack, 0, 200); another.should.equal(another); another.should.equal(error.stack); formatted = formatErrorsExports.stackRange(error.stack, 0, 1); lines = formatted.split('\n'); should.equal(2, lines.length); should.equal("Error: an error", lines[0]); lines[1].should.include("testFormatErrors"); test.done(); } }; exports.testMultiLineMessageStackRange = function (test) { try { throw new Error("a multi\nline\nerror\nmessage"); } catch (error) { var formatted = formatErrorsExports.stackRange(error.stack, 0, 5); var lines = formatted.split('\n'); should.equal(9, lines.length); should.equal("Error: a multi", lines[0]); should.equal("message", lines[3]); lines[4].should.include("testFormatError"); test.done(); } }; exports.testStackFilter = function (test) { try { throw new Error("an error"); } catch (error) { var filters = ["testFormatErrors", "nodeunit"]; var formatted = formatErrorsExports.stackFilter(error.stack, filters, true); var lines = formatted.split("\n"); lines[1].should.include("testFormatErrors"); for (var i = 2; i < lines.length - 1; i++) { lines[i].should.include("nodeunit"); } formatted.should.equal(error.stack); filters = ["testFormatErrors"]; formatted = formatErrorsExports.stackFilter(error.stack, filters, true); lines = formatted.split("\n"); lines[1].should.include("testFormatErrors"); lines.length.should.equal(3); var another = formatErrorsExports.stackFilter(error.stack, filters); another.should.equal(formatted); filters = ["testFormatErrors", "nodeunit"]; formatted = formatErrorsExports.stackFilter(error.stack, filters, false); lines = formatted.split("\n"); for (i = 1; i < lines.length - 1; i++) { lines[i].should.not.include("nodeunit"); lines[i].should.not.include("testFormatErrors"); } test.done(); } }; exports.testMultiLineMessageStackFilter = function (test) { try { throw new Error("a multi\nline\nerror\nmessage"); } catch (error) { var filters = ["testFormatErrors", "nodeunit"]; var formatted = formatErrorsExports.stackFilter(error.stack, filters, true); formatted.should.equal(error.stack); formatted = formatErrorsExports.stackFilter(error.stack, filters, false); formatted.should.not.equal(error.stack); var lines = formatted.split("\n"); for (var i = 0; i < lines.length; i++) { formatErrorsModule.isMessageLine(lines[i]).should.equal(true); } test.done(); } }; exports.testStackHighlight = function (test) { try { throw new Error("an error"); } catch (error) { var patterns = ["testFormatErrors", "nodeunit"]; var formatted = formatErrorsExports.stackHighlight(error.stack, patterns, formatErrorsExports.STYLES.RED); var lines = formatted.split("\n"); lines[0].should.not.include(formatErrorsExports.STYLES.RED); lines[0].should.not.include(formatErrorsExports.STYLES.NORMAL); lines[1].should.include("testFormatErrors"); lines[1].indexOf(formatErrorsExports.STYLES.RED).should.equal(0); lines[1].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[1].length - formatErrorsExports.STYLES.NORMAL.length); lines[1].should.not.include("undefined"); for (var i = 2; i < lines.length - 1; i++) { lines[i].should.not.include("undefined"); lines[i].should.include("nodeunit"); lines[i].indexOf(formatErrorsExports.STYLES.RED).should.equal(0); lines[i].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[i].length - formatErrorsExports.STYLES.NORMAL.length); } patterns = ["testFormatErrors"]; formatted = formatErrorsExports.stackHighlight(error.stack, patterns, [formatErrorsExports.STYLES.GREEN, formatErrorsExports.STYLES.BOLD]); lines = formatted.split("\n"); lines[0].should.not.include(formatErrorsExports.STYLES.GREEN); lines[0].should.not.include(formatErrorsExports.STYLES.BOLD); lines[0].should.not.include(formatErrorsExports.STYLES.NORMAL); lines[1].should.include("testFormatErrors"); lines[1].should.not.include("undefined"); lines[1].indexOf(formatErrorsExports.STYLES.GREEN).should.equal(0); lines[1].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(formatErrorsExports.STYLES.GREEN.length); lines[1].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[1].length - formatErrorsExports.STYLES.NORMAL.length); for (i = 2; i < lines.length - 1; i++) { lines[i].should.not.include("undefined"); lines[i].should.include("nodeunit"); lines[i].should.not.include(formatErrorsExports.STYLES.GREEN); lines[i].should.not.include(formatErrorsExports.STYLES.BOLD); lines[i].should.not.include(formatErrorsExports.STYLES.NORMAL); } test.done(); } }; exports.testMultiLineMessageStackHighlight = function (test) { try { throw new Error("a multi\nline\nerror\nmessage"); } catch (error) { var patterns = ["testFormatErrors", "nodeunit"]; var formatted = formatErrorsExports.stackHighlight(error.stack, patterns, formatErrorsExports.STYLES.RED); var lines = formatted.split("\n"); lines[0].should.not.include(formatErrorsExports.STYLES.RED); lines[0].should.not.include(formatErrorsExports.STYLES.NORMAL); lines[3].should.not.include(formatErrorsExports.STYLES.RED); lines[3].should.not.include(formatErrorsExports.STYLES.NORMAL); lines[4].should.include("testFormatErrors"); lines[4].indexOf(formatErrorsExports.STYLES.RED).should.equal(0); lines[4].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[4].length - formatErrorsExports.STYLES.NORMAL.length); lines[4].should.not.include("undefined"); for (var i = 5; i < lines.length - 1; i++) { lines[i].should.not.include("undefined"); lines[i].should.include("nodeunit"); lines[i].indexOf(formatErrorsExports.STYLES.RED).should.equal(0); lines[i].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[i].length - formatErrorsExports.STYLES.NORMAL.length); } test.done(); } }; exports.testStackFilterNoFilters = function (test) { try { throw new Error("an error"); } catch (error) { var formatted = formatErrorsExports.stackFilter(error.stack, null, true); var lines = formatted.split("\n"); lines.length.should.equal(2); formatted = formatErrorsExports.stackFilter(error.stack, null, false); lines = formatted.split("\n"); lines.length.should.be.above(10); formatted.should.equal(error.stack); test.done(); } }; exports.testStackFormatChaining = function (test) { try { var assertion = function() { false.should.equal(true); }; assertion(); } catch (error) { var formatted = formatErrorsExports.stackHighlight( formatErrorsExports.stackHighlight( formatErrorsExports.stackRange(error.stack, 2), ["testFormatErrors"], [formatErrorsExports.STYLES.BOLD], true ), ["Error:"], [formatErrorsExports.STYLES.BOLD, formatErrorsExports.STYLES.RED] ); var lines = formatted.split("\n"); lines[0].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); lines[0].indexOf(formatErrorsExports.STYLES.RED).should.equal(formatErrorsExports.STYLES.BOLD.length); lines[0].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[0].length - formatErrorsExports.STYLES.NORMAL.length); for (var i = 1; i < 2; i++) { lines[i].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); lines[i].should.not.include(formatErrorsExports.STYLES.RED); lines[i].should.not.include("should"); lines[i].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[i].length - formatErrorsExports.STYLES.NORMAL.length); } for (i = 3; i < lines.length; i++) { lines[i].should.not.include("should"); lines[i].should.not.include(formatErrorsExports.STYLES.BOLD); lines[i].should.not.include(formatErrorsExports.STYLES.RED); lines[i].should.not.include(formatErrorsExports.STYLES.NORMAL); } test.done(); } }; exports.testApplyHighlightStackFormat = function (test) { try { true.should.equal(false); } catch (error) { var formatted = formatErrorsExports.applyStackHighlights( error.stack, [formatErrorsExports.STYLES.BLUE, formatErrorsExports.STYLES.BOLD], [formatErrorsExports.STYLES.BOLD], ["testFormatErrors"] ); var lines = formatted.split("\n"); lines[2].should.include("testFormatErrors"); lines[2].should.not.include("undefined"); test.done(); } }; exports.testHighlightStackMessage = function (test) { try { true.should.equal(false); } catch (error) { var formatted = formatErrorsExports.highlightStackMessage(error.stack, [formatErrorsExports.STYLES.BLUE]); var lines = formatted.split("\n"); lines[0].indexOf(formatErrorsExports.STYLES.BLUE).should.equal(0); lines[0].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[0].length - formatErrorsExports.STYLES.NORMAL.length); formatted = formatErrorsExports.highlightStackMessage(error.stack, [formatErrorsExports.STYLES.CYAN, formatErrorsExports.STYLES.BOLD]); lines = formatted.split("\n"); lines[0].indexOf(formatErrorsExports.STYLES.CYAN).should.equal(0); lines[0].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(formatErrorsExports.STYLES.CYAN.length); lines[0].indexOf(formatErrorsExports.STYLES.NORMAL).should.equal(lines[0].length - formatErrorsExports.STYLES.NORMAL.length); for (var i = 1; i < lines.length; i++) { lines[i].should.not.include(formatErrorsExports.STYLES.CYAN); lines[i].should.not.include(formatErrorsExports.STYLES.BOLD); lines[i].should.not.include(formatErrorsExports.STYLES.NORMAL); } test.done(); } }; exports.testBoldMessageBoldModuleStack = function (test) { try { true.should.equal(false); } catch (error) { var formatted = formatErrorsExports.boldMessageBoldModuleStack(error.stack, "testFormatErrors"); var lines = formatted.split("\n"); lines[0].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); lines[1].should.not.include(formatErrorsExports.STYLES.BOLD); lines[2].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); lines[3].should.not.include(formatErrorsExports.STYLES.BOLD); test.done(); } }; exports.testBoldError = function (test) { try { true.should.equal(false); } catch (error) { var formatted = formatErrorsExports.boldError(error, "testFormatErrors"); var lines = formatted.stack.split("\n"); lines[0].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); lines[1].should.not.include(formatErrorsExports.STYLES.BOLD); lines[2].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); lines[3].should.not.include(formatErrorsExports.STYLES.BOLD); } try { true.should.equal(false); } catch (error) { var noModule = formatErrorsExports.boldError(error); var noModuleLines = noModule.stack.split("\n"); noModuleLines[0].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); noModuleLines[1].should.not.include(formatErrorsExports.STYLES.BOLD); noModuleLines[2].should.not.include(formatErrorsExports.STYLES.BOLD); } test.done(); }; exports.testStackLineType = function (test) { try { true.should.equal(false); } catch (error) { var lines = error.stack.split('\n'); formatErrorsModule.isStackLine(lines[0]).should.equal(false); formatErrorsModule.isMessageLine(lines[0]).should.equal(true); for (var i = 1; i < lines.length; i++) { formatErrorsModule.isStackLine(lines[i]).should.equal(true); formatErrorsModule.isMessageLine(lines[i]).should.equal(false); } test.done(); } }; exports.testEnhanceError = function (test) { assert.throws(function () { formatErrorsModule.enhanceError("hello"); }); assert.doesNotThrow(function () { formatErrorsModule.enhanceError(new Error("message")); }); test.done(); }; exports.testIsError = function (test) { formatErrorsModule.isError(new Error()).should.equal(true); formatErrorsModule.isError(7).should.equal(false); formatErrorsModule.isError("Error").should.equal(false); function EnhancedError() { } EnhancedError.prototype = new Error(); EnhancedError.prototype.constructor = EnhancedError; var e2 = new EnhancedError(); formatErrorsModule.isError(e2).should.equal(true); test.done(); }; exports.testGetMessages = function (test) { var messages = formatErrorsModule.getMessages(new Error("message")); messages[0].should.equal("Error: message"); messages = formatErrorsModule.getMessages(new Error("message\nnext line")); messages.length.should.equal(2); messages[0].should.equal("Error: message"); messages[1].should.equal("next line"); test.done(); }; exports.testStackFormatObject = function (test) { var format = ['typeName', 'functionName', 'methodName', 'fileName', 'lineNumber', 'columnNumber']; var sf = new formatErrorsExports.StackFormat(); sf.prefix.should.equal(" at"); sf.components.length.should.equal(6); var c = sf.components; format.join().should.equal(c.join()); test.done(); }; exports.testFormatStack = function (test) { var error = new Error("a message"); var formatted = formatErrorsExports.formatStack(error); var lines = formatted.stack.split("\n"); lines[0].should.equal("Error: a message"); lines[1].should.include("test/testFormatErrors.js"); lines[3].should.include("node_modules/nodeunit/lib/core.js:235:16"); lines[4].should.include("node_modules/nodeunit/lib/core.js:69:9)"); lines[10].should.include("node_modules/nodeunit/lib/types.js:146:17)"); var format = new formatErrorsExports.StackFormat(); format.prefix = " \u2192"; format.components = ["fileName", "lineNumber"]; formatted = formatErrorsExports.formatStack(error, format); lines = formatted.stack.split("\n"); lines[0].should.equal("Error: a message"); lines[1].indexOf(" → ").should.equal(0); lines[1].should.include("testFormatErrors.js"); lines[10].indexOf(" → ").should.equal(0); lines[10].should.include("node_modules/nodeunit/lib/types.js:146"); test.done(); }; exports.testHighlightError = function (test) { var theme = new formatErrorsExports.StackTheme(); var lines; theme.messageLineHighlights = [formatErrorsExports.STYLES.BOLD, formatErrorsExports.STYLES.RED]; theme.stackHighlights = [formatErrorsExports.STYLES.BOLD]; theme.stackHighlightPatterns = ["testFormatErrors"]; try { true.should.equal(false); } catch (error) { var err1 = formatErrorsExports.highlightError(error, theme); should.not.exist(err1.diff); lines = err1.stack.split("\n"); lines[0].indexOf(formatErrorsExports.STYLES.BOLD + formatErrorsExports.STYLES.RED).should.equal(0); lines[0].should.include("AssertionError: expected true to equal false"); lines[0].should.include(formatErrorsExports.STYLES.NORMAL); lines[2].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); lines[3].should.not.include(formatErrorsExports.STYLES.RED); lines[3].should.not.include(formatErrorsExports.STYLES.BOLD); lines[3].should.not.include(formatErrorsExports.STYLES.NORMAL); } try { assert.equal("I am the very model of a modern Major-General, I've information vegetable, animal, and mineral, I know the kings of England, and I quote the fights historical, From Marathon to Waterloo, in order categorical.", "I am the very model of a modern Major-General, I've information vegetable, and mineral, I know the kings of England, and I quote the fights historical, From Marathon to Waterloo, in order categorical."); } catch (error) { var err2 = formatErrorsExports.highlightError(error, theme); should.exist(err2.diff); lines = err2.stack.split("\n"); lines[0].indexOf(formatErrorsExports.STYLES.BOLD + formatErrorsExports.STYLES.RED).should.equal(0); lines[0].indexOf("AssertionError").should.equal(9); lines[0].should.include("I am the very model of a modern Major-General"); lines[1].should.equal("\u001b[1m\u001b[31mDifferences: 'actual': \"animal, \"\u001b[39m\u001b[22m"); lines[2].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); } try { assert.equal(true, false); } catch (error) { var err3 = formatErrorsExports.highlightError(error, theme); should.not.exist(err3.diff); lines = err3.stack.split("\n"); lines[0].should.include("AssertionError: "); lines[1].indexOf(formatErrorsExports.STYLES.BOLD).should.equal(0); } test.done(); };