Skip to content

Commit

Permalink
[Fix] Update RegExp for matching stack frames to handle Promise/then …
Browse files Browse the repository at this point in the history
…scenario (#516)

Fixes #515
  • Loading branch information
DavidAnson authored and ljharb committed May 19, 2020
1 parent 33712e2 commit 751e592
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 12 deletions.
8 changes: 4 additions & 4 deletions lib/test.js
Expand Up @@ -236,8 +236,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)
Expand Down Expand Up @@ -267,9 +267,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);

Expand Down
2 changes: 1 addition & 1 deletion test/anonymous-fn.js
Expand Up @@ -18,7 +18,7 @@ tap.test('inside anonymous functions', function (tt) {
'not ok 1 fail',
' ---',
' operator: fail',
' at: Test.<anonymous> ($TEST/anonymous-fn/test-wrapper.js:$LINE:$COL)',
' at: <anonymous> ($TEST/anonymous-fn.js:$LINE:$COL)',
' stack: |-',
' Error: fail',
' [... stack stripped ...]',
Expand Down
2 changes: 1 addition & 1 deletion test/exit.js
Expand Up @@ -52,7 +52,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.<anonymous> ($TEST/exit/fail.js:$LINE:$COL)',
' at: <anonymous> ($TEST/exit/fail.js:$LINE:$COL)',
' stack: |-',
' Error: should be equivalent',
' [... stack stripped ...]',
Expand Down
2 changes: 1 addition & 1 deletion test/fail.js
Expand Up @@ -22,7 +22,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.<anonymous> ($TEST/fail.js:$LINE:$COL)',
' at: <anonymous> ($TEST/fail.js:$LINE:$COL)',
' stack: |-',
' Error: should be equivalent',
' [... stack stripped ...]',
Expand Down
68 changes: 64 additions & 4 deletions test/stackTrace.js
Expand Up @@ -68,15 +68,18 @@ 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();

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);
});
};

Expand All @@ -86,15 +89,18 @@ 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();

test._results._watch = function (t) {
t.on('result', function (res) {
tt.equal('Test.<anonymous>', res.functionName);
tt.match(res.file, /stackTrace.js/i);
tt.ok(Number(res.line) > 0);
tt.ok(Number(res.column) > 0);
});
};

Expand All @@ -104,6 +110,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('<anonymous>', 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);

Expand Down
2 changes: 1 addition & 1 deletion test/too_many.js
Expand Up @@ -22,7 +22,7 @@ tap.test('array test', function (tt) {
' operator: fail',
' expected: 3',
' actual: 4',
' at: Test.<anonymous> ($TEST/too_many.js:$LINE:$COL)',
' at: <anonymous> ($TEST/too_many.js:$LINE:$COL)',
' stack: |-',
' Error: plan != count',
' [... stack stripped ...]',
Expand Down

0 comments on commit 751e592

Please sign in to comment.