I wrote some failing tests based tests I've had working for my stackinfo project. I'm blocked on using the new version of stacktrace.js until they're fixed, so I'd like to do as much as I can to get them fixed up.
it('should parse V8 Error.stack entries of various types', function () {
var stackFrames = unit.parse(CapturedExceptions.CHROME_38);
expect(stackFrames).toBeTruthy();
expect(stackFrames.length).toBe(10);
expect(stackFrames[0]).toMatchStackFrame(['Object.StackTrace$$get', undefined, 'http://localhost:8100/generatedBuild/stackinfo.umd.js', 3788, 23]);
expect(stackFrames[1]).toMatchStackFrame(['21.module.exports', undefined, "http://localhost:8100/generatedBuild/stackinfo.umd.js", 3923, 38]);
expect(stackFrames[2]).toMatchStackFrame([undefined, undefined, "http://localhost:8100/", 47, 13]);
expect(stackFrames[3]).toMatchStackFrame([undefined, undefined, "http://localhost:8100/test/moar.js", 12, 9]);
expect(stackFrames[4]).toMatchStackFrame(['x', undefined, 'http://localhost:8100/test/moar.js', 7, 5]);
expect(stackFrames[5]).toMatchStackFrame(['moar', undefined, 'http://localhost:8100/test/moar.js', 2, 5]);
expect(stackFrames[6]).toMatchStackFrame(['H', undefined, 'http://localhost:8100/', 46, 9]);
expect(stackFrames[7]).toMatchStackFrame([undefined, undefined, 'http://localhost:8100/', 41, 13]);
expect(stackFrames[8]).toMatchStackFrame(['Array.forEach', undefined, undefined, undefined, undefined]);
expect(stackFrames[9]).toMatchStackFrame(['G', undefined, 'http://localhost:8100/', 40, 14]);
});
it('should parse V8 Error.stack entries of other various types', function () {
var stackFrames = unit.parse(CapturedExceptions.CHROME_37);
expect(stackFrames).toBeTruthy();
expect(stackFrames.length).toBe(4);
expect(stackFrames[0]).toMatchStackFrame(['H', undefined, 'http://localhost:8100/', 47, 25]);
expect(stackFrames[1]).toMatchStackFrame(['ProtoObjectFactory.<anonymous>', undefined, "http://localhost:8001/git/frontend/test/allTestsFE.bundle.js", 1459, 20]);
expect(stackFrames[2]).toMatchStackFrame([undefined, undefined, "http://localhost:8001/git/frontend/test/allTestsFE.bundle.js", 79, 15]);
expect(stackFrames[3]).toMatchStackFrame(['Object.module.exports.test.TabBar.buttons.callback', undefined, "http://localhost:8001/git/frontend/test/allTestsFE.bundle.js", 1546, 9]);
});
it('should parse Firefox 35 Error.stack', function () {
var stackFrames = unit.parse(CapturedExceptions.FIREFOX_35);
expect(stackFrames).toBeTruthy();
expect(stackFrames.length).toBe(3);
expect(stackFrames[0]).toMatchStackFrame(['(?)()', undefined, "http://localhost:8100/test.web.bundle.js", 75, undefined]);
expect(stackFrames[1]).toMatchStackFrame(['module.exports/req.onreadystatechange', undefined, "http://localhost:8001/git/frontend/test/generated/allTestsFE.bundle.js", 5943, 1]);
expect(stackFrames[2]).toMatchStackFrame(['module.exports<.getSourceMapObject', undefined, "http://localhost:8001/git/frontend/test/generated/allTestsFE.bundle.js", 4970, 10]);
});
it('should parse another Firefox 35 Error.stack', function () {
var stackFrames = unit.parse(CapturedExceptions.FIREFOX_35_B);
expect(stackFrames).toBeTruthy();
expect(stackFrames.length).toBe(27);
expect(stackFrames[0]).toMatchStackFrame(['StackTrace$$get', undefined, "http://localhost:8100/generatedBuild/stackinfo.umd.js", 3788, 23]);
expect(stackFrames[1]).toMatchStackFrame(['[21]</module.exports', undefined, "", 3923, 27]);
expect(stackFrames[2]).toMatchStackFrame(['H', undefined, "", 47, 13]);
expect(stackFrames[3]).toMatchStackFrame(['gen', undefined, "", 12, 9]);
expect(stackFrames[4]).toMatchStackFrame(['x', undefined, "", 7, 5]);
expect(stackFrames[5]).toMatchStackFrame(['moar', undefined, "", 2, 5]);
expect(stackFrames[6]).toMatchStackFrame(['H', undefined, "", 46, 9]);
expect(stackFrames[7]).toMatchStackFrame(['G', undefined, "", 41, 13]);
expect(stackFrames[8]).toMatchStackFrame(['G', undefined, "", 40, 10]);
expect(stackFrames[9]).toMatchStackFrame(['F', undefined, "", 34, 21]);
expect(stackFrames[10]).toMatchStackFrame(['E.fn1', undefined, "", 27, 13]);
expect(stackFrames[11]).toMatchStackFrame(['D', undefined, "", 22, 9]);
expect(stackFrames[12]).toMatchStackFrame(['C', undefined, "", 18, 9]);
expect(stackFrames[13]).toMatchStackFrame(['B', undefined, "", 14, 9]);
expect(stackFrames[14]).toMatchStackFrame(['A', undefined, "", 10, 9]);
expect(stackFrames[15]).toMatchStackFrame(['unittest', undefined, "", 156, 13]);
expect(stackFrames[16]).toMatchStackFrame(['testGroup/runTest', undefined, "", 3746, 17]);
expect(stackFrames[17]).toMatchStackFrame(['[18]</module.exports<.runTestGroup', undefined, "", 3465, 9]);
expect(stackFrames[18]).toMatchStackFrame(['testGroup', undefined, "", 3752, 9]);
expect(stackFrames[19]).toMatchStackFrame(['[19]</module.exports/UnitTester.prototype.test', undefined, "", 3881, 17]);
expect(stackFrames[20]).toMatchStackFrame(['unittest', undefined, "", 153, 9]);
expect(stackFrames[21]).toMatchStackFrame(['testGroup/runTest', undefined, "", 3746, 17]);
expect(stackFrames[22]).toMatchStackFrame(['[18]</module.exports<.runTestGroup', undefined, "", 3465, 9]);
expect(stackFrames[23]).toMatchStackFrame(['testGroup', undefined, "", 3752, 9]);
expect(stackFrames[24]).toMatchStackFrame(['[19]</module.exports/UnitTester.prototype.test', undefined, "", 3881, 17]);
expect(stackFrames[25]).toMatchStackFrame(['runTest', undefined, "", 3649, 13]);
expect(stackFrames[26]).toMatchStackFrame(['[19]</module.exports/UnitTest</this.init/<', undefined, "", 3593, 17]);
});
it('should parse other IE 11 Error stacks', function () {
var stackFrames = unit.parse(CapturedExceptions.IE_11_C);
expect(stackFrames).toBeTruthy();
expect(stackFrames.length).toBe(2);
expect(stackFrames[0]).toMatchStackFrame(['{anonymous}()', undefined, "http://localhost:8100/", 47, 13]);
expect(stackFrames[1]).toMatchStackFrame(['x', undefined, "http://localhost:8100/test/moar.js", 7, 5]);
});
I can show you the code I'm using to parse these things if you want - they're done very differently from how you're doing it tho.
Btw I'd recommend that if you can't parse a line, instead of completely failing the whole parse, you include an object that contains the error or something. You're never going to be able to parse every kind of stack trace, especially since browsers may change their formats. This would allow the user to either use the original raw traceline, print some kind of error message just for that line, or do whatever kind of handling they like, without interrupting the rest of the operation. Otherwise you're gonna get a lot of cases where stacktrace.js tells users "can't get a stacktrace for you" when really you mean "I can't figure out everything about this particular line in the stacktrace".
I see that in some cases (for example, in parseFFOrSafari) you are clipping out some of the stack trace lines using filter. I really don't think this is the right thing to do - you're throwing away information that could be useful to the end user. Why throw it away? If you can't parse it, add a StackFrame that indicates you couldn't parse it. You should also put the raw line somewhere in the StackFrame so users can access that if they want / need to (say if stacktrace.js can't properly parse the line).