Assert against every member of a JSONPATH collection?
Hi, I'm sorry if this is an ignorant question. Let's imagine an API which returns an array of elements:
{
"data": [
{ "item": "value1" },
{ "item": "value2" },
{ "item": "value3" }
]
}
My basic use case is that I want to assert that all of the values of "item" match the pattern "value.*". Today it seems like I can do:
jsonpath "$.data[0].item" matches "value.*"
However I would really like a way to say:
jsonpath "$.data[*].item" matches "value.*"
That is to say, test each member against the regex. What seems to happen when I try this is that all of the items are concatenated, so that the match is against something like [string <value1>, string <value2>, string <value3>] (according to the output of hurl). I can see using https://jsonpath.com/ that this is due to the way jsonpath processes the input.
I tried to bend jsonpath to emit a collection of elements whose value does not match value.* (so I could assert that zero things remained) but couldn't figure it out.
Something I wondered along the way is whether it would make sense to be able to run the predicate on each value in a resultant collection. So jsonpath "$.data[*].item" EACH matches "value.*"
Thanks for your consideration! I have had good success using hurl to help me build an API gateway.
Your understanding of Hurl is good. That's also how we would do it.
In a testing/controlled environment, responses can be tested "statically" as you suggested.
jsonpath "$.data[*].item" count == 3
jsonpath "$.data[0].item" matches "value.*"
jsonpath "$.data[1].item" matches "value.*"
jsonpath "$.data[2].item" matches "value.*"
I like your "each" operator for a list. it would become very useful is the collection is very large and could be combined very nicely with the existing predicates.
jsonpath "$.values" each == 3
jsonpath "$.values" each > 0
jsonpath "$.values" each matches "value.*"
Very good idea, we could also support any or none.
jsonpath "$.values" any == 3
jsonpath "$.values" any > 0
jsonpath "$.values" any matches "value.*"
jsonpath "$.values" none == 3
jsonpath "$.values" none > 0
jsonpath "$.values" none matches "value.*"
A sidenote: in Hurl syntax, we have the notion of query and predicate. Ex:
jsonpath "$.data[0].item" matches "value.*"
query: jsonpath "$.data[0].item"
predicate: matches
predicate-value: "value.*"
If we negate:
jsonpath "$.data[0].item" not matches "value.*"
(not if part of predicate)
Using each:
jsonpath "$.values" each not matches "value.*"
jsonpath "$.values" each != "something"
each belongs definitively to the predicate https://hurl.dev/docs/asserting-response.html#predicates. It a kind of predicate iterator.
@danielbprice Thanks for the idea; is your project using Hurl Open Source so we can look at it? I'm really interested to see how other people use Hurl!
@jcamiel unfortunately it's not a piece of open source that I can share. It's an API gateway to support a single enterprise customer, mapping an older version of an API to a newer version in a situation where that was really the only option.
Also "none" and "any" seem smart. Thanks for listening.