-
Notifications
You must be signed in to change notification settings - Fork 6
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
Add a non-deterministic test not involving objects #66
Conversation
The non-determinism in this case arises because of the interleaving of descendants allowed by RFC 9535 Section 2.5.2.2. Note that there is more non-determinism in the ordering of descendants, but much of this is removed by the applications of the child wildcard ([*]). The list of the input node and its descendants (the result of .. before [*] is applied) can be in any of these orders: [[[[1]],[2]],[[1]],[1],[2],1,2] [[[[1]],[2]],[[1]],[1],[2],2,1] [[[[1]],[2]],[[1]],[1],1,[2],2] [[[[1]],[2]],[[1]],[2],[1],1,2] [[[[1]],[2]],[[1]],[2],[1],2,1] [[[[1]],[2]],[[1]],[2],2,[1],1] Notice that these all satisfy the rules in Section 2.5.2.2: * nodes of any array are visited in array order, and * nodes are visited before their descendants. Ref: https://github.com/glyn/jsonpath-nondeterminism
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The examples in your opening comment don't exactly line up with this test, but I get the point.
[[[1]],[2],[1],1,2], | ||
[[[1]],[2],[1],2,1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect we'd want all of the orderings here.
These should be valid as well, right?
[[[1]],[1],1,[2],2]
[[[1]],[1],[2],1,2]
[[[1]],[1],[2],2,1]
[[[1]],[2],2,[1],1]
I think the only constraints are:
[[1]]
comes before[2]
(array order) and[1]
(descendant)[2]
comes before2
(descendant)[1]
comes before1
(descendant)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there's a way we can express the constraints themselves rather than listing all of the possibilities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be valid as well, right?
Although valid permutations, applying the wildcard selector to 1
and 2
will never produce a node, so their position has no impact on the resulting node list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applying the wildcard selector to 1 and 2 will never produce a node
They don't have to produce a node for these orderings. I'm not sure what point you're making.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might have misunderstood what you were saying 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect we'd want all of the orderings here.
These should be valid as well, right?
[[[1]],[1],1,[2],2] [[[1]],[1],[2],1,2] [[[1]],[1],[2],2,1] [[[1]],[2],2,[1],1]
No, these are the result of ..
before [*]
is applied. See section 2.5.2.2 of the RFC. Actually, I made the same mistake the other day, see "Confession" in my recent blog post.
I think the only constraints are:
* `[[1]]` comes before `[2]` (array order) and `[1]` (descendant) * `[2]` comes before `2` (descendant) * `[1]` comes before `1` (descendant)
Those are constraints on the traversal order. The RFC requires that [*]
is applied to the input node and its descendants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there's a way we can express the constraints themselves rather than listing all of the possibilities.
@gregsdennis I've given that a lot of thought. The best description of the constraints that I know of is in the RFC, but that's not amenable to coding in a testcase. The difficulty is that a mixture of deterministically and non-deterministically ordered subsections are flattened into the resultant nodelist and it's very hard to keep track of what's going on. If someone can think of a way of encoding this rather than listing all the possibilities, that would be very interesting. For the moment, I think generating the list of possibilities is the most reliable approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are the result of
..
before[*]
is applied.
This doesn't make sense. ..
on its own doesn't do anything. It merely informs the [*]
that it should recurse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are the result of
..
before[*]
is applied.This doesn't make sense.
..
on its own doesn't do anything. It merely informs the[*]
that it should recurse.
That's not what RFC 9535 says. Section 2.5.2.2 explains the semantics of ..[<selectors>]
in terms of first visiting the input value and its descendants to form the list of nodes D1, ..., Dn (where n >= 1 and D1 is the input value).
So that's the semantics of the ..
part of ..[*]
, even though ..
on its own is not valid syntax in the RFC.
Then, and this is crucial, the RFC says:
For each i such that 1 <= i <= n, the nodelist Ri is defined to be a result of applying the child segment [] to the node Di.
So, in this example, we need to apply [*]
to each of the input node and its descendants. We then concatenate the resultant nodelists to form the result of ..[*]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're confident that these are the only two possibilities, I'm happy to go with it. I still don't understand why the others I listed aren't valid outputs, though.
I've cobbled together a nondeterministic recursive descent visitor in JSON-P3 (PR #9). It does, after enough test runs, produce each of the valid orderings listed here, and the results match those in this PR. 👍 |
The non-determinism in this case arises because of the interleaving of descendants allowed by RFC 9535 Section 2.5.2.2.
Note that there is more non-determinism in the ordering of descendants, but much of this is removed by the applications of the child wildcard ([*]).
The list of the input node and its descendants (the result of .. before [*] is applied) can be in any of these orders:
[[[[1]],[2]],[[1]],[1],[2],1,2]
[[[[1]],[2]],[[1]],[1],[2],2,1]
[[[[1]],[2]],[[1]],[1],1,[2],2]
[[[[1]],[2]],[[1]],[2],[1],1,2]
[[[[1]],[2]],[[1]],[2],[1],2,1]
[[[[1]],[2]],[[1]],[2],2,[1],1]
Notice that these all satisfy the rules in Section 2.5.2.2:
Ref: https://github.com/glyn/jsonpath-nondeterminism
/cc @gregsdennis @jg-rp @f3ath @hiltontj who were involved in the initial discussion of non-deterministic tests.