karate icon indicating copy to clipboard operation
karate copied to clipboard

Feature request: contains deep only

Open ericdriggs opened this issue 1 year ago • 2 comments

Feature: match contains deep only

#Current matchers don't have a syntax for a 1 line order insensitive exact values match #Single line, order insensitive matching is actually they behavior I would prefer 99.99% of the time #and it would be my vote to have this be the default behvaior of the == operator #barring this, match deep only (or similar syntax) would address this use case

Background: * def expected = { "a": [1, 2, 3, 4, 5] } * def actualLarger = { "a": [1, 2, 3, 5, 4, 6] } * def actualDifferentOrder = { "a": [1, 2, 3, 5, 4] }

#######

#fails per spec -- would love to see this pass by default as imo it's the least surprise behavior Scenario: match equality per spec doesn't ignore order * match expected == actualDifferentOrder

#######

#passes per spec -- this is the correct behavior Scenario: by design 'match contains deep' ignores ordering but allows for extra entries

* match actualLarger contains deep expected

#######

#doesn't exist -- would solve this use case #no preference on 'contains deep only' vs 'contains only deep' Scenario: 'match contains deep only' would allow for order-insensitive exact value comparisons

* def expected = { "a": [1, 2, 3, 4, 5] }
* def actual = { "a": [1, 2, 3, 5, 4, 6] }
* match actualDifferentOrder contains deep only expected`

ericdriggs avatar Aug 18 '22 21:08 ericdriggs

@ericdriggs okay, will consider for investigation. the assumption was the order of arrays ALWAYS matters, for example a list of "history" items, etc.

I do think a way to do an "exact but ignore array order" match is useful.

suggestions welcome for alternate syntax. contains only deep sounds good to me

ptrthomas avatar Aug 19 '22 03:08 ptrthomas

After looking through JSON specs, I agree that by default json array ordering is important and should be strict.

ericdriggs avatar Aug 19 '22 19:08 ericdriggs

@ericdriggs implemented. do try it out.

so this should work:

* def response = { foo: [ 'a', 'b' ] }
* match response contains only deep { foo: [ 'b', 'a' ] }

once you test a few cases, we can consider a short-cut for this, for example:

* match response ^= { foo: [ 'b', 'a' ] }

I would vote for this being the only short-cut we allow in the match syntax. we can also add it to the "inline" short-cuts here: https://github.com/karatelabs/karate#contains-short-cuts

ptrthomas avatar Nov 01 '22 09:11 ptrthomas

1.3.0 released

ptrthomas avatar Nov 02 '22 17:11 ptrthomas