Skip to content

Commit 18251fc

Browse files
author
homyakov
committed
Tests optimized; Started rewriting guessFunction()
1 parent 6df59da commit 18251fc

File tree

2 files changed

+64
-51
lines changed

2 files changed

+64
-51
lines changed

stacktrace.js

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -311,43 +311,42 @@ printStackTrace.implementation.prototype = {
311311
var reStack = /\{anonymous\}\(.*\)@(\w+:\/\/([\-\w\.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/;
312312
var frame = stack[i], m = reStack.exec(frame);
313313
if (m) {
314-
var file = m[1], lineno = m[4]; //m[7] is character position in Chrome
314+
var file = m[1], lineno = m[4], charno = m[7] || 0; //m[7] is character position in Chrome
315315
if (file && this.isSameDomain(file) && lineno) {
316-
var functionName = this.guessFunctionName(file, lineno);
316+
var functionName = this.guessFunctionName(file, lineno, charno);
317317
stack[i] = frame.replace('{anonymous}', functionName);
318318
}
319319
}
320320
}
321321
return stack;
322322
},
323323

324-
guessFunctionName: function(url, lineNo) {
324+
guessFunctionName: function(url, lineNo, charNo) {
325325
var ret;
326326
try {
327-
ret = this.guessFunctionNameFromLines(lineNo, this.getSource(url));
327+
ret = this.guessFunctionNameFromLines(this.getSource(url), lineNo);
328328
} catch (e) {
329329
ret = 'getSource failed with url: ' + url + ', exception: ' + e.toString();
330330
}
331331
return ret;
332332
},
333333

334-
guessFunctionNameFromLines: function(lineNo, source) {
334+
guessFunctionNameFromLines: function(source, lineNo) {
335335
var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/;
336336
var reGuessFunction = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/;
337-
// Walk backwards from the first line in the function until we find the line which
338-
// matches the pattern above, which is the function definition
339-
var line = "", maxLines = 10;
337+
// Walk backwards in the source lines until we find
338+
// the line which matches one of the patterns above
339+
var line = "", maxLines = 10, m;
340340
for (var i = 0; i < maxLines; ++i) {
341341
line = source[lineNo - i] + line;
342342
if (line !== undefined) {
343-
var m = reGuessFunction.exec(line);
343+
m = reGuessFunction.exec(line);
344+
if (m && m[1]) {
345+
return m[1];
346+
}
347+
m = reFunctionArgNames.exec(line);
344348
if (m && m[1]) {
345349
return m[1];
346-
} else {
347-
m = reFunctionArgNames.exec(line);
348-
if (m && m[1]) {
349-
return m[1];
350-
}
351350
}
352351
}
353352
}

test/test-stacktrace.js

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,13 @@
129129

130130
test("function instrumentation", function() {
131131
expect(4);
132+
var p = printStackTrace.implementation.prototype;
132133
this.toInstrument = function() { equals(1, 1, 'called instrumented function'); };
133134
this.callback = function(stacktrace) { ok(typeof stacktrace !== 'undefined', 'called callback'); };
134-
printStackTrace.implementation.prototype.instrumentFunction(this, 'toInstrument', this.callback);
135+
p.instrumentFunction(this, 'toInstrument', this.callback);
135136
ok(this.toInstrument._instrumented, 'function instrumented');
136137
this.toInstrument();
137-
printStackTrace.implementation.prototype.deinstrumentFunction(this, 'toInstrument');
138+
p.deinstrumentFunction(this, 'toInstrument');
138139
ok(!this.toInstrument._instrumented, 'function deinstrumented');
139140
this.toInstrument = this.callback = null;
140141
});
@@ -189,31 +190,42 @@
189190
});
190191

191192
test("chrome", function() {
192-
var mode = printStackTrace.implementation.prototype.mode(UnitTest.fn.createGenericError());
193-
var e = [];
194-
e.push({ stack: 'ignored\n at f0 (file.js:132:3)\n at file.js:135:3\n at f1 (file.js:132:13)\n at file.js:135:23\n at Object.<anonymous> (file.js:137:9)\n at file.js:137:32 at process (file.js:594:22)'});
195-
if(mode == 'chrome') {
196-
function f0() {
197-
try {this.undef();} catch (exception) {
198-
e.push(exception);
199-
}
193+
var p = printStackTrace.implementation.prototype, e = [], ex;
194+
195+
var stack = "TypeError: Object [object DOMWindow] has no method 'undef'\n" +
196+
" at f0 (test/test-stacktrace.js:198:20)\n" +
197+
" at f1 (test/test-stacktrace.js:203:10)\n" +
198+
" at test/test-stacktrace.js:206:10\n" +
199+
" at Object.<anonymous> (test/test-stacktrace.js:208:6)\n" +
200+
" at Object.run (test/qunit.js:89:18)\n" +
201+
" at test/qunit.js:214:10\n" +
202+
" at process (test/qunit.js:783:23)\n" +
203+
" at test/qunit.js:383:5";
204+
e.push({ stack: stack}); // test saved Chrome stacktrace
205+
206+
function f0() {
207+
try {this.undef();} catch (exception) {
208+
ex = exception;
200209
}
201-
function f1(arg1, arg2) {
202-
f0();
203-
}
204-
var f2 = function() {
205-
f1(1, "abc");
206-
};
207-
f2();
208210
}
209-
expect(4 * e.length);
210-
for(var i = 0; i < e.length; i++) {
211-
var message = printStackTrace.implementation.prototype.chrome(e[i]);
212-
//equals(message.join("\n"), '', 'debug');
211+
function f1(arg1, arg2) {
212+
f0();
213+
}
214+
var f2 = function() {
215+
f1(1, "abc");
216+
};
217+
f2();
218+
if (p.mode(ex) == 'chrome') {e.push(ex);} // test native Chrome stacktrace
219+
220+
expect(3 * e.length);
221+
for (var i = 0; i < e.length; i++) {
222+
var message = p.chrome(e[i]);
223+
//equals(e[i].stack, '', 'original stack trace');
224+
//equals(message.join("\n"), '', 'processed stack trace');
213225
equals(message[0].indexOf('f0') >= 0, true, 'f0 is top of stack');
214226
equals(message[1].indexOf('f1') >= 0, true, 'f1 is second called function');
215227
equals(message[2].indexOf('anonymous') >= 0, true, 'f2 anonymous function called');
216-
equals(message[3].indexOf('unknown source'), -1, 'unknown source discarded');
228+
//equals(message[3].indexOf('unknown source'), -1, 'unknown source discarded');
217229
}
218230
});
219231

@@ -337,11 +349,12 @@
337349

338350
test("stringify", function() {
339351
expect(5);
340-
equals(printStackTrace.implementation.prototype.stringifyArguments(["a", 1, {}, function() {}, undefined]), '"a",1,#object,#function,undefined');
341-
equals(printStackTrace.implementation.prototype.stringifyArguments([0, 1, 2, 3]), '0,1,2,3');
342-
equals(printStackTrace.implementation.prototype.stringifyArguments([['a', null]]), '["a",null]');
343-
equals(printStackTrace.implementation.prototype.stringifyArguments([[2, 4, 6, 8, 10, 12, 14]]), '[2...14]');
344-
equals(printStackTrace.implementation.prototype.stringifyArguments([]), '');
352+
var p = printStackTrace.implementation.prototype;
353+
equals(p.stringifyArguments(["a", 1, {}, function() {}, undefined]), '"a",1,#object,#function,undefined');
354+
equals(p.stringifyArguments([0, 1, 2, 3]), '0,1,2,3');
355+
equals(p.stringifyArguments([['a', null]]), '["a",null]');
356+
equals(p.stringifyArguments([[2, 4, 6, 8, 10, 12, 14]]), '[2...14]');
357+
equals(p.stringifyArguments([]), '');
345358
});
346359

347360
test("isSameDomain", function() {
@@ -350,34 +363,35 @@
350363
});
351364

352365
test("guessFunctionNameFromLines", function() {
353-
expect(3);
354-
equals(printStackTrace.implementation.prototype.guessFunctionNameFromLines(2, ['var a = function() {', 'var b = 2;', '};']), 'a');
355-
equals(printStackTrace.implementation.prototype.guessFunctionNameFromLines(2, ['function a() {', 'var b = 2;', '};']), 'a');
356-
equals(printStackTrace.implementation.prototype.guessFunctionNameFromLines(2, ['var a = 1;', 'var b = 2;', 'var c = 3;']), '(?)');
366+
expect(5);
367+
var p = printStackTrace.implementation.prototype;
368+
equals(p.guessFunctionNameFromLines(['var a = function aa() {', 'var b = 2;', '};'], 2), 'a');
369+
equals(p.guessFunctionNameFromLines(['var a = function () {', 'var b = 2;', '};'], 2), 'a');
370+
equals(p.guessFunctionNameFromLines(['var a = function() {', 'var b = 2;', '};'], 2), 'a');
371+
equals(p.guessFunctionNameFromLines(['function a() {', 'var b = 2;', '};'], 2), 'a');
372+
equals(p.guessFunctionNameFromLines(['var a = 1;', 'var b = 2;', 'var c = 3;'], 2), '(?)');
357373
});
358374

359375
test("getSource cache miss", function() {
360376
expect(3);
361-
var p = new printStackTrace.implementation();
362-
var file = 'file:///test';
377+
var p = new printStackTrace.implementation(), file = 'file:///test', lines;
363378
p.ajax = function(fileArg, callback) {
364379
equals(fileArg, file, 'cache miss');
365380
return 'line0\nline1\n';
366381
};
367-
var lines = p.getSource(file);
382+
lines = p.getSource(file);
368383
equals(lines[0], 'line0');
369384
equals(lines[1], 'line1');
370385
});
371386

372387
test("getSource cache hit", function() {
373388
expect(2);
374-
var p = new printStackTrace.implementation();
375-
var file = 'file:///test';
389+
var p = new printStackTrace.implementation(), file = 'file:///test', lines;
376390
p.ajax = function(fileArg, callback) {
377391
ok(false, 'not called');
378392
};
379393
p.sourceCache[file] = ['line0', 'line1'];
380-
var lines = p.getSource(file);
394+
lines = p.getSource(file);
381395
equals(lines[0], 'line0');
382396
equals(lines[1], 'line1');
383397
});

0 commit comments

Comments
 (0)