diff --git a/lib/jasmine.js b/lib/jasmine.js index 7ba87079..39d74abf 100644 --- a/lib/jasmine.js +++ b/lib/jasmine.js @@ -1623,6 +1623,7 @@ jasmine.Spec = function(env, suite, description) { this.results = new jasmine.NestedResults(); this.results.description = description; this.runs = this.addToQueue; + this.matchersClass = null; }; jasmine.Spec.prototype.getFullName = function() { @@ -1660,7 +1661,7 @@ jasmine.Spec.prototype.expects_that = function(actual) { * @private */ jasmine.Spec.prototype.expect = function(actual) { - return new jasmine.Matchers(this.env, actual, this.results); + return new (this.getMatchersClass_())(this.env, actual, this.results); }; /** @@ -1682,6 +1683,22 @@ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, message) { return this; }; +jasmine.Spec.prototype.getMatchersClass_ = function(matcherPrototype) { + return this.matchersClass || jasmine.Matchers; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + for (var method in matchersPrototype) { + newMatchersClass.prototype[method] = matchersPrototype[method]; + } + this.matchersClass = newMatchersClass; +}; + jasmine.Spec.prototype.resetTimeout = function() { this.currentTimeout = 0; this.currentLatchFunction = undefined; diff --git a/spec/suites/SpecRunningTest.js b/spec/suites/SpecRunningTest.js index d74f5f34..ca84e1d4 100644 --- a/spec/suites/SpecRunningTest.js +++ b/spec/suites/SpecRunningTest.js @@ -728,4 +728,36 @@ describe("jasmine spec running", function () { expect(exceptionMessage).toEqual('explodes function should not have been called'); }); + + it("should be easy to add more matchers local to a spec, suite, etc.", function() { + var spec1, spec2, spec1Matcher, spec2Matcher; + + var suite = env.describe('some suite', function() { + env.beforeEach(function() { + this.addMatchers({ matcherForSuite: function(expected) { + return "matcherForSuite: actual: " + this.actual + "; expected: " + expected; + } }); + }); + + spec1 = env.it('spec with an expectation').runs(function () { + this.addMatchers( { matcherForSpec: function(expected) { + return "matcherForSpec: actual: " + this.actual + "; expected: " + expected; + } }); + spec1Matcher = this.expect("xxx"); + }); + + spec2 = env.it('spec with failing expectation').runs(function () { + spec2Matcher = this.expect("yyy"); + }); + }); + + suite.execute(); + + expect(spec1Matcher.matcherForSuite("expected")).toEqual("matcherForSuite: actual: xxx; expected: expected"); + expect(spec1Matcher.matcherForSpec("expected")).toEqual("matcherForSpec: actual: xxx; expected: expected"); + + expect(spec2Matcher.matcherForSuite("expected")).toEqual("matcherForSuite: actual: yyy; expected: expected"); + expect(spec2Matcher.matcherForSpec).toBe(undefined); + }); + }); diff --git a/src/Spec.js b/src/Spec.js index 70c84698..d5666609 100644 --- a/src/Spec.js +++ b/src/Spec.js @@ -21,6 +21,7 @@ jasmine.Spec = function(env, suite, description) { this.results = new jasmine.NestedResults(); this.results.description = description; this.runs = this.addToQueue; + this.matchersClass = null; }; jasmine.Spec.prototype.getFullName = function() { @@ -58,7 +59,7 @@ jasmine.Spec.prototype.expects_that = function(actual) { * @private */ jasmine.Spec.prototype.expect = function(actual) { - return new jasmine.Matchers(this.env, actual, this.results); + return new (this.getMatchersClass_())(this.env, actual, this.results); }; /** @@ -80,6 +81,22 @@ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, message) { return this; }; +jasmine.Spec.prototype.getMatchersClass_ = function(matcherPrototype) { + return this.matchersClass || jasmine.Matchers; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + for (var method in matchersPrototype) { + newMatchersClass.prototype[method] = matchersPrototype[method]; + } + this.matchersClass = newMatchersClass; +}; + jasmine.Spec.prototype.resetTimeout = function() { this.currentTimeout = 0; this.currentLatchFunction = undefined;