diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index d9099698..5f6be9e4 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -156,6 +156,14 @@ getJasmineRequireObj().base = function(j$) { return spyStrategy.exec.apply(this, arguments); }; + for (var prop in originalFn) { + if (prop === 'and' || prop === 'calls') { + throw new Error("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon"); + } + + spy[prop] = originalFn[prop]; + } + spy.and = spyStrategy; spy.calls = callTracker; @@ -553,16 +561,16 @@ getJasmineRequireObj().Env = function(j$) { this.spyOn = function(obj, methodName) { if (j$.util.isUndefined(obj)) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; + throw new Error("spyOn could not find an object to spy upon for " + methodName + "()"); } if (j$.util.isUndefined(obj[methodName])) { - throw methodName + '() method does not exist'; + throw new Error(methodName + '() method does not exist'); } if (obj[methodName] && j$.isSpy(obj[methodName])) { //TODO?: should this return the current spy? Downside: may cause user confusion about spy state - throw methodName + ' has already been spied upon'; + throw new Error(methodName + ' has already been spied upon'); } var spy = j$.createSpy(methodName, obj[methodName]); @@ -1235,6 +1243,8 @@ getJasmineRequireObj().ObjectContaining = function(j$) { } ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { + if (typeof(this.sample) !== "object") { throw new Error("You must provide an object to objectContaining, not '"+this.sample+"'."); } + mismatchKeys = mismatchKeys || []; mismatchValues = mismatchValues || []; @@ -1246,7 +1256,7 @@ getJasmineRequireObj().ObjectContaining = function(j$) { if (!hasKey(other, property) && hasKey(this.sample, property)) { mismatchKeys.push("expected has key '" + property + "', but missing from actual."); } - else if (!j$.matchersUtil.equals(this.sample[property], other[property], mismatchKeys, mismatchValues)) { + else if (!j$.matchersUtil.equals(this.sample[property], other[property])) { mismatchValues.push("'" + property + "' was '" + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + "' in actual, but was '" + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in expected."); } } @@ -1530,6 +1540,11 @@ getJasmineRequireObj().SpyStrategy = function() { plan = fn; return getSpy(); }; + + this.stub = function(fn) { + plan = function() {}; + return getSpy(); + }; } return SpyStrategy; diff --git a/spec/core/SpySpec.js b/spec/core/SpySpec.js index c42db911..b80f390a 100644 --- a/spec/core/SpySpec.js +++ b/spec/core/SpySpec.js @@ -15,6 +15,8 @@ describe('Spies', function () { }); it("warns the user that we indend to overwrite an existing property", function() { + TestClass.prototype.someFunction.and = "turkey"; + expect(function() { j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction); }).toThrowError("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon"); @@ -23,8 +25,8 @@ describe('Spies', function () { it("adds a spyStrategy and callTracker to the spy", function() { var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction); - expect(spy.and).toEqual(jasmine.any(j$.SpyStrategy); - expect(spy.calls).toEqual(jasmine.any(j$.CallTracker); + expect(spy.and).toEqual(jasmine.any(j$.SpyStrategy)); + expect(spy.calls).toEqual(jasmine.any(j$.CallTracker)); }); });