-
-
Notifications
You must be signed in to change notification settings - Fork 700
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
deepEqual may ignore object's null/undefined properties, by configuration #332
Comments
Sorry for late reply @jpnovais. Thanks for the issue! I'd like to learn a little bit more about the use case before we go forward with implementing code. I'd argue that the test should be as strict as possible, and in fact I don't speak for the community, so if there is a strong support for this then I believe we should implement it, but I'd personally like to see a stronger use case because I think the current behaviour is correct. Now, if we were to go down the road of implementing some kind of flag to disregard undefined values, I'd recommend it become a property - perhaps something like |
Found this issue when I was looking for a way to easily implement a test for a REST API. We are writing a JSONAPI compliant API. For POST actions, the specs say that the server should generate the IDs in case none are provided. So, a request such as this
Should yield a response like this:
The ideal solution for us (of course, unless there's a better idea around) would be to perform a comparison that ignores the id of the request JSON object when comparing to the response. And I agree that modifying global behavior would be less the ideal. For example, the same specs say that when posting with a client-generated ID, it should be stored as-is, so we would not be able to globally ignore an attribute. |
if this were available it may be possible to work around #304 |
Having a re-read of this, it seems like this is more like #72 right? It seems like what @jpnovais and @dclucas would get most benefit from is a expect({ a: 1, b: 2, c: 3 }).to.have.subset({ a: 1 }); Thoughts? |
expect({ a: 1, b: 2, c: 3 }).to.loose.eql({ a: 1, b: 2 });
// FAIL - property c is not expected
expect({ a: 1, b: 2, c: undefined }).to.loose.eql({ a: 1, b: 2 });
// PASS - property c is undefined so it's ignored
expect({ a: 1, b: 2, c: null }).to.loose.eql({ a: 1, b: 2 });
// FAIL/PASS? - property c is null. should null properties be ignored as well? Is it useful (makes sense) to have a property like this? |
+1 |
Hello guys, thanks for your feedback! 😄 We currently have this, I think it could help you solve a big part of this problem. I think it would be easy to design a workaround using it. Maybe you could write something like: var obj = { a: 1, b: 2, c: undefined, d: null };
var subset = {};
for (let key of Object.keys(obj)) {
if (obj[key] !== null && obj[key] !== undefined) {
subset[key] = obj[key];
}
}
expect(obj).to.include.subset(subset); I'm not sure this use case is common enough for us to have a specific assertion for this, maybe a flag would be enough, but even then it would be easy to design a workaround and maybe some people would like to ignore just |
Once nesting and recursion become involved, the semantics for 'ignore undefined' becomes more complicated. For top-level key stuff, As an alt. proposal... maybe having a utility function that does the 'subsetting' could be useful? Turning @lucasfcosta 's code above into a (js5!) function, for example. |
Hi @gregglind, thanks for sharing your opinion! If you are interested in it you can take a look at _.pickBy(). |
Thanks everyone for your feedback on this issue. We've got a plan for this in our Roadmap https://github.com/chaijs/chai/projects/2! It'll likely be different to what @jpnovais proposed, but rest assured this is something we'll have a good way of handling come chai 5. We'll be releasing chai 5 soon, but for now I'll close this issue because it is tracked on our roadmap. |
Hi @keithamus . The roadmap is a moving artifact, and I think it no longer references what it did at the time you wrote that. Can you name / precise / link to the precise feature of chai 5 you were talking about? Thanks 🙂. |
Sure @ronjouch! Specifically https://github.com/chaijs/chai/projects/2#card-10444381 and https://github.com/chaijs/chai/projects/2#card-10444260 capture the desired functionality. This is a matcher API which would allow you to pass expectations as properties in a deep-eql assertion, e.g. expect({ a: 1, b: 2, c: 3 }).to.deep.eql({ a: 1, b: 2, c: expect.to.be.a('number') }); or in the case of the OPs example for a users table you could do something like: expect(usersBD['alice']).to.eql({
login: 'alice',
password: expect.to.be.a('string').with.lengthOf(40),
lastLogin: expect.to.be.a('string'),
company: 'Wonderland'
}); // success If you're looking for an assertion which only tests the existance of some keys, we already have this available. But we think having a matcher API to make more broad assertions on object properties is the right direction here. |
Hi, @keithamus I am trying to implement it: |
This is not a feature yet, but it is a sketch for a future API |
I think it would be nice to have a chai configuration property to set chai to ignore
null
orundefined
properties on object deepEqual assertion (e.g.chai.config.ignoreNullOrUndefinedProperties = true
).This is useful for instance when we want to filter objects's properties before serialization (e.g REST APIs). These objects may have optional properties set to
undefined
which won't be serialized. Example:For this simple case scenario, I cloud do something like:
But sometimes we have several optional properties which will require more verbose code polluted with
if
statements.Currently I overcome this with
JSON.stringify
.Is this a good feature, does it meet chai purpose?
The text was updated successfully, but these errors were encountered: