Added the 'any' and 'all' flags for 'keys' assertion, with 'all' being the default behavior #313

merged 1 commit into from Dec 8, 2014


None yet

3 participants

cjqed commented Dec 1, 2014

This should resolve #254 and the unintuitive behavior of the keys assertion. See the tests for more details, but in a nutshell, the following pass:

expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');
expect({ foo: 1, bar: 2 }).to.contain.all.keys(['bar', 'foo']);

And the following fail:

expect({ foo: 1, bar: 2 }).to.not.have.all.keys(['foo', 'bar']);
expect({ foo: 1, bar: 2 }).to.not.have.any.keys(['foo', 'baz']);

To preserve backward compatibility, using neither any nor all will default you to all. Since no previous tests failed, I'm assuming this worked but let me know if anything sticks out to you.


@keithamus keithamus commented on an outdated diff Dec 1, 2014
@@ -953,14 +988,26 @@ module.exports = function (chai, _) {
, expected = keys
, len = keys.length;
- // Inclusion
- ok = keys.every(function(key){
- return ~actual.indexOf(key);
- });
+ if (!flag(this, 'any') && !flag(this, 'all')) {
+ flag(this, 'all', true);
+ }
keithamus Dec 1, 2014 Member

I'm not 100% sure this is an entirely safe thing to do. It will set the flag for any future assertions - which could lead to subtle bugs, should we ever extend the any or all flags. Might be better to just var these up as Booleans at this point I believe.


Great work @cjqed!

It'd be nice if this PR also featured extending the documentation for .keys(). It already contains documentation for .contains, and is probably the place people will go to when working out if they can do .any.keys/.all.keys. FYI here's the LOC to change.

With this and the above comment addressed, I'll be overjoyed to merge this 😄

cjqed commented Dec 2, 2014

Thanks for the comments @keithamus . Keys just uses bools for any and all now and I redid the documentation for keys.

cjqed commented Dec 2, 2014

Just kidding, now it's good. Had an error about the behavior of "contains" in the documentation.


Great job @cjqed! It's so close to being perfect for me - but I feel like the documentation could be a little more explicit. Reading through it, it doesn't seem to make a solid distinction between .have and .contain despite the examples demonstrating both.

That is definitely my last comment now 😸


@keithamus when docs are to your liking, you have my 👍

cjqed commented Dec 3, 2014

@keithamus No worries on doc rewrite requests, I understand that documentation for something like an assertion library needs to be really explicit. Try that, what do you think?

Also, I rebased from my other branch, so merging this last should lead to no conflicts.


@cjqed the documentation is looking great now, but I think the rebase has introduced the commits from your other branch. I recommend running the following in your repo:

git remote add upstream 
git fetch -p
git rebase upstream/master

Optionally, which would be pretty sweet, you could do a git rebase -i upstream/master and then clean up the commits by squashing them into one or two. If you need some help with interactive rebases, there's some great docs over at

@cjqed cjqed Added the all and any flags for keys assertion, with all being the de…
…fault 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
cjqed commented Dec 3, 2014

That should do it.



@keithamus keithamus merged commit 46aac80 into chaijs:master Dec 8, 2014

1 check passed

continuous-integration/travis-ci The Travis CI build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment