Skip to content

Commit

Permalink
fix chaijs#359. Add `.keys(object)
Browse files Browse the repository at this point in the history
- `.keys(object)n => .keys(Object.keys(Object)`
- added exceptions for 'if first arg is non-string, then it must be only
arg.  => `.keys(Array|Object, ...)`

Warning:  `Object.keys` must exist on systems to use this functionality.
  • Loading branch information
gregglind committed Feb 8, 2015
1 parent bd72280 commit 0baa6f1
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 8 deletions.
25 changes: 20 additions & 5 deletions lib/chai/core/assertions.js
Expand Up @@ -992,23 +992,38 @@ module.exports = function (chai, _) {
* 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.contain.any.keys({'foo': 6});
* expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
* expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo', 7});
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
* expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys([{'bar': 6}}]);
*
*
* @name keys
* @alias key
* @param {String...|Array} keys
* @param {String...|Array|Object} keys
* @api public
*/

function assertKeys (keys) {
var obj = flag(this, 'object')
, str
, ok = true;
, ok = true
, mixedArgsMsg = "keys: if first argument is instanceof Array|Object, must be only argument."

if (keys instanceof Array || keys instanceof Object) {
if (arguments.length > 1) {
throw (new Error(mixedArgsMsg));
}
if (keys instanceof Array) {
//
} else {
keys = Object.keys(keys);

keys = keys instanceof Array
? keys
: Array.prototype.slice.call(arguments);
}
} else {
keys = Array.prototype.slice.call(arguments);
}

if (!keys.length) throw new Error('keys required');

Expand Down
68 changes: 66 additions & 2 deletions test/expect.js
Expand Up @@ -568,13 +568,18 @@ describe('expect', function () {
}, "expected [ { a: 1 }, { b: 2 } ] to not include { b: 2 }");
});

it('keys(array)', function(){
it('keys(array|Object|arguments)', function(){
expect({ foo: 1 }).to.have.keys(['foo']);
expect({ foo: 1 }).have.keys({ 'foo': 6 });
expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
expect({ foo: 1, bar: 2 }).to.have.keys('foo', 'bar');
expect({ foo: 1, bar: 2 }).have.keys({ 'foo': 6, 'bar': 7 });
expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('bar', 'foo');
expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('baz');
expect({ foo: 1, bar: 2 }).contain.keys({ 'foo': 6 });
expect({ foo: 1, bar: 2 }).contain.keys({ 'bar': 7 });
expect({ foo: 1, bar: 2 }).contain.keys({ 'foo': 6 });

expect({ foo: 1, bar: 2 }).to.contain.keys('foo');
expect({ foo: 1, bar: 2 }).to.contain.keys('bar', 'foo');
Expand All @@ -595,12 +600,17 @@ describe('expect', function () {
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 }).contain.any.keys({ 'foo': 6 });
expect({ foo: 1, bar: 2 }).have.all.keys({ 'foo': 6, 'bar': 7 });
expect({ foo: 1, bar: 2 }).contain.all.keys({ 'bar': 7, 'foo': 6 });

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']);
expect({ foo: 1, bar: 2 }).not.have.all.keys({ 'baz': 8, 'foo': 7 });
expect({ foo: 1, bar: 2 }).not.contain.all.keys({ 'baz': 8, 'foo': 7 });

err(function(){
expect({ foo: 1 }).to.have.keys();
Expand All @@ -618,6 +628,15 @@ describe('expect', function () {
expect({ foo: 1 }).to.contain.keys([]);
}, "keys required");

err(function(){
expect({}).contain.keys(['a'], "b");
}, "keys: if first argument is instanceof Array|Object, must be only argument.");

err(function(){
expect({}).contain.keys({ 'a': 1 }, "b");
}, "keys: if first argument is instanceof Array|Object, must be only argument.");


err(function(){
expect({ foo: 1 }).to.have.keys(['bar']);
}, "expected { foo: 1 } to have key 'bar'");
Expand All @@ -641,7 +660,7 @@ 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'");
Expand All @@ -666,6 +685,51 @@ describe('expect', 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'");

// repeat previous tests with Object as arg.
err(function(){
expect({ foo: 1 }).have.keys({ 'bar': 1 });
}, "expected { foo: 1 } to have key 'bar'");

err(function(){
expect({ foo: 1 }).have.keys({ 'bar': 1, 'baz': 1});
}, "expected { foo: 1 } to have keys 'bar', and 'baz'");

err(function(){
expect({ foo: 1 }).have.keys({ 'foo': 1, 'bar': 1, 'baz': 1});
}, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'");

err(function(){
expect({ foo: 1 }).not.have.keys({ 'foo': 1 });
}, "expected { foo: 1 } to not have key 'foo'");

err(function(){
expect({ foo: 1 }).not.have.keys({ 'foo': 1 });
}, "expected { foo: 1 } to not have key 'foo'");

err(function(){
expect({ foo: 1, bar: 2 }).not.have.keys({ 'foo': 1, 'bar': 1});
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'");

err(function(){
expect({ foo: 1 }).not.contain.keys({ 'foo': 1 });
}, "expected { foo: 1 } to not contain key 'foo'");

err(function(){
expect({ foo: 1 }).contain.keys('foo', 'bar');
}, "expected { foo: 1 } to contain keys 'foo', and 'bar'");

err(function() {
expect({ foo: 1 }).have.any.keys('baz');
}, "expected { foo: 1 } to have key 'baz'");

err(function(){
expect({ foo: 1, bar: 2 }).not.have.all.keys({ 'foo': 1, 'bar': 1});
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'");

err(function(){
expect({ foo: 1, bar: 2 }).not.have.any.keys({ 'foo': 1, 'baz': 1});
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'");

});

it('keys(array) will not mutate array (#359)', function () {
Expand Down
68 changes: 67 additions & 1 deletion test/should.js
Expand Up @@ -431,10 +431,14 @@ describe('should', function() {
}, "expected { a: 1 } to have a property 'b'")
});

it('keys(array)', function(){
it('keys(array|Object|arguments)', function(){
({ foo: 1 }).should.have.keys(['foo']);
({ foo: 1 }).should.have.keys({ 'foo': 6 });

({ foo: 1, bar: 2 }).should.have.keys(['foo', 'bar']);
({ foo: 1, bar: 2 }).should.have.keys('foo', 'bar');
({ foo: 1, bar: 2 }).should.have.keys({ 'foo': 6, 'bar': 7 });

({ foo: 1, bar: 2, baz: 3 }).should.include.keys('foo', 'bar');
({ foo: 1, bar: 2, baz: 3 }).should.contain.keys('bar', 'foo');
({ foo: 1, bar: 2, baz: 3 }).should.contain.keys('baz');
Expand All @@ -444,6 +448,9 @@ describe('should', function() {
({ foo: 1, bar: 2 }).should.contain.keys(['foo']);
({ foo: 1, bar: 2 }).should.contain.keys(['bar']);
({ foo: 1, bar: 2 }).should.contain.keys(['bar', 'foo']);
({ foo: 1, bar: 2 }).should.contain.keys({ 'foo': 6 });
({ foo: 1, bar: 2 }).should.contain.keys({ 'bar': 7 });
({ foo: 1, bar: 2 }).should.contain.keys({ 'foo': 6 });

({ foo: 1, bar: 2 }).should.not.have.keys('baz');
({ foo: 1, bar: 2 }).should.not.have.keys('foo', 'baz');
Expand All @@ -457,12 +464,17 @@ describe('should', function() {
({ 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.contain.any.keys({ 'foo': 6 });
({ foo: 1, bar: 2 }).should.have.all.keys({ 'foo': 6, 'bar': 7 });
({ foo: 1, bar: 2 }).should.contain.all.keys({ 'bar': 7, 'foo': 6 });

({ 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']);
({ foo: 1, bar: 2 }).should.not.have.all.keys({ 'baz': 8, 'foo': 7 });
({ foo: 1, bar: 2 }).should.not.contain.all.keys({ 'baz': 8, 'foo': 7 });

err(function(){
({ foo: 1 }).should.have.keys();
Expand All @@ -480,6 +492,14 @@ describe('should', function() {
({ foo: 1 }).should.contain.keys([]);
}, "keys required");

err(function(){
({}).should.contain.keys(['a'], "b");
}, "keys: if first argument is instanceof Array|Object, must be only argument.");

err(function(){
({}).should.contain.keys({ 'a': 1 }, "b");
}, "keys: if first argument is instanceof Array|Object, must be only argument.");

err(function(){
({ foo: 1 }).should.have.keys(['bar']);
}, "expected { foo: 1 } to have key 'bar'");
Expand Down Expand Up @@ -523,6 +543,52 @@ describe('should', function() {
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'");

// repeat previous tests with Object as arg.
err(function(){
({ foo: 1 }).should.have.keys({ 'bar': 1 });
}, "expected { foo: 1 } to have key 'bar'");

err(function(){
({ foo: 1 }).should.have.keys({ 'bar': 1, 'baz': 1});
}, "expected { foo: 1 } to have keys 'bar', and 'baz'");

err(function(){
({ foo: 1 }).should.have.keys({ 'foo': 1, 'bar': 1, 'baz': 1});
}, "expected { foo: 1 } to have keys 'foo', 'bar', and 'baz'");

err(function(){
({ foo: 1 }).should.not.have.keys({ 'foo': 1 });
}, "expected { foo: 1 } to not have key 'foo'");

err(function(){
({ foo: 1 }).should.not.have.keys({ 'foo': 1 });
}, "expected { foo: 1 } to not have key 'foo'");

err(function(){
({ foo: 1, bar: 2 }).should.not.have.keys({ 'foo': 1, 'bar': 1});
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'");

err(function(){
({ foo: 1 }).should.not.contain.keys({ 'foo': 1 });
}, "expected { foo: 1 } to not contain key 'foo'");

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': 1, 'bar': 1});
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', and 'bar'");

err(function(){
({ foo: 1, bar: 2 }).should.not.have.any.keys({ 'foo': 1, 'baz': 1});
}, "expected { foo: 1, bar: 2 } to not have keys 'foo', or 'baz'");

});

it('keys(array) will not mutate array (#359)', function () {
Expand Down

0 comments on commit 0baa6f1

Please sign in to comment.