mirror of
https://github.com/chaijs/chai
synced 2024-11-15 00:07:11 +00:00
Added the all and any flags for keys assertion, with all being the default behavior
Extended keys documentation and set bools instead of changing flags in the keys assertion Miswrote in keys documentation, corrected mistake Edited documentation for keys to better match how it interacts with contains and have
This commit is contained in:
parent
f06278f0b8
commit
e0e06082ea
3 changed files with 143 additions and 15 deletions
|
@ -82,6 +82,41 @@ module.exports = function (chai, _) {
|
|||
flag(this, 'deep', true);
|
||||
});
|
||||
|
||||
/**
|
||||
* ### .any
|
||||
*
|
||||
* Sets the `any` flag, (opposite of the `all` flag)
|
||||
* later used in the `keys` assertion.
|
||||
*
|
||||
* expect(foo).to.have.any.keys('bar', 'baz');
|
||||
*
|
||||
* @name any
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Assertion.addProperty('any', function () {
|
||||
flag(this, 'any', true);
|
||||
flag(this, 'all', false)
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* ### .all
|
||||
*
|
||||
* Sets the `all` flag (opposite of the `any` flag)
|
||||
* later used by the `keys` assertion.
|
||||
*
|
||||
* expect(foo).to.have.all.keys('bar', 'baz');
|
||||
*
|
||||
* @name all
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Assertion.addProperty('all', function () {
|
||||
flag(this, 'all', true);
|
||||
flag(this, 'any', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* ### .a(type)
|
||||
*
|
||||
|
@ -930,12 +965,30 @@ module.exports = function (chai, _) {
|
|||
/**
|
||||
* ### .keys(key1, [key2], [...])
|
||||
*
|
||||
* Asserts that the target has exactly the given keys, or
|
||||
* asserts the inclusion of some keys when using the
|
||||
* `include` or `contain` modifiers.
|
||||
*
|
||||
* expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
|
||||
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
|
||||
* Asserts that the target contains any or all of the passed-in keys.
|
||||
* Use in combination with `any`, `all`, `contains`, or `have` will affect
|
||||
* what will pass.
|
||||
*
|
||||
* When used in conjunction with `any`, at least one key that is passed
|
||||
* in must exist in the target object. This is regardless whether or not
|
||||
* the `have` or `contain` qualifiers are used. Note, either `any` or `all`
|
||||
* should be used in the assertion. If neither are used, the assertion is
|
||||
* defaulted to `all`.
|
||||
*
|
||||
* When both `all` and `contain` are used, the target object must have at
|
||||
* least all of the passed-in keys but may have more keys not listed.
|
||||
*
|
||||
* When both `all` and `have` are used, the target object must both contain
|
||||
* all of the passed-in keys AND the number of keys in the target object must
|
||||
* match the number of keys passed in (in other words, a target object must
|
||||
* have all and only all of the passed-in keys).
|
||||
*
|
||||
* expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');
|
||||
* expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');
|
||||
* expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');
|
||||
* expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);
|
||||
* expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
|
||||
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
|
||||
*
|
||||
* @name keys
|
||||
* @alias key
|
||||
|
@ -956,16 +1009,30 @@ module.exports = function (chai, _) {
|
|||
|
||||
var actual = Object.keys(obj)
|
||||
, expected = keys
|
||||
, len = keys.length;
|
||||
, len = keys.length
|
||||
, any = flag(this, 'any')
|
||||
, all = flag(this, 'all');
|
||||
|
||||
// Inclusion
|
||||
ok = keys.every(function(key){
|
||||
return ~actual.indexOf(key);
|
||||
});
|
||||
if (!any && !all) {
|
||||
all = true;
|
||||
}
|
||||
|
||||
// Strict
|
||||
if (!flag(this, 'negate') && !flag(this, 'contains')) {
|
||||
ok = ok && keys.length == actual.length;
|
||||
// Has any
|
||||
if (any) {
|
||||
var intersection = expected.filter(function(key) {
|
||||
return ~actual.indexOf(key);
|
||||
});
|
||||
ok = intersection.length > 0;
|
||||
}
|
||||
|
||||
// Has all
|
||||
if (all) {
|
||||
ok = keys.every(function(key){
|
||||
return ~actual.indexOf(key);
|
||||
});
|
||||
if (!flag(this, 'negate') && !flag(this, 'contains')) {
|
||||
ok = ok && keys.length == actual.length;
|
||||
}
|
||||
}
|
||||
|
||||
// Key string
|
||||
|
@ -974,7 +1041,12 @@ module.exports = function (chai, _) {
|
|||
return _.inspect(key);
|
||||
});
|
||||
var last = keys.pop();
|
||||
str = keys.join(', ') + ', and ' + last;
|
||||
if (all) {
|
||||
str = keys.join(', ') + ', and ' + last;
|
||||
}
|
||||
if (any) {
|
||||
str = keys.join(', ') + ', or ' + last;
|
||||
}
|
||||
} else {
|
||||
str = _.inspect(keys[0]);
|
||||
}
|
||||
|
|
|
@ -581,6 +581,7 @@ describe('expect', function () {
|
|||
expect({ foo: 1, bar: 2 }).to.contain.keys(['foo']);
|
||||
expect({ foo: 1, bar: 2 }).to.contain.keys(['bar']);
|
||||
expect({ foo: 1, bar: 2 }).to.contain.keys(['bar', 'foo']);
|
||||
expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
|
||||
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.keys('baz');
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.keys('foo', 'baz');
|
||||
|
@ -588,6 +589,19 @@ describe('expect', function () {
|
|||
expect({ foo: 1, bar: 2 }).to.not.contain.keys('foo', 'baz');
|
||||
expect({ foo: 1, bar: 2 }).to.not.contain.keys('baz', 'foo');
|
||||
|
||||
expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');
|
||||
expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');
|
||||
expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');
|
||||
expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);
|
||||
expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
|
||||
expect({ foo: 1, bar: 2 }).to.contain.all.keys(['bar', 'foo']);
|
||||
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.any.keys('baz', 'abc', 'def');
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.any.keys('baz');
|
||||
expect({ foo: 1, bar: 2 }).to.not.contain.any.keys('baz');
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.all.keys(['baz', 'foo']);
|
||||
expect({ foo: 1, bar: 2 }).to.not.contain.all.keys(['baz', 'foo']);
|
||||
|
||||
err(function(){
|
||||
expect({ foo: 1 }).to.have.keys();
|
||||
}, "keys required");
|
||||
|
@ -627,6 +641,10 @@ describe('expect', function () {
|
|||
err(function(){
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.keys(['foo', 'bar']);
|
||||
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'");
|
||||
|
||||
err(function(){
|
||||
expect({ foo: 1, bar: 2 }).to.have.all.keys('foo');
|
||||
}, "expected { foo: 1, bar: 2 } to have key 'foo'");
|
||||
|
||||
err(function(){
|
||||
expect({ foo: 1 }).to.not.contain.keys(['foo']);
|
||||
|
@ -635,6 +653,19 @@ describe('expect', function () {
|
|||
err(function(){
|
||||
expect({ foo: 1 }).to.contain.keys('foo', 'bar');
|
||||
}, "expected { foo: 1 } to contain keys 'foo', and 'bar'");
|
||||
|
||||
err(function() {
|
||||
expect({ foo: 1 }).to.have.any.keys('baz');
|
||||
}, "expected { foo: 1 } to have key 'baz'");
|
||||
|
||||
err(function(){
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.all.keys(['foo', 'bar']);
|
||||
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'");
|
||||
|
||||
err(function(){
|
||||
expect({ foo: 1, bar: 2 }).to.not.have.any.keys(['foo', 'baz']);
|
||||
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'");
|
||||
|
||||
});
|
||||
|
||||
it('chaining', function(){
|
||||
|
|
|
@ -451,6 +451,19 @@ describe('should', function() {
|
|||
({ foo: 1, bar: 2 }).should.not.contain.keys('foo', 'baz');
|
||||
({ foo: 1, bar: 2 }).should.not.contain.keys('baz', 'foo');
|
||||
|
||||
({ foo: 1, bar: 2 }).should.have.any.keys('foo', 'baz');
|
||||
({ foo: 1, bar: 2 }).should.have.any.keys('foo');
|
||||
({ foo: 1, bar: 2 }).should.contain.any.keys('bar', 'baz');
|
||||
({ foo: 1, bar: 2 }).should.contain.any.keys(['foo']);
|
||||
({ foo: 1, bar: 2 }).should.have.all.keys(['bar', 'foo']);
|
||||
({ foo: 1, bar: 2 }).should.contain.all.keys(['bar', 'foo']);
|
||||
|
||||
({ foo: 1, bar: 2 }).should.not.have.any.keys('baz', 'abc', 'def');
|
||||
({ foo: 1, bar: 2 }).should.not.have.any.keys('baz');
|
||||
({ foo: 1, bar: 2 }).should.not.contain.any.keys('baz');
|
||||
({ foo: 1, bar: 2 }).should.not.have.all.keys(['baz', 'foo']);
|
||||
({ foo: 1, bar: 2 }).should.not.contain.all.keys(['baz', 'foo']);
|
||||
|
||||
err(function(){
|
||||
({ foo: 1 }).should.have.keys();
|
||||
}, "keys required");
|
||||
|
@ -498,6 +511,18 @@ describe('should', function() {
|
|||
err(function(){
|
||||
({ foo: 1 }).should.contain.keys('foo', 'bar');
|
||||
}, "expected { foo: 1 } to contain keys 'foo', and 'bar'");
|
||||
|
||||
err(function() {
|
||||
({ foo: 1 }).should.have.any.keys('baz');
|
||||
}, "expected { foo: 1 } to have key 'baz'");
|
||||
|
||||
err(function(){
|
||||
({ foo: 1, bar: 2 }).should.not.have.all.keys(['foo', 'bar']);
|
||||
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'");
|
||||
|
||||
err(function(){
|
||||
({ foo: 1, bar: 2 }).should.not.have.any.keys(['foo', 'baz']);
|
||||
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'");
|
||||
});
|
||||
|
||||
it('throw', function () {
|
||||
|
|
Loading…
Reference in a new issue