Skip to content

Commit

Permalink
Handle spaces in path name for setting file, line no
Browse files Browse the repository at this point in the history
  • Loading branch information
fongandrew committed Sep 12, 2017
1 parent 3c2087a commit bf5a750
Showing 1 changed file with 50 additions and 18 deletions.
68 changes: 50 additions & 18 deletions lib/test.js
Expand Up @@ -217,33 +217,65 @@ Test.prototype._assert = function assert (ok, opts) {
var e = new Error('exception');
var err = (e.stack || '').split('\n');
var dir = __dirname + path.sep;

for (var i = 0; i < err.length; i++) {
var m = /^[^\s]*\s*\bat\s+(.+)/.exec(err[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.
at myFunction (/path/to/file.js:123:45)
at myFunction (/path/to/file.other-ext:123:45)
at myFunction (/path to/file.js:123:45)
at myFunction (C:\path\to\file.js:123:45)
at myFunction (/path/to/file.js:123)
at Test.<anonymous> (/path/to/file.js:123:45)
at Test.bound [as run] (/path/to/file.js:123:45)
at /path/to/file.js:123:45
Regex has three parts. First is non-capturing group for 'at '
(plus anything preceding it).
/^(?:[^\s]*\s*\bat\s+)/
Second captures function call description (optional). This is
not necessarily a valid JS function name, but just what the
stack trace is using to represent a function call. It may look
like `<anonymous>` or 'Test.bound [as run]'.
For our purposes, we assume that, if there is a function
name, it's everything leading up to the first open
parentheses (trimmed) before our pathname.
/(?:(.*)\s+\()?/
Last part captures file path plus line no (and optional
column no).
/((?:\/|[A-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)/
*/
var re = /^(?:[^\s]*\s*\bat\s+)(?:(.*)\s+\()?((?:\/|[A-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)/
var m = re.exec(err[i]);

if (!m) {
continue;
}

var callDescription = m[1] || '<anonymous>';
var filePath = m[2];

var s = m[1].split(/\s+/);
var filemRe = /((?:\/|[A-Z]:\\)[^:\s]+:(\d+)(?::(\d+))?)/;
var filem;
var sIndex;
for (sIndex in s.slice(0, 4)) {
filem = filemRe.exec(s[sIndex]);
if (filem) break;
}
if (! filem) continue;

if (filem[1].slice(0, dir.length) === dir) {
if (filePath.slice(0, dir.length) === dir) {
continue;
}

res.functionName = s.length > 1 ? s[0] : '<anonymous>';
res.file = filem[1];
res.line = Number(filem[2]);
if (filem[3]) res.column = filem[3];
// Function call description may not (just) be a function name.
// Try to extract function name by looking at first "word" only.
res.functionName = callDescription.split(/s+/)[0]
res.file = filePath;
res.line = Number(m[3]);
if (m[4]) res.column = Number(m[4]);

res.at = s.length > 1 ? m[1] : '<anonymous> (' + m[1] + ')';
res.at = callDescription + ' (' + filePath + ')';
break;
}
}
Expand Down

0 comments on commit bf5a750

Please sign in to comment.