From e13621b3d6f39805b33c7853105e9d097bbb50f6 Mon Sep 17 00:00:00 2001 From: Grant Snodgrass Date: Tue, 21 Jun 2016 21:38:35 -0400 Subject: [PATCH] Fix .with when multiple identical arguments --- lib/spy.js | 48 +++++++++++++++++++++--------------------------- test/spies.js | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/lib/spy.js b/lib/spy.js index 87a331b..3bd26b1 100644 --- a/lib/spy.js +++ b/lib/spy.js @@ -264,46 +264,40 @@ module.exports = function (chai, _) { function assertWith () { new Assertion(this._obj).to.be.spy; - var args = [].slice.call(arguments, 0) + var expArgs = [].slice.call(arguments, 0) , calls = this._obj.__spy.calls , always = _.flag(this, 'spy always') - , passed; - - if (always) { - passed = 0 - calls.forEach(function (call) { - var found = 0; - args.forEach(function (arg) { - for (var i = 0; i < call.length; i++) { - if (_.eql(call[i], arg)) found++; + , passed = 0; + + calls.forEach(function (call) { + var actArgs = call.slice() + , found = 0; + + expArgs.forEach(function (expArg) { + for (var i = 0; i < actArgs.length; i++) { + if (_.eql(actArgs[i], expArg)) { + found++; + actArgs.splice(i, 1); + break; } - }); - if (found === args.length) passed++; + } }); + if (found === expArgs.length) passed++; + }); + if (always) { this.assert( passed === calls.length , 'expected ' + this._obj + ' to have been always called with #{exp} but got ' + passed + ' out of ' + calls.length - , 'expected ' + this._his + ' to have not always been called with #{exp}' - , args + , 'expected ' + this._obj + ' to have not always been called with #{exp}' + , expArgs ); } else { - passed = 0; - calls.forEach(function (call) { - var found = 0; - args.forEach(function (arg) { - for (var i = 0; i < call.length; i++) { - if (_.eql(call[i], arg)) found++; - } - }); - if (found === args.length) passed++; - }); - this.assert( passed > 0 , 'expected ' + this._obj + ' to have been called with #{exp}' - , 'expected ' + this._his + ' to have not been called with #{exp} but got ' + passed + ' times' - , args + , 'expected ' + this._obj + ' to have not been called with #{exp} but got ' + passed + ' times' + , expArgs ); } } diff --git a/test/spies.js b/test/spies.js index bb6bd14..c9de8a2 100644 --- a/test/spies.js +++ b/test/spies.js @@ -276,6 +276,15 @@ describe('Chai Spies', function () { spy.should.have.not.been.called.with(3,6,9); }).should.throw(chai.AssertionError, /have not been called with/); }); + + it('should pass when called with multiple identical arguments', function () { + var spy = chai.spy(); + spy(1, 1); + spy.should.have.been.called.with(1); + spy.should.have.been.called.with(1, 1); + spy.should.not.have.been.called.with(1, 2); + spy.should.not.have.been.called.with(1, 1, 1); + }); }); describe('.always.with(arg, ...)', function () { @@ -312,6 +321,16 @@ describe('Chai Spies', function () { spy.should.not.have.been.always.called.with(1,2); }).should.throw(chai.AssertionError, /to have not always been called with/); }); + + it('should pass when called with multiple identical arguments', function () { + var spy = chai.spy(); + spy(1, 3, 1); + spy(1, 2, 1); + spy.should.have.always.been.called.with(1); + spy.should.have.always.been.called.with(1, 1); + spy.should.not.have.always.been.called.with(1, 2); + spy.should.not.have.always.been.called.with(1, 1, 1); + }); }); describe('.with.exactly(arg, ...)', function () { @@ -342,6 +361,15 @@ describe('Chai Spies', function () { spy.should.have.not.been.called.with.exactly(3,2); }).should.throw(chai.AssertionError, /to not have been called with exactly/); }); + + it('should pass when called with multiple identical arguments', function () { + var spy = chai.spy(); + spy(1, 1); + spy.should.have.been.called.with.exactly(1, 1); + spy.should.not.have.been.called.with.exactly(1); + spy.should.not.have.been.called.with.exactly(1, 2); + spy.should.not.have.been.called.with.exactly(1, 1, 1); + }); }); describe('.always.with.exactly(arg, ...)', function () { @@ -376,6 +404,16 @@ describe('Chai Spies', function () { spy2.should.have.been.always.called.with.exactly(4,4); }).should.throw(chai.AssertionError, /to have been always called with exactly/); }); + + it('should pass when called with multiple identical arguments', function () { + var spy = chai.spy(); + spy(1, 1); + spy(1, 1); + spy.should.have.always.been.called.with.exactly(1, 1); + spy.should.not.have.always.been.called.with.exactly(1); + spy.should.not.have.always.been.called.with.exactly(1, 2); + spy.should.not.have.always.been.called.with.exactly(1, 1, 1); + }); }); describe('spy object', function () {