From 470e43bbe802564a2e091d56e83dadf6481b5a3a Mon Sep 17 00:00:00 2001 From: David Anson Date: Mon, 18 May 2020 21:21:37 -0700 Subject: [PATCH] [Fix] Update RegExp for matching stack frames to handle Promise/then scenario Fixes #515 --- lib/test.js | 8 +++--- test/anonymous-fn.js | 2 +- test/exit.js | 2 +- test/fail.js | 2 +- test/stackTrace.js | 68 +++++++++++++++++++++++++++++++++++++++++--- test/too_many.js | 2 +- 6 files changed, 72 insertions(+), 12 deletions(-) diff --git a/lib/test.js b/lib/test.js index c72b65b7..9012dc84 100644 --- a/lib/test.js +++ b/lib/test.js @@ -268,8 +268,8 @@ Test.prototype._assert = function assert(ok, opts) { for (var i = 0; i < err.length; i++) { /* Stack trace lines may resemble one of the following. We need - to should correctly extract a function name (if any) and - path / line no. for each line. + to correctly extract a function name (if any) and path / line + number for each line. at myFunction (/path/to/file.js:123:45) at myFunction (/path/to/file.other-ext:123:45) @@ -299,9 +299,9 @@ Test.prototype._assert = function assert(ok, opts) { Last part captures file path plus line no (and optional column no). - /((?:\/|[a-zA-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)/ + /((?:\/|[a-zA-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)\)?/ */ - var re = /^(?:[^\s]*\s*\bat\s+)(?:(.*)\s+\()?((?:\/|[a-zA-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)\)$/; + var re = /^(?:[^\s]*\s*\bat\s+)(?:(.*)\s+\()?((?:\/|[a-zA-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)\)?$/; var lineWithTokens = err[i].replace(process.cwd(), '/\$CWD').replace(__dirname, '/\$TEST'); var m = re.exec(lineWithTokens); diff --git a/test/anonymous-fn.js b/test/anonymous-fn.js index 3473e99c..019241e6 100644 --- a/test/anonymous-fn.js +++ b/test/anonymous-fn.js @@ -20,7 +20,7 @@ tap.test('inside anonymous functions', function (tt) { 'not ok 1 fail', ' ---', ' operator: fail', - ' at: Test. ($TEST/anonymous-fn/test-wrapper.js:$LINE:$COL)', + ' at: ($TEST/anonymous-fn.js:$LINE:$COL)', ' stack: |-', ' Error: fail', ' [... stack stripped ...]', diff --git a/test/exit.js b/test/exit.js index 4e61ab74..098d76e9 100644 --- a/test/exit.js +++ b/test/exit.js @@ -54,7 +54,7 @@ tap.test('exit fail', function (t) { ' operator: deepEqual', ' expected: [ [ 1, 2, [ 3, 4444 ] ], [ 5, 6 ] ]', ' actual: [ [ 1, 2, [ 3, 4 ] ], [ 5, 6 ] ]', - ' at: Test. ($TEST/exit/fail.js:$LINE:$COL)', + ' at: ($TEST/exit/fail.js:$LINE:$COL)', ' stack: |-', ' Error: should be deeply equivalent', ' [... stack stripped ...]', diff --git a/test/fail.js b/test/fail.js index 6221b4c6..2296fed2 100644 --- a/test/fail.js +++ b/test/fail.js @@ -24,7 +24,7 @@ tap.test('array test', function (tt) { ' operator: deepEqual', ' expected: [ [ 1, 2, [ 3, 4444 ] ], [ 5, 6 ] ]', ' actual: [ [ 1, 2, [ 3, 4 ] ], [ 5, 6 ] ]', - ' at: Test. ($TEST/fail.js:$LINE:$COL)', + ' at: ($TEST/fail.js:$LINE:$COL)', ' stack: |-', ' Error: should be deeply equivalent', ' [... stack stripped ...]', diff --git a/test/stackTrace.js b/test/stackTrace.js index 5f3e1487..7906884f 100644 --- a/test/stackTrace.js +++ b/test/stackTrace.js @@ -62,8 +62,8 @@ tap.test('preserves stack trace with newlines', function (tt) { }); }); -tap.test('parses function name from original stack', function (tt) { - tt.plan(1); +tap.test('parses function info from original stack', function (tt) { + tt.plan(4); var test = tape.createHarness(); test.createStream(); @@ -71,6 +71,9 @@ tap.test('parses function name from original stack', function (tt) { test._results._watch = function (t) { t.on('result', function (res) { tt.equal('Test.testFunctionNameParsing', res.functionName); + tt.match(res.file, /stackTrace.js/i); + tt.ok(Number(res.line) > 0); + tt.ok(Number(res.column) > 0); }); }; @@ -80,8 +83,8 @@ tap.test('parses function name from original stack', function (tt) { }); }); -tap.test('parses function name from original stack for anonymous function', function (tt) { - tt.plan(1); +tap.test('parses function info from original stack for anonymous function', function (tt) { + tt.plan(4); var test = tape.createHarness(); test.createStream(); @@ -89,6 +92,9 @@ tap.test('parses function name from original stack for anonymous function', func test._results._watch = function (t) { t.on('result', function (res) { tt.equal('Test.', res.functionName); + tt.match(res.file, /stackTrace.js/i); + tt.ok(Number(res.line) > 0); + tt.ok(Number(res.column) > 0); }); }; @@ -98,6 +104,60 @@ tap.test('parses function name from original stack for anonymous function', func }); }); +if (typeof Promise === 'function' && typeof Promise.resolve === 'function') { + + tap.test('parses function info from original stack for Promise scenario', function (tt) { + tt.plan(4); + + var test = tape.createHarness(); + test.createStream(); + + test._results._watch = function (t) { + t.on('result', function (res) { + tt.equal('onfulfilled', res.functionName); + tt.match(res.file, /stackTrace.js/i); + tt.ok(Number(res.line) > 0); + tt.ok(Number(res.column) > 0); + }); + }; + + test('t.equal stack trace', function testFunctionNameParsing(t) { + new Promise(function (resolve) { + resolve(); + }).then(function onfulfilled() { + t.equal(true, false, 'true should be false'); + t.end(); + }); + }); + }); + + tap.test('parses function info from original stack for Promise scenario with anonymous function', function (tt) { + tt.plan(4); + + var test = tape.createHarness(); + test.createStream(); + + test._results._watch = function (t) { + t.on('result', function (res) { + tt.equal('', res.functionName); + tt.match(res.file, /stackTrace.js/i); + tt.ok(Number(res.line) > 0); + tt.ok(Number(res.column) > 0); + }); + }; + + test('t.equal stack trace', function testFunctionNameParsing(t) { + new Promise(function (resolve) { + resolve(); + }).then(function () { + t.equal(true, false, 'true should be false'); + t.end(); + }); + }); + }); + +} + tap.test('preserves stack trace for failed assertions', function (tt) { tt.plan(6); diff --git a/test/too_many.js b/test/too_many.js index dc47b7b2..3ff2d43b 100644 --- a/test/too_many.js +++ b/test/too_many.js @@ -24,7 +24,7 @@ tap.test('array test', function (tt) { ' operator: fail', ' expected: 3', ' actual: 4', - ' at: Test. ($TEST/too_many.js:$LINE:$COL)', + ' at: ($TEST/too_many.js:$LINE:$COL)', ' stack: |-', ' Error: plan != count', ' [... stack stripped ...]',