alexjeffburke / chai-better-shallow-deep-equal

MIT License
3 stars 0 forks source link

Add option to verify key without value #2

Open kamiloski opened 3 years ago

kamiloski commented 3 years ago

I think it will be great feature to verify only key in some cases. eg I have json: { "userID":123, "randomInt":<random generated value I cannot put to my fixtures (because it is generated randomly)> } and it will be great that i can assert whole json, excluding only value - random (skipping it eg using skip), but asserting that key "randomInt" exist. So for example response above created fixture to assers eg: { "userID":123, "randomInt":skip }

kamiloski commented 3 years ago

@alexjeffburke can you comment? :)

alexjeffburke commented 3 years ago

Hi @kamiloski, thanks for you interest in the plugin, hope that it's working for you :)

With regard to your request, I'd like to first make sure I completely understand the behaviour you are after: basically, you want to be able to assert that keying into an object with a particular key returns any value that is not undefined. Assuming I've got that right, this is actually something that Unexpected (which the plugin makes use of internally) already supports. That was the good news - the bad news is that while the mechanism exists, we'd need to wrap it and expose that somehow via the plugin and I'm just not sure what the best way of going about this is.

One thing that might help is to better understand whether you really want to say that they key is any value, or whether what you really want to assert is something more specific like "the value is a number" or "the value is a string". For the record hesitancy around special casing a facility for asserting "any value" is it may encourage writing overly loose assertions.

kamiloski commented 3 years ago

Ok, I will explain you on exaple. I have fixture json file eg: { "firstName": "Tom", "lastName":"Cruse", "cashBalance: "" - I cannot put here value because if I get response from API and this value is changing dynamically - so I don't kwon what value will be there } so if I have json (fixture) like this above I want to to assert keys and values from response of firstName and lastName, but I cannot assert the value of cash balance because its dynamically (user can buy or sell sth so value of cashbalance is changing) - so I just want to know that in response from API, key cashBalance exists without checking value.

alexjeffburke commented 3 years ago

Thanks for the additional example - think I've got a pretty good handle on your use case :)

Though I think I might have not been clear with my second question - rather than just saying that you received "any value" as cashBalance, for example, would it actually be better to say that it must be a string? I'm asking because one possible design I've considered of the facility your asking is something like:

const betterShallowDeepEqual = require('chai-better-shallow-deep-equal');

const response = { /* ... */ };

expect(response).to.shallowDeepEqual({
  firstName: "Tom",
  secondName: "Cruise",
  cashBalance: betterShallowDeepEqual.checkValue((value) => {
    expect(value).to.be.a('string'); // note the nested use of chai allowing a more specific assertion
  })
})

I think I'd prefer to implement a more generic solution like this, so would you agree this would meet your use case but would actually be more specific because rather than asserting "any value" you'd be asserting "any string value"?

kamiloski commented 3 years ago

Thanks for answear, your solution is nice, but I just show you in my before example the simplest Jason. At work I’m asserting jsons with a much more values that are dynamically, so the assertion written in yours way will be very long and I get a lot of jsons with different dinamically values. So as I described in first post, it will be great if I can in my fixture json put some keyword as value to be skipped in assertion. Or if there will be a way to declare in json value type will be great, but for me it will be enough to if I can just declare value by keyword in json that should be skipped

alexjeffburke commented 3 years ago

Hi, yeah I appreciate that solution is very simple but I can't implement a special value that can be used within pure JSON files on disk that can act as "any value" - it just isn't safe to do it. Whatever value you could choose there is no value that could be guaranteed to not be valid for someone else's assertion.

Whatever the solution ends up being you should be able to easily arrange the kind of behaviour you want by choosing a magic value yourself and implementing a mapping function you pass your imported JSON fixture through which maps the magic value to, for example, the construct above (or whatever else it ends up being). To be clear, I'm not sure what I might implement for the plugin yet but it would almost certainly be some kind of export and will need to be of generic utility.