From 5f6fb4f7e1271584cef49237622fb9db8aac7a8d Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Mon, 8 Mar 2010 21:30:21 -0800 Subject: [PATCH] Remove jasmine internals from stack traces, WIP. --- spec/suites/ExceptionsSpec.js | 42 +++++++++++++++++++++++++++++--- src/Block.js | 2 +- src/Matchers.js | 5 ++-- src/base.js | 45 ++++++++++++++++++++++++++--------- 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/spec/suites/ExceptionsSpec.js b/spec/suites/ExceptionsSpec.js index 5494b1c..e111cf1 100644 --- a/spec/suites/ExceptionsSpec.js +++ b/spec/suites/ExceptionsSpec.js @@ -73,7 +73,6 @@ describe('Exceptions:', function() { }); }); - var runner = env.currentRunner(); suite.execute(); fakeTimer.tick(2500); @@ -89,7 +88,7 @@ describe('Exceptions:', function() { expect(blockResults[0].message).toMatch(/fake error 1/); expect(specResults[1].passed()).toEqual(false); - var blockResults = specResults[1].getItems(); + blockResults = specResults[1].getItems(); expect(blockResults[0].passed()).toEqual(false); expect(blockResults[0].message).toMatch(/fake error 2/), expect(blockResults[1].passed()).toEqual(true); @@ -101,7 +100,44 @@ describe('Exceptions:', function() { expect(blockResults[0].message).toMatch(/fake error 3/); expect(specResults[4].passed()).toEqual(true); - }); + it("should remove jasmine internals from reported stack traces", function() { + var spec; + var suite = env.describe('Suite for handles exceptions', function () { + spec = env.it('should be a test that fails because it throws an exception', function() { + function someNamedFunction() { + this.expect(true).toEqual(false); + throw new Error('fake error 1'); + } + someNamedFunction.call(this); + }); + }); + + suite.execute(); + + var webKitRegex = /^ at .*?(new |\.)([^. ]*) \((.+:[0-9]+:[0-9]+)\)+$/; + var firefoxRegex = /^([^.(]*)\(.*\)@(.+:[0-9]+)$/; + + var stackLinks = spec.results().getItems()[0].stackTrace().split("\n"); + var stackInfos = []; + for (var i = 0; i < stackLinks.length; i++) { + + var match; + if (match = webKitRegex.exec(stackLinks[i])) { + stackInfos.push(match[2] + ": " + stackLinks[i]); + } else if (match = firefoxRegex.exec(stackLinks[i])) { + stackInfos.push(match[1]); + } else { + stackInfos.push(stackLinks[i]); + } + } + expect(stackInfos).toEqual([ + "Error: Expected true to equal false.", + "__jasmine_Matchers_matcherFn__", + "someNamedFunction", + "" + ]); + expect({a:1,b:2,c:3}).toEqual({d:4,e:5,f:6}); + }); }); \ No newline at end of file diff --git a/src/Block.js b/src/Block.js index 75964a1..21d0aac 100644 --- a/src/Block.js +++ b/src/Block.js @@ -12,7 +12,7 @@ jasmine.Block = function(env, func, spec) { this.spec = spec; }; -jasmine.Block.prototype.execute = function(onComplete) { +jasmine.Block.prototype.execute = function __jasmine_Block_prototype_execute__(onComplete) { try { this.func.apply(this.spec); } catch (e) { diff --git a/src/Matchers.js b/src/Matchers.js index 8219336..334dde2 100644 --- a/src/Matchers.js +++ b/src/Matchers.js @@ -45,7 +45,7 @@ jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { }; jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { + var wrapper = function __jasmine_Matchers_matcherFn__() { var matcherArgs = jasmine.util.argsToArray(arguments); var result = matcherFunction.apply(this, arguments); @@ -84,11 +84,12 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { this.spec.addMatcherResult(expectationResult); return result; }; + var fn = eval("(function __jasmine_Matchers_$" + matcherName + "$_Matcher__(matcherFn, args) { return matcherFn.apply(this, args); });"); + return function() { return fn.call(this, wrapper, arguments)}; }; - /** * toBe: compares the actual to the expected using === * @param expected diff --git a/src/base.js b/src/base.js index fc4837b..b5f4ef3 100755 --- a/src/base.js +++ b/src/base.js @@ -57,24 +57,47 @@ jasmine.MessageResult = function(text) { this.trace = new Error(); // todo: test better }; -jasmine.ExpectationResult = function(params) { - this.type = 'ExpectationResult'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; +(function() { + jasmine.ExpectationResult = function __jasmine_ExpectationResult__(params) { + this.type = 'ExpectationResult'; + this.matcherName = params.matcherName; + this.passed_ = params.passed; + this.expected = params.expected; + this.actual = params.actual; - /** @deprecated */ - this.details = params.details; + /** @deprecated */ + this.details = params.details; - this.message = this.passed_ ? 'Passed.' : params.message; - this.trace = this.passed_ ? '' : new Error(this.message); -}; + this.message = this.passed_ ? 'Passed.' : params.message; + this.trace = this.passed_ ? '' : new Error(this.message); + }; +})(); jasmine.ExpectationResult.prototype.passed = function () { return this.passed_; }; +jasmine.ExpectationResult.prototype.stackTrace = function () { + var trace = []; + var orig = this.trace.stack.split("\n"); + var skipNext = false; + for (var i = 0; i < orig.length; i++) { + if (skipNext) { skipNext = false; continue; } + if (orig[i].match(/__jasmine_Matchers_matcherFn__/)) continue; + if (orig[i].match(/__jasmine_ExpectationResult__/)) continue; + var match; + if (match = orig[i].match(/__jasmine_Matchers_\$([^ .()]+)\$_Matcher__/)) { + trace.push(orig[i]); + trace.push(match[1]); + skipNext = true; + continue; + } + if (orig[i].match(/__jasmine_Block_prototype_execute__/)) break; + trace.push(orig[i]); + } + return trace.join("\n"); +}; + /** * Getter for the Jasmine environment. Ensures one gets created */