Skip to content

Commit

Permalink
Merge branch 'feature/arguments'
Browse files Browse the repository at this point in the history
* feature/arguments:
  browser build
  tests for argument call assertions
  add assertions for argument checking
  add assertion: .with() / .with
  • Loading branch information
logicalparadox committed Nov 15, 2012
2 parents 60bb510 + 59c097e commit 851b958
Show file tree
Hide file tree
Showing 3 changed files with 407 additions and 46 deletions.
147 changes: 128 additions & 19 deletions chai-spies.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,32 @@
* @api public
*/

Assertion.addProperty('called', function () {
var assert = function () {
new Assertion(this._obj).to.be.spy;
function assertCalled (n) {
new Assertion(this._obj).to.be.spy;
var spy = this._obj.__spy;

if (n) {
this.assert(
spy.calls.length === n
, 'expected #{this} to have been called #{exp} but got #{act}'
, 'expected #{this} to have not been called #{exp}'
, spy.calls.length
, n
);
} else {
this.assert(
this._obj.__spy.called === true
, 'expected ' + this._obj + ' to have been called'
, 'expected ' + this._obj + ' to not have been called'
spy.called === true
, 'expected #{this} to have been called'
, 'expected #{this} to not have been called'
);
}
}

return this;
};
function assertCalledChain () {
new Assertion(this._obj).to.be.spy;
}

assert.__proto__ = this;
return assert;
});
Assertion.addChainableMethod('called', assertCalled, assertCalledChain);

/**
* # once
Expand Down Expand Up @@ -179,6 +189,71 @@
);
});

/**
* ### .with
*
*/

function assertWith () {
new Assertion(this._obj).to.be.spy;
var args = [].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++;
}
});
if (found === args.length) passed++;
});

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
);
} 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
);
}
}

function assertWithChain () {
if ('undefined' !== this._obj.__spy) {
_.flag(this, 'spy with', true);
}
}

Assertion.addChainableMethod('with', assertWith, assertWithChain);

Assertion.addProperty('always', function () {
if ('undefined' !== this._obj.__spy) {
_.flag(this, 'spy always', true);
}
});

/**
* # exactly (n)
*
Expand All @@ -188,15 +263,49 @@
* @api public
*/

Assertion.addMethod('exactly', function (n) {
Assertion.addMethod('exactly', function () {
new Assertion(this._obj).to.be.spy;
this.assert(
this._obj.__spy.calls.length === n
, 'expected ' + this._obj + ' to have been called #{exp} times but got #{act}'
, 'expected ' + this._obj + ' to not have been called #{exp} times'
, n
, this._obj.__spy.calls.length
);
var always = _.flag(this, 'spy always')
, _with = _.flag(this, 'spy with')
, args = [].slice.call(arguments, 0)
, calls = this._obj.__spy.calls
, passed;

if (always && _with) {
passed = 0
calls.forEach(function (call) {
if (call.length !== args.length) return;
if (_.eql(call, args)) passed++;
});

this.assert(
passed === calls.length
, 'expected ' + this._obj + ' to have been always called with exactly #{exp} but got ' + passed + ' out of ' + calls.length
, 'expected ' + this._obj + ' to have not always been called with exactly #{exp}'
, args
);
} else if (_with) {
passed = 0;
calls.forEach(function (call) {
if (call.length !== args.length) return;
if (_.eql(call, args)) passed++;
});

this.assert(
passed > 0
, 'expected ' + this._obj + ' to have been called with exactly #{exp}'
, 'expected ' + this._obj + ' to not have been called with exactly #{exp} but got ' + passed + ' times'
, args
);
} else {
this.assert(
this._obj.__spy.calls.length === args[0]
, 'expected ' + this._obj + ' to have been called #{exp} times but got #{act}'
, 'expected ' + this._obj + ' to not have been called #{exp} times'
, args[0]
, this._obj.__spy.calls.length
);
}
});

/**
Expand Down
147 changes: 128 additions & 19 deletions lib/spy.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,32 @@ module.exports = function (chai, _) {
* @api public
*/

Assertion.addProperty('called', function () {
var assert = function () {
new Assertion(this._obj).to.be.spy;
function assertCalled (n) {
new Assertion(this._obj).to.be.spy;
var spy = this._obj.__spy;

if (n) {
this.assert(
spy.calls.length === n
, 'expected #{this} to have been called #{exp} but got #{act}'
, 'expected #{this} to have not been called #{exp}'
, spy.calls.length
, n
);
} else {
this.assert(
this._obj.__spy.called === true
, 'expected ' + this._obj + ' to have been called'
, 'expected ' + this._obj + ' to not have been called'
spy.called === true
, 'expected #{this} to have been called'
, 'expected #{this} to not have been called'
);
}
}

return this;
};
function assertCalledChain () {
new Assertion(this._obj).to.be.spy;
}

assert.__proto__ = this;
return assert;
});
Assertion.addChainableMethod('called', assertCalled, assertCalledChain);

/**
* # once
Expand Down Expand Up @@ -163,6 +173,71 @@ module.exports = function (chai, _) {
);
});

/**
* ### .with
*
*/

function assertWith () {
new Assertion(this._obj).to.be.spy;
var args = [].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++;
}
});
if (found === args.length) passed++;
});

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
);
} 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
);
}
}

function assertWithChain () {
if ('undefined' !== this._obj.__spy) {
_.flag(this, 'spy with', true);
}
}

Assertion.addChainableMethod('with', assertWith, assertWithChain);

Assertion.addProperty('always', function () {
if ('undefined' !== this._obj.__spy) {
_.flag(this, 'spy always', true);
}
});

/**
* # exactly (n)
*
Expand All @@ -172,15 +247,49 @@ module.exports = function (chai, _) {
* @api public
*/

Assertion.addMethod('exactly', function (n) {
Assertion.addMethod('exactly', function () {
new Assertion(this._obj).to.be.spy;
this.assert(
this._obj.__spy.calls.length === n
, 'expected ' + this._obj + ' to have been called #{exp} times but got #{act}'
, 'expected ' + this._obj + ' to not have been called #{exp} times'
, n
, this._obj.__spy.calls.length
);
var always = _.flag(this, 'spy always')
, _with = _.flag(this, 'spy with')
, args = [].slice.call(arguments, 0)
, calls = this._obj.__spy.calls
, passed;

if (always && _with) {
passed = 0
calls.forEach(function (call) {
if (call.length !== args.length) return;
if (_.eql(call, args)) passed++;
});

this.assert(
passed === calls.length
, 'expected ' + this._obj + ' to have been always called with exactly #{exp} but got ' + passed + ' out of ' + calls.length
, 'expected ' + this._obj + ' to have not always been called with exactly #{exp}'
, args
);
} else if (_with) {
passed = 0;
calls.forEach(function (call) {
if (call.length !== args.length) return;
if (_.eql(call, args)) passed++;
});

this.assert(
passed > 0
, 'expected ' + this._obj + ' to have been called with exactly #{exp}'
, 'expected ' + this._obj + ' to not have been called with exactly #{exp} but got ' + passed + ' times'
, args
);
} else {
this.assert(
this._obj.__spy.calls.length === args[0]
, 'expected ' + this._obj + ' to have been called #{exp} times but got #{act}'
, 'expected ' + this._obj + ' to not have been called #{exp} times'
, args[0]
, this._obj.__spy.calls.length
);
}
});

/**
Expand Down
Loading

0 comments on commit 851b958

Please sign in to comment.