Skip to content

Commit bf5a750

Browse files
committed
Handle spaces in path name for setting file, line no
1 parent 3c2087a commit bf5a750

File tree

1 file changed

+50
-18
lines changed

1 file changed

+50
-18
lines changed

Diff for: lib/test.js

+50-18
Original file line numberDiff line numberDiff line change
@@ -217,33 +217,65 @@ Test.prototype._assert = function assert (ok, opts) {
217217
var e = new Error('exception');
218218
var err = (e.stack || '').split('\n');
219219
var dir = __dirname + path.sep;
220-
220+
221221
for (var i = 0; i < err.length; i++) {
222-
var m = /^[^\s]*\s*\bat\s+(.+)/.exec(err[i]);
222+
/*
223+
Stack trace lines may resemble one of the following. We need
224+
to should correctly extract a function name (if any) and
225+
path / line no. for each line.
226+
227+
at myFunction (/path/to/file.js:123:45)
228+
at myFunction (/path/to/file.other-ext:123:45)
229+
at myFunction (/path to/file.js:123:45)
230+
at myFunction (C:\path\to\file.js:123:45)
231+
at myFunction (/path/to/file.js:123)
232+
at Test.<anonymous> (/path/to/file.js:123:45)
233+
at Test.bound [as run] (/path/to/file.js:123:45)
234+
at /path/to/file.js:123:45
235+
236+
Regex has three parts. First is non-capturing group for 'at '
237+
(plus anything preceding it).
238+
239+
/^(?:[^\s]*\s*\bat\s+)/
240+
241+
Second captures function call description (optional). This is
242+
not necessarily a valid JS function name, but just what the
243+
stack trace is using to represent a function call. It may look
244+
like `<anonymous>` or 'Test.bound [as run]'.
245+
246+
For our purposes, we assume that, if there is a function
247+
name, it's everything leading up to the first open
248+
parentheses (trimmed) before our pathname.
249+
250+
/(?:(.*)\s+\()?/
251+
252+
Last part captures file path plus line no (and optional
253+
column no).
254+
255+
/((?:\/|[A-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)/
256+
*/
257+
var re = /^(?:[^\s]*\s*\bat\s+)(?:(.*)\s+\()?((?:\/|[A-Z]:\\)[^:\)]+:(\d+)(?::(\d+))?)/
258+
var m = re.exec(err[i]);
259+
223260
if (!m) {
224261
continue;
225262
}
263+
264+
var callDescription = m[1] || '<anonymous>';
265+
var filePath = m[2];
226266

227-
var s = m[1].split(/\s+/);
228-
var filemRe = /((?:\/|[A-Z]:\\)[^:\s]+:(\d+)(?::(\d+))?)/;
229-
var filem;
230-
var sIndex;
231-
for (sIndex in s.slice(0, 4)) {
232-
filem = filemRe.exec(s[sIndex]);
233-
if (filem) break;
234-
}
235-
if (! filem) continue;
236-
237-
if (filem[1].slice(0, dir.length) === dir) {
267+
if (filePath.slice(0, dir.length) === dir) {
238268
continue;
239269
}
240270

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

246-
res.at = s.length > 1 ? m[1] : '<anonymous> (' + m[1] + ')';
278+
res.at = callDescription + ' (' + filePath + ')';
247279
break;
248280
}
249281
}

0 commit comments

Comments
 (0)