-
Notifications
You must be signed in to change notification settings - Fork 526
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
JSONPath includes on collection with single entry does not work #1469
Comments
Hi @janwytze, In fact, the issue comes from the fact that the jsonpath returns a single value. Standard jsonpath always returns a collection, which most of the time is not meaningful, and harder to test. Here are a few examples for ilustration. Here are 2 inputs
For the jsonpath For the jsonpath |
@fabricereix with one of the most supported Java library https://github.com/json-path/JsonPath, we have this result: import com.jayway.jsonpath.Configuration
import com.jayway.jsonpath.JsonPath
fun main() {
val json = """
[
{
"id": 1,
"name": "car"
}
]
""".trimIndent()
val document = Configuration.defaultConfiguration().jsonProvider().parse(json)
val resultA: Int = JsonPath.read(document, "$[0].id");
assert(resultA == 1)
val resultB: List<Int> = JsonPath.read(document, "$[*].id");
assert(resultB == listOf(1))
} which corresponds well to the defined the target behaviour in your response (different from the current Hurl implementation).
|
@fabricereix One of the guys on our team also ran into this and lost an hour trying to figure out why hurl's JSONPath implementation was not returning the standard syntax. I would urge the Hurl team to consider changing this behavior in an upcoming major release to make Hurl's JSONPath as standards-compliant and intuitive as possible. The decision to coerce single-entry arrays to an object is very problematic. I have seen many products / tools do this "as a convenience" and it always turns out to cause problems. The big issue is that the data set you're querying against is not always deterministic ---> if a query might return 1 record but sometimes returns 2+, then it's impossible to use Hurl to reliably test this, because you can't even assert on the count, you have to do some sort of crazy "duck-typing" to check whether the result of the jsonpath is an object or an array before running any further assertions, which is way more cumbersome and confusing than simply doing a Having a consistent, standards-compliant API is far better than trying to save developers from having to enter the 3 characters |
yes, as explained in the previous comments, we will remove this single-entry coercion. |
@zachelrath we have choose a compromise between being strictly compliant to the spec https://goessner.net/articles/JsonPath/ and introducing some convenience. We have looked at various implementations of JSONPath in different languages, and you can find the same behaviour : Regarding this JSON: {
"welcome": {
"message": ["Hello World!"]
}
} And the following JSONPath query:
In the documentation:
I'm sure you can find various library that return an array, regarding of the queries, including https://goessner.net/articles/JsonPath/ and https://jsonpath.com. But, you can agree that Hurl is not the only tool/package to return the "natural" value of a query ("natural" is subjective of course). I'm just saying that what you find not a good choice, can been also seen as a good/pragmatic choice by other (including us!). Currently, what we've implemented: Given: {
"welcome": {
"message": ["Hello World!"]
}
}
What we're going to change:
Regarding duck typing, we don't support schemas for the moment but we'll add JSON Schema in the future (see #543). You have also a very basic type assertions with predicates: That say, it also always good to discuss with some JSON samples and query. Would you be able to give us some sample that have been problematic? |
What is the current bug behavior?
Using the
includes
assertion on a collection with a single item does not work.Steps to reproduce
When I run the assertion
jsonpath "$[*].id" includes 4
on the following response is will return an error:The error:
But when there are multiple entries the assertion does not fail.
What is the expected correct behavior?
The above assertion should be true, even on a single item
Execution context
hurl --version
):P.S. Is there a way to use and/or with assertions? Then I could use
jsonpath "$[*].id" includes 4 || jsonpath "$[*].id" == 4
The text was updated successfully, but these errors were encountered: