var expect = require('expect.js'), StackTraceParser = require('../lib/stacktrace-parser'); describe('StackTraceParser', function() { var data = { 'Chrome & Chrome Mobile & Opera': [ { from: "Error: with timeout\n at http://errwischt.com/stack_traces/test:76:15\n at wrapped (http://errwischt.com/bandage.js:51:25)", to: [ { file: 'http://errwischt.com/stack_traces/test', methodName: '', lineNumber: 76, column: 15 }, { file: 'http://errwischt.com/bandage.js', methodName: 'wrapped', lineNumber: 51, column: 25 } ] }, { from: "Error: with timeout and named func\n at timeoutWithName (http://errwischt.com/stack_traces/test:83:15)\n at wrapped (http://errwischt.com/bandage.js:51:25)", to: [ { file: 'http://errwischt.com/stack_traces/test', methodName: 'timeoutWithName', lineNumber: 83, column: 15 }, { file: 'http://errwischt.com/bandage.js', methodName: 'wrapped', lineNumber: 51, column: 25 } ] }, { from: "TypeError: Object # has no method 'objectBreakDown'\n at HTMLDocument. (http://errwischt.com/stack_traces/test:91:19)\n at l (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:24882)\n at Object.c.fireWith [as resolveWith] (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:25702)\n at Function.x.extend.ready (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:2900)\n at HTMLDocument.S (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:553)", to: [ { file: 'http://errwischt.com/stack_traces/test', methodName: 'HTMLDocument.', lineNumber: 91, column: 19 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'l', lineNumber: 4, column: 24882 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'Object.c.fireWith [as resolveWith]', lineNumber: 4, column: 25702 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'Function.x.extend.ready', lineNumber: 4, column: 2900 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'HTMLDocument.S', lineNumber: 4, column: 553 } ] } ], 'Firefox': [ { from: "timeoutWithName@http://errwischt.com/stack_traces/test:83\nwrapped@http://errwischt.com/bandage.js:51", to: [ { file: 'http://errwischt.com/stack_traces/test', methodName: 'timeoutWithName', lineNumber: 83, column: null }, { file: 'http://errwischt.com/bandage.js', methodName: 'wrapped', lineNumber: 51, column: null } ] }, { from: "@http://errwischt.com/stack_traces/test:76\nwrapped@http://errwischt.com/bandage.js:51", to: [ { file: 'http://errwischt.com/stack_traces/test', methodName: '', lineNumber: 76, column: null }, { file: 'http://errwischt.com/bandage.js', methodName: 'wrapped', lineNumber: 51, column: null } ] }, { from: "@http://errwischt.com/stack_traces/test:97\nx.Callbacks/l@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4\nx.Callbacks/c.fireWith@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4\n.ready@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4\nS@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4", to: [ { file: 'http://errwischt.com/stack_traces/test', methodName: '', lineNumber: 97, column: null }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'x.Callbacks/l', lineNumber: 4, column: null }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'x.Callbacks/c.fireWith', lineNumber: 4, column: null }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: '.ready', lineNumber: 4, column: null }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'S', lineNumber: 4, column: null } ] } ], 'Safari': [ { from: "timeoutWithName@http://bandage.local:8181/stack_traces/test:83:55\nwrapped@http://bandage.local:8181/bandage.js:51:30", to: [ { file: 'http://bandage.local:8181/stack_traces/test', methodName: 'timeoutWithName', lineNumber: 83, column: 55 }, { file: 'http://bandage.local:8181/bandage.js', methodName: 'wrapped', lineNumber: 51, column: 30 } ] }, { from: "http://bandage.local:8181/stack_traces/test:76:40\nwrapped@http://bandage.local:8181/bandage.js:51:30", to: [ { file: 'http://bandage.local:8181/stack_traces/test', methodName: '', lineNumber: 76, column: 40 }, { file: 'http://bandage.local:8181/bandage.js', methodName: 'wrapped', lineNumber: 51, column: 30 } ] }, { from: "http://bandage.local:8181/stack_traces/test:97:28\nl@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:24909\nfireWith@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:50440\nready@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:2933\nS@http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:580", to: [ { file: 'http://bandage.local:8181/stack_traces/test', methodName: '', lineNumber: 97, column: 28 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'l', lineNumber: 4, column: 24909 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'fireWith', lineNumber: 4, column: 50440 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'ready', lineNumber: 4, column: 2933 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'S', lineNumber: 4, column: 580 } ] } ], 'JavaScriptCore': [ { from: "timeoutWithName@stack_traces/test:83:55\nwrapped@bandage.js:51:30", to: [ { file: 'stack_traces/test', methodName: 'timeoutWithName', lineNumber: 83, column: 55 }, { file: 'bandage.js', methodName: 'wrapped', lineNumber: 51, column: 30 } ] }, { from: "timeoutWithName@stack_traces/test:83:55\nwrapped@42start-with-number.js:51:30", to: [ { file: 'stack_traces/test', methodName: 'timeoutWithName', lineNumber: 83, column: 55 }, { file: '42start-with-number.js', methodName: 'wrapped', lineNumber: 51, column: 30 } ] }, { from: "global code@stack_traces/test:83:55", to: [ { file: 'stack_traces/test', methodName: 'global code', lineNumber: 83, column: 55 } ] } ], 'Internet Explorer': [ { from: "Error: with timeout and named func\n at timeoutWithName (http://bandage.jaz-lounge.com/stack_traces/test:83:9)\n at wrapped (http://bandage.jaz-lounge.com/bandage.js:51:13)", to: [ { file: 'http://bandage.jaz-lounge.com/stack_traces/test', methodName: 'timeoutWithName', lineNumber: 83, column: 9 }, { file: 'http://bandage.jaz-lounge.com/bandage.js', methodName: 'wrapped', lineNumber: 51, column: 13 } ] }, { from: "Error: with timeout\n at Anonymous function (http://bandage.jaz-lounge.com/stack_traces/test:76:9)\n at wrapped (http://bandage.jaz-lounge.com/bandage.js:51:13)", to: [ { file: 'http://bandage.jaz-lounge.com/stack_traces/test', methodName: '', lineNumber: 76, column: 9 }, { file: 'http://bandage.jaz-lounge.com/bandage.js', methodName: 'wrapped', lineNumber: 51, column: 13 } ] }, { from: "TypeError: Object doesn't support property or method 'objectBreakDown'\n at Anonymous function (http://bandage.jaz-lounge.com/stack_traces/test:91:7)\n at l (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:24874)\n at fireWith (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:25638)\n at ready (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:2898)\n at S (http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js:4:551)", to: [ { file: 'http://bandage.jaz-lounge.com/stack_traces/test', methodName: '', lineNumber: 91, column: 7 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'l', lineNumber: 4, column: 24874 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'fireWith', lineNumber: 4, column: 25638 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'ready', lineNumber: 4, column: 2898 }, { file: 'http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', methodName: 'S', lineNumber: 4, column: 551 } ] } ], 'Node.js': [ { from: "ReferenceError: test is not defined\n at repl:1:2\n at REPLServer.self.eval (repl.js:110:21)\n at Interface. (repl.js:239:12)\n at Interface.EventEmitter.emit (events.js:95:17)\n at emitKey (readline.js:1095:12)", to: [ { file: 'repl', methodName: '', lineNumber: 1, column: 2 }, { file: 'repl.js', methodName: 'REPLServer.self.eval', lineNumber: 110, column: 21 }, { file: 'repl.js', methodName: 'Interface.', lineNumber: 239, column: 12 }, { file: 'events.js', methodName: 'Interface.EventEmitter.emit', lineNumber: 95, column: 17 }, { file: 'readline.js', methodName: 'emitKey', lineNumber: 1095, column: 12 } ] }, { from: "ReferenceError: breakDown is not defined\n at null._onTimeout (repl:1:25)\n at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)", to: [ { file: 'repl', methodName: 'null._onTimeout', lineNumber: 1, column: 25 }, { file: 'timers.js', methodName: 'Timer.listOnTimeout [as ontimeout]', lineNumber: 110, column: 15 } ] }, ], 'io.js': [ // io.js 2.4.0 { from: "ReferenceError: test is not defined\n at repl:1:1\n at REPLServer.defaultEval (repl.js:154:27)\n at bound (domain.js:254:14)\n at REPLServer.runBound [as eval] (domain.js:267:12)\n at REPLServer. (repl.js:308:12)\n at emitOne (events.js:77:13)\n at REPLServer.emit (events.js:169:7)\n at REPLServer.Interface._onLine (readline.js:210:10)\n at REPLServer.Interface._line (readline.js:549:8)\n at REPLServer.Interface._ttyWrite (readline.js:826:14)", to: [ { file: 'repl', methodName: '', lineNumber: 1, column: 1 }, { file: 'repl.js', methodName: 'REPLServer.defaultEval', lineNumber: 154, column: 27 }, { file: 'domain.js', methodName: 'bound', lineNumber: 254, column: 14 }, { file: 'domain.js', methodName: 'REPLServer.runBound [as eval]', lineNumber: 267, column: 12 }, { file: 'repl.js', methodName: 'REPLServer.', lineNumber: 308, column: 12 }, { file: 'events.js', methodName: 'emitOne', lineNumber: 77, column: 13 }, { file: 'events.js', methodName: 'REPLServer.emit', lineNumber: 169, column: 7 }, { file: 'readline.js', methodName: 'REPLServer.Interface._onLine', lineNumber: 210, column: 10 }, { file: 'readline.js', methodName: 'REPLServer.Interface._line', lineNumber: 549, column: 8 }, { file: 'readline.js', methodName: 'REPLServer.Interface._ttyWrite', lineNumber: 826, column: 14 } ] }, ] }; Object.keys(data).forEach(function(browser) { describe('can parse stack trace of ' + browser, function() { data[browser].forEach(function(browserData) { it(browserData.from, function() { var result = StackTraceParser.parse(browserData.from); expect(result.length).to.equal(browserData.to.length); expect(result).to.eql(browserData.to); }); }); }); }); });