From dd8c5f2415d6fefc360e2787ae7bc5f73f6c4243 Mon Sep 17 00:00:00 2001 From: Hugo Wood Date: Tue, 12 Jul 2016 11:33:36 +0200 Subject: [PATCH] Fix Windows path support in error messages Supersede #221. Fix #220. Generally makes tape support more kinds of stacktrace formats. --- lib/test.js | 34 ++++++++++------------------------ test/circular-things.js | 1 + test/deep-equal-failure.js | 21 +++++++++++++++------ test/double_end.js | 1 + test/stackTrace.js | 7 +++++-- test/throws.js | 9 +++++++++ test/undef.js | 1 + 7 files changed, 42 insertions(+), 32 deletions(-) diff --git a/lib/test.js b/lib/test.js index 497c58a4..02c04ea2 100644 --- a/lib/test.js +++ b/lib/test.js @@ -217,36 +217,22 @@ Test.prototype._assert = function assert (ok, opts) { if (!ok) { var e = new Error('exception'); var err = (e.stack || '').split('\n'); - var dir = path.dirname(__dirname) + '/'; + var dir = path.dirname(__dirname) + path.sep; for (var i = 0; i < err.length; i++) { - var m = /^[^\s]*\s*\bat\s+(.+)/.exec(err[i]); - if (!m) { - continue; - } - - var s = m[1].split(/\s+/); - var filem = /(\/[^:\s]+:(\d+)(?::(\d+))?)/.exec(s[1]); - if (!filem) { - filem = /(\/[^:\s]+:(\d+)(?::(\d+))?)/.exec(s[2]); - - if (!filem) { - filem = /(\/[^:\s]+:(\d+)(?::(\d+))?)/.exec(s[3]); - - if (!filem) { - continue; - } - } - } + // regex taken from https://github.com/errwischt/stacktrace-parser/blob/fb58c13ba19dd9aa12b8480d8e9b938524953921/lib/stacktrace-parser.js#L13 + // and edited to have a matching group around everything after the 'at' + var traceRegex = /^\s*at ((?:((?:\[object object\])?\S+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*)$/ - if (filem[1].slice(0, dir.length) === dir) { + var m = traceRegex.exec(err[i]); + if (!m || m[3].slice(0, dir.length) === dir) { continue; } - res.functionName = s[0]; - res.file = filem[1]; - res.line = Number(filem[2]); - if (filem[3]) res.column = filem[3]; + res.functionName = m[2]; + res.file = m[3]; + res.line = Number(m[4]); + if (m[5]) res.column = m[5]; res.at = m[1]; break; diff --git a/test/circular-things.js b/test/circular-things.js index 590ae430..0ac6a227 100644 --- a/test/circular-things.js +++ b/test/circular-things.js @@ -18,6 +18,7 @@ tap.test('circular test', function (assert) { + ' {}\n' + ' actual: |-\n' + ' { circular: [Circular] }\n' + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + '\n' + '1..1\n' diff --git a/test/deep-equal-failure.js b/test/deep-equal-failure.js index 3f12b30e..c93f0146 100644 --- a/test/deep-equal-failure.js +++ b/test/deep-equal-failure.js @@ -23,6 +23,7 @@ tap.test('deep equal failure', function (assert) { + ' { b: 2 }\n' + ' actual: |-\n' + ' { a: 1 }\n' + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + '\n' + '1..1\n' @@ -34,7 +35,8 @@ tap.test('deep equal failure', function (assert) { assert.deepEqual(getDiag(body), { operator: 'equal', expected: '{ b: 2 }', - actual: '{ a: 1 }' + actual: '{ a: 1 }', + at: 'tryOnImmediate (timers.js:543:15)' }); })); @@ -46,7 +48,8 @@ tap.test('deep equal failure', function (assert) { diag: { operator: 'equal', expected: '{ b: 2 }', - actual: '{ a: 1 }' + actual: '{ a: 1 }', + at: 'tryOnImmediate (timers.js:543:15)' } }); }); @@ -76,6 +79,7 @@ tap.test('deep equal failure, depth 6, with option', function (assert) { + ' { a: { a1: { a2: { a3: { a4: { a5: 2 } } } } } }\n' + ' actual: |-\n' + ' { a: { a1: { a2: { a3: { a4: { a5: 1 } } } } } }\n' + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + '\n' + '1..1\n' @@ -87,7 +91,8 @@ tap.test('deep equal failure, depth 6, with option', function (assert) { assert.deepEqual(getDiag(body), { operator: 'equal', expected: '{ a: { a1: { a2: { a3: { a4: { a5: 2 } } } } } }', - actual: '{ a: { a1: { a2: { a3: { a4: { a5: 1 } } } } } }' + actual: '{ a: { a1: { a2: { a3: { a4: { a5: 1 } } } } } }', + at: 'tryOnImmediate (timers.js:543:15)' }); })); @@ -99,7 +104,8 @@ tap.test('deep equal failure, depth 6, with option', function (assert) { diag: { operator: 'equal', expected: '{ a: { a1: { a2: { a3: { a4: { a5: 2 } } } } } }', - actual: '{ a: { a1: { a2: { a3: { a4: { a5: 1 } } } } } }' + actual: '{ a: { a1: { a2: { a3: { a4: { a5: 1 } } } } } }', + at: 'tryOnImmediate (timers.js:543:15)' } }); }); @@ -129,6 +135,7 @@ tap.test('deep equal failure, depth 6, without option', function (assert) { + ' { a: { a1: { a2: { a3: { a4: [Object] } } } } }\n' + ' actual: |-\n' + ' { a: { a1: { a2: { a3: { a4: [Object] } } } } }\n' + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + '\n' + '1..1\n' @@ -140,7 +147,8 @@ tap.test('deep equal failure, depth 6, without option', function (assert) { assert.deepEqual(getDiag(body), { operator: 'equal', expected: '{ a: { a1: { a2: { a3: { a4: [Object] } } } } }', - actual: '{ a: { a1: { a2: { a3: { a4: [Object] } } } } }' + actual: '{ a: { a1: { a2: { a3: { a4: [Object] } } } } }', + at: 'tryOnImmediate (timers.js:543:15)' }); })); @@ -152,7 +160,8 @@ tap.test('deep equal failure, depth 6, without option', function (assert) { diag: { operator: 'equal', expected: '{ a: { a1: { a2: { a3: { a4: [Object] } } } } }', - actual: '{ a: { a1: { a2: { a3: { a4: [Object] } } } } }' + actual: '{ a: { a1: { a2: { a3: { a4: [Object] } } } } }', + at: 'tryOnImmediate (timers.js:543:15)' } }); }); diff --git a/test/double_end.js b/test/double_end.js index c405d45e..98717d2f 100644 --- a/test/double_end.js +++ b/test/double_end.js @@ -16,6 +16,7 @@ test(function (t) { 'not ok 2 .end() called twice', ' ---', ' operator: fail', + ' at: tryOnTimeout (timers.js:224:11)', ' ...', '', '1..2', diff --git a/test/stackTrace.js b/test/stackTrace.js index bde1bc50..c8060c1e 100644 --- a/test/stackTrace.js +++ b/test/stackTrace.js @@ -21,7 +21,8 @@ tap.test('preserves stack trace with newlines', function (tt) { stack: stackTrace, operator: 'error', expected: 'undefined', - actual: '[Error: Preserve stack]' + actual: '[Error: Preserve stack]', + at: 'tryOnImmediate (timers.js:543:15)' } }); }); @@ -39,6 +40,7 @@ tap.test('preserves stack trace with newlines', function (tt) { + ' undefined\n' + ' actual: |-\n' + ' [Error: Preserve stack]\n' + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' stack: |-\n' + ' foo\n' + ' bar\n' @@ -54,7 +56,8 @@ tap.test('preserves stack trace with newlines', function (tt) { stack: stackTrace, operator: 'error', expected: 'undefined', - actual: '[Error: Preserve stack]' + actual: '[Error: Preserve stack]', + at: 'tryOnImmediate (timers.js:543:15)' }); })); diff --git a/test/throws.js b/test/throws.js index 44ce1382..8ca86534 100644 --- a/test/throws.js +++ b/test/throws.js @@ -48,6 +48,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage() + "] message: '" + getNonFunctionMessage() + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + 'not ok 2 should throw\n' + ' ---\n' @@ -56,6 +57,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(null) + "] message: '" + getNonFunctionMessage(null) + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + 'not ok 3 should throw\n' + ' ---\n' @@ -64,6 +66,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(true) + "] message: '" + getNonFunctionMessage(true) + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + 'not ok 4 should throw\n' + ' ---\n' @@ -72,6 +75,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(false) + "] message: '" + getNonFunctionMessage(false) + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + 'not ok 5 should throw\n' + ' ---\n' @@ -80,6 +84,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage('abc') + "] message: '" + getNonFunctionMessage('abc') + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + 'not ok 6 should throw\n' + ' ---\n' @@ -88,6 +93,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(/a/g) + "] message: '" + getNonFunctionMessage(/a/g) + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + 'not ok 7 should throw\n' + ' ---\n' @@ -96,6 +102,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage([]) + "] message: '" + getNonFunctionMessage([]) + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + 'not ok 8 should throw\n' + ' ---\n' @@ -104,6 +111,7 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage({}) + "] message: '" + getNonFunctionMessage({}) + "' }\n" + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + '# function\n' + 'not ok 9 should throw\n' @@ -111,6 +119,7 @@ tap.test('failures', function (tt) { + ' operator: throws\n' + ' expected: undefined\n' + ' actual: undefined\n' + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n\n' + '1..9\n' + '# tests 9\n' diff --git a/test/undef.js b/test/undef.js index d3ae8d40..899e11a0 100644 --- a/test/undef.js +++ b/test/undef.js @@ -18,6 +18,7 @@ tap.test('array test', function (tt) { + ' { beep: undefined }\n' + ' actual: |-\n' + ' {}\n' + + ' at: tryOnImmediate (timers.js:543:15)\n' + ' ...\n' + '\n' + '1..1\n'