diff --git a/spec/core/ExpectationFilterChainSpec.js b/spec/core/ExpectationFilterChainSpec.js new file mode 100644 index 00000000..8c91dd5a --- /dev/null +++ b/spec/core/ExpectationFilterChainSpec.js @@ -0,0 +1,78 @@ +describe('ExpectationFilterChainSpec', function() { + describe('#selectComparisonFunc', function() { + describe('When no filters have #selectComparisonFunc', function() { + it('returns undefined', function() { + var chain = new jasmineUnderTest.ExpectationFilterChain(); + chain.addFilter({}); + expect(chain.selectComparisonFunc()).toBeUndefined(); + }); + }); + + describe('When some filters have #selectComparisonFunc', function() { + it('calls the first filter that has #selectComparisonFunc', function() { + var chain = new jasmineUnderTest.ExpectationFilterChain(), + first = jasmine.createSpy('first').and.returnValue('first'), + second = jasmine.createSpy('second').and.returnValue('second'), + matcher = {}, + result; + + chain.addFilter({selectComparisonFunc: first}); + chain.addFilter({selectComparisonFunc: second}); + result = chain.selectComparisonFunc(matcher); + + expect(first).toHaveBeenCalledWith(matcher); + expect(second).not.toHaveBeenCalled(); + expect(result).toEqual('first'); + }); + }); + }); + + describe('#buildFailureMessage', function() { + describe('When no filters have #buildFailureMessage', function() { + it('returns undefined', function() { + var chain = new jasmineUnderTest.ExpectationFilterChain(); + chain.addFilter({}); + expect(chain.buildFailureMessage()).toBeUndefined(); + }); + }); + + describe('When some filters have #buildFailureMessage', function() { + it('calls the first filter that has #buildFailureMessage', function() { + var chain = new jasmineUnderTest.ExpectationFilterChain(), + first = jasmine.createSpy('first').and.returnValue('first'), + second = jasmine.createSpy('second').and.returnValue('second'), + matcherResult = {pass: false}, + matcherName = 'foo', + args = [], + util = {}, + result; + + chain.addFilter({buildFailureMessage: first}); + chain.addFilter({buildFailureMessage: second}); + result = chain.buildFailureMessage(matcherResult, matcherName, args, util); + + expect(first).toHaveBeenCalledWith(matcherResult, matcherName, args, util); + expect(second).not.toHaveBeenCalled(); + expect(result).toEqual('first'); + }); + }); + }); + + describe('#modifyFailureMessage', function() { + it('calls each filter with the return value of the next previously added filter', function() { + var chain = new jasmineUnderTest.ExpectationFilterChain(), + first = jasmine.createSpy('first').and.returnValue('first'), + third = jasmine.createSpy('third').and.returnValue('third'), + result; + + chain.addFilter({modifyFailureMessage: first}); + chain.addFilter({}) + chain.addFilter({modifyFailureMessage: third}); + result = chain.modifyFailureMessage('original'); + + expect(third).toHaveBeenCalledWith('original'); + expect(first).toHaveBeenCalledWith('third'); + expect(result).toEqual('first'); + }); + }); +}); diff --git a/src/core/ExpectationFilterChain.js b/src/core/ExpectationFilterChain.js new file mode 100644 index 00000000..3577ab4c --- /dev/null +++ b/src/core/ExpectationFilterChain.js @@ -0,0 +1,43 @@ +getJasmineRequireObj().ExpectationFilterChain = function() { + function ExpectationFilterChain() { + this.filters_ = []; + } + + ExpectationFilterChain.prototype.addFilter = function(filter) { + this.filters_.push(filter); + }; + + ExpectationFilterChain.prototype.selectComparisonFunc = function(matcher) { + return this.callFirst_('selectComparisonFunc', arguments); + }; + + ExpectationFilterChain.prototype.buildFailureMessage = function(result, matcherName, args, util) { + return this.callFirst_('buildFailureMessage', arguments); + }; + + ExpectationFilterChain.prototype.modifyFailureMessage = function(msg) { + var i; + + for (i = this.filters_.length - 1; i >= 0; i--) { + if (this.filters_[i].modifyFailureMessage) { + msg = this.filters_[i].modifyFailureMessage(msg); + } + } + + return msg; + }; + + ExpectationFilterChain.prototype.callFirst_ = function(fname, args) { + var i, filter; + + for (i = 0; i < this.filters_.length; i++) { + filter = this.filters_[i]; + + if (filter[fname]) { + return filter[fname].apply(filter, args); + } + } + }; + + return ExpectationFilterChain; +}; diff --git a/src/core/requireCore.js b/src/core/requireCore.js index abc12e67..252ba2a9 100644 --- a/src/core/requireCore.js +++ b/src/core/requireCore.js @@ -37,6 +37,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) { j$.Env = jRequire.Env(j$); j$.StackTrace = jRequire.StackTrace(j$); j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$); + j$.ExpectationFilterChain = jRequire.ExpectationFilterChain(); j$.Expectation = jRequire.Expectation(j$); j$.buildExpectationResult = jRequire.buildExpectationResult(); j$.JsApiReporter = jRequire.JsApiReporter();