Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deep flag support for keys assertion #668

Merged
merged 1 commit into from Sep 28, 2016

Conversation

lucasfcosta
Copy link
Member

@lucasfcosta lucasfcosta commented Apr 6, 2016

This adds support for the deep flag on the keys assertion (for Maps/Sets) as I've talked to @keithamus at #633.

This PR should include:

  • Deep flag support for the keys assertion (Maps/Sets)
  • Updated doc comments with examples and a general explanation about the deep flag on this assertion
  • Tests on the should interface
  • Tests on the expect interface
  • Bindings for these on the assert interface
  • Tests on the assert interface

Currently the only thing missing are the bindings for these assertions on the assert interface, I didn't do it yet because I'm not sure if adding lots of bindings for this to the assert interface would be cool. If we added bindings for every possible combination of the keys assertion flags we would have:

  1. hasAnyKeys
  2. hasAllKeys
  3. containsAllKeys
  4. doesNotHaveAnyKeys
  5. doesNotHaveAllKeys
  6. hasAnyDeepKeys
  7. hasAllDeepKeys
  8. containsAllDeepKeys
  9. doesNotHaveAnyDeepKeys
  10. doesNotHaveAllDeepKeys

IMO we should have all of them on the assert interface because I think it should have the same features as the other interfaces do, but I just wanted to make sure you guys agree with me before adding all these bindings.


Important Detail:

Currently we need to fix #662 in order to enable all tests, so I think we may keep this open but on hold until we've got inspect to work properly for maps and sets so we can fully test this.
What's your opinion on this?


Thanks in advance, please feel free to point any possible mistakes/improvements 😄

@lucasfcosta
Copy link
Member Author

Hello everyone, I'll finish the items left on this one since we're getting close to releasing 4.x.x.
But before getting this merged I'd like to have #662 fixed just so we can have complete tests for it.
What do you think?

@keithamus
Copy link
Member

@lucasfcosta my work with refactoring loupe is quite a ways off. We can probably apple a simple fix for #662 though, to get it working with Maps and Sets for now.

@lucasfcosta
Copy link
Member Author

lucasfcosta commented Sep 14, 2016

@keithamus seems like a good idea. Let's solve this one that way then so we can get this merged.

@lucasfcosta lucasfcosta force-pushed the deep-flag-for-keys branch 3 times, most recently from a72431a to a911ec0 Compare September 15, 2016 17:48
@lucasfcosta
Copy link
Member Author

This one is done!
Feel free to review and merge this if you think it's good to go.
Thanks everyone! 😄

@lucasfcosta lucasfcosta changed the title [WIP] Deep flag support for keys assertion Deep flag support for keys assertion Sep 15, 2016
@@ -778,7 +794,7 @@ describe('assert', function () {
var errMap = new Map();

errMap.set({1: 20}, 'number');

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see trailing spaces 😱

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My vim does only removes it when there's an .editorconfig file in the root folder of where the file is 😢

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just fixed that, thanks for noticing 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha

I add a .editorconfig file on my home with some rules that I always want.
I think it goes looking upwards until it finds one

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does, great idea 😄

@vieiralucas
Copy link
Member

Awesome work!
Specially with the docs and tests 🎉 🎉 🎉

What could we do to remember enabling these commented tests when #662 gets solved?
Maybe solving that issue should require enabling this tests?

@lucasfcosta
Copy link
Member Author

@vieiralucas Yes, I think that would be ideal.
I'll leave a comment there so we won't forget it, thanks for noticing 😄

Copy link
Contributor

@meeber meeber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasfcosta Excellent work sir, this will be a fine addition to Chai. I have a few small comments sprinkled throughout (it only looks like a lot of comments cause I repeated them wherever applicable).

, str
, ok = true
, mixedArgsMsg = 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments';

if (_.type(obj) === 'map' || _.type(obj) === 'set') {
str = isDeep ? 'deeply ' : '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize messages aren't being tested yet due to an issue with inspect and sets/maps, but just noting that I believe str will get overwritten here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right!
I'm going to use a different variable to store that String, thanks 😄

assert.hasAnyDeepKeys = function (obj, keys, msg) {
if (keys === undefined) {
new Assertion(obj, msg).to.have.any.deep.keys();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the undefined check was at the top of the actual assertKeys function instead?

*
* @name doesNotHaveAllKeys
* @param {Mixed} object
* @param {...String|Array|Object} keys
Copy link
Contributor

@meeber meeber Sep 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look to me like the ...String style of the keys argument is supported here.

*
* @name hasAllDeepKeys
* @param {Mixed} object
* @param {...String|Array|Object} keys
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look to me like the ...String style of the keys argument is supported here.

/**
* ### .containsAllDeepKeys(object, [keys], [message])
*
* Asserts that `object` contains all of the `keys` provided.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though it's shown in the example, probably worth mentioning explicitly that the object can have more keys than those provided, just to contrast with hasAll

@@ -877,6 +903,22 @@ describe('assert', function () {
errSet.add({1: 20});
errSet.add('number');

// Tests for the deep variations of the keys assertion
Copy link
Contributor

@meeber meeber Sep 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking a test should be added to the non-deep variety of assertion above demonstrating that it uses strict equality instead of deep. For example:

assert.doesNotHaveAnyKeys(testSet, {thisIs: 'anExampleObject'});

@@ -1205,6 +1205,27 @@ describe('expect', function () {
expect(testMap).to.not.have.any.keys([20, 1, {13: 37}]);
expect(testMap).to.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);

// Using the same assertions as above but with `.deep` flag instead of using referential equality
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing as mentioned in the assert interface tests about adding a non-deep test to demonstrate strict equality.

@@ -1285,6 +1316,26 @@ describe('expect', function () {
expect(testSet).to.not.have.any.keys([20, 1, {13: 37}]);
expect(testSet).to.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);

// Using the same assertions as above but with `.deep` flag instead of using referential equality
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing as mentioned in the assert interface tests about adding a non-deep test to demonstrate strict equality.

@@ -1051,6 +1051,23 @@ describe('should', function() {
testMap.should.not.have.any.keys([20, 1, {13: 37}]);
testMap.should.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);

// Using the same assertions as above but with `.deep` flag instead of using referential equality
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing as mentioned in the assert interface tests about adding a non-deep test to demonstrate strict equality.

@@ -1131,6 +1158,26 @@ describe('should', function() {
testSet.should.not.have.any.keys([20, 1, {13: 37}]);
testSet.should.not.have.all.keys([aKey, {'iDoNot': 'exist'}]);

// Using the same assertions as above but with `.deep` flag instead of using referential equality
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing as mentioned in the assert interface tests about adding a non-deep test to demonstrate strict equality.

@lucasfcosta
Copy link
Member Author

lucasfcosta commented Sep 22, 2016

Here it is!
So, with the removal of the if conditions from the assert interface this becomes a breaking change.

Please let me know if I missed something.

I'd also like to add a note here for my future self: it would be nice to refactor these methods in order for them to support what I've said in this comment and also throw an error indicating keys are required when no keys are passed for the other combination of keys assertions other than the ones I mentioned there.

@meeber
Copy link
Contributor

meeber commented Sep 25, 2016

@lucasfcosta I like the extra tests you added since the last commit on the assert interface that demonstrate that strict equality is used by default, but I think similar tests should be added on the expect and should interfaces, just for consistency.

@lucasfcosta
Copy link
Member Author

@meeber, seems adequate!
Good idea 😄
I'm gonna do it later today, thanks for noticing.

@lucasfcosta
Copy link
Member Author

@meeber here it is!
I think we've got everything covered by now.
I added tests to see if every combination of have, contain, all and any is using strict equality.

@meeber
Copy link
Contributor

meeber commented Sep 27, 2016

@lucasfcosta Well done sir! LGTM! The only way this could be better is if we add another 5 or 6 interfaces so you can add all of the same tests on those interfaces too! Wouldn't that be fun?! :D

Pinging @keithamus and @vieiralucas!

@vieiralucas
Copy link
Member

As I have said previously, this is awesome work.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inspect doesn't work properly for Maps and Sets - It displays an empty object
4 participants