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

Add object includes a string key and exclusion test for objects #86

Merged
merged 5 commits into from
Apr 18, 2016

Conversation

calebmer
Copy link
Contributor

@calebmer calebmer commented Apr 9, 2016

First of all, thank you so much for writing this package. It makes writing tests so nice 😊. In addition this codebase is some of the best code I have ever read.

I just ran into two things which I expected to exist but didn't, this PR adds these things. Specifically this PR adds one feature and fixes one bug.

The feature this PR adds is a simple property string test for toInclude. Now, the user can ignore the value of an object and just test if a property is included in an object like so: expect({ a: 1 }).toInclude('a').

This feature also fixes a bug where objects were not enabled to be used by toExclude making it asymmetrical to toInclude which tests objects.

@@ -258,10 +258,25 @@ expect([ 1, 2, 3 ]).toExclude(4)
Asserts the given `object` contains all keys and values in `value`, recursively. The `comparator` function, if given, should compare two objects and either `return false` or `throw` if they are not equal. It defaults to `assert.deepEqual`.

```js
expect({ a: 1, b: 2 }).toInclude('a')
Copy link
Collaborator

Choose a reason for hiding this comment

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

i'm not really a fan of overloading APIs to take multiple types. I'd rather see a separate .toIncludeKeys that takes an array of strings, for example.

@ljharb
Copy link
Collaborator

ljharb commented Apr 9, 2016

I do like the toExclude change - if you could separate out the "string key" stuff in a separate PR, I could see being able to quickly update toExclude (without the string key checking, so that toInclude/toExclude are always parallel).

@@ -334,8 +334,8 @@ class Expectation {

toExclude(value, compareValues, message) {
assert(
isArray(this.actual) || typeof this.actual === 'string',
'The "actual" argument in expect(actual).toExclude() must be an array or a string'
isArray(this.actual) || isObject(this.actual) || typeof this.actual === 'string',
Copy link
Collaborator

Choose a reason for hiding this comment

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

i wonder if there's a way we could make toExclude call into toInclude, or have them share a core function, rather than duplicating the checks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Check my latest commit and tell me what you think.

@calebmer calebmer force-pushed the feat/object-include-exclude-keys branch from 45a4514 to 096af85 Compare April 9, 2016 16:26
@@ -293,77 +293,47 @@ class Expectation {
return this
}

toInclude(value, compareValues, message) {
toInclude(value, compareValues, message, _exclude = false) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Definitely not a fan of the _exclude param - this adds an obscure boolean param to the public API. Could we refactor both toInclude and toExclude to call into a private (closed-over) function instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is a precedence for this already included for the Expectation class? My next instinct would to be to create a TestUtils function.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That seems reasonable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, ammended the last commit with the core implementation in TestUtils.

@calebmer calebmer force-pushed the feat/object-include-exclude-keys branch 2 times, most recently from afce62d to 57f2343 Compare April 9, 2016 17:05
@calebmer calebmer force-pushed the feat/object-include-exclude-keys branch from 57f2343 to c103bcd Compare April 9, 2016 17:09
@calebmer
Copy link
Contributor Author

calebmer commented Apr 9, 2016

@ljharb I used the same TestUtils approach to abstracting similar functionalities between toInclude and toExclude in #87. If you make a comment that is applicable to both PRs (#86 and #87) I will change it in both.

*/
export const containsHelper = (actual, value, compareValues, exclude, funcName, message) => {
if (compareValues == null)
compareValues = isEqual
Copy link
Collaborator

Choose a reason for hiding this comment

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

could this be done with default values in the signature instead?

@ljharb
Copy link
Collaborator

ljharb commented Apr 9, 2016

In general I think this looks great overall - I like the reduced code duplication, and the new docs/tests are solid.

@calebmer
Copy link
Contributor Author

@mjackson what's the status on this PR and #87?

value
)
}
containsHelper(
Copy link
Owner

Choose a reason for hiding this comment

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

I know this probably sounds silly, but I think I'd prefer to leave the branching in this method rather than tuck it away under containsHelper. It personally makes it easier for me to read the code and figure out e.g. what kinds of actual values toInclude accepts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, doesn't sound silly. Would you prefer duplicating the logic or adding a private boolean switch as an undocumented parameter to switch the behavior like I had before?

Copy link
Collaborator

Choose a reason for hiding this comment

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

My vote is to duplicate the logic rather than adding public API.

Copy link
Owner

Choose a reason for hiding this comment

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

I'd like to see it with the logic duplicated for now. We can take another pass at it later if it becomes ridiculously long.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds great 👍

@mjackson
Copy link
Owner

mjackson commented Apr 18, 2016

Hi @calebmer – thanks for your work here! I'm sorry to be slow on the response. Just got back from 2 weeks away. I like the docs updates, additional tests, and support for objects in toExclude, but I'd prefer to leave the code branching inline in the toInclude/toExclude methods because it's a little easier for me to read that way. Would you mind making those changes? I'll get this merged ASAP. Thanks!

}

assert(
Copy link
Owner

Choose a reason for hiding this comment

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

👏 Well done. This is some de-duplication I can live with!

@mjackson mjackson merged commit a78e970 into mjackson:master Apr 18, 2016
@calebmer calebmer deleted the feat/object-include-exclude-keys branch April 18, 2016 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants