Skip to content

Commit e087f70

Browse files
committed
Remember to test async path too
1 parent 225f686 commit e087f70

12 files changed

+233
-91
lines changed

jsonpath/path.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,14 @@ def finditer(
123123
an incompatible way.
124124
"""
125125
_data = load_data(data)
126+
path = self.env.pseudo_root_token if self.pseudo_root else self.env.root_token
127+
126128
matches: Iterable[JSONPathMatch] = [
127129
JSONPathMatch(
128130
filter_context=filter_context or {},
129131
obj=[_data] if self.pseudo_root else _data,
130132
parent=None,
131-
path=self.env.root_token,
133+
path=path,
132134
parts=(),
133135
root=_data,
134136
)
@@ -161,13 +163,14 @@ async def finditer_async(
161163
) -> AsyncIterable[JSONPathMatch]:
162164
"""An async version of `finditer()`."""
163165
_data = load_data(data)
166+
path = self.env.pseudo_root_token if self.pseudo_root else self.env.root_token
164167

165168
async def root_iter() -> AsyncIterable[JSONPathMatch]:
166169
yield self.env.match_class(
167170
filter_context=filter_context or {},
168171
obj=[_data] if self.pseudo_root else _data,
169172
parent=None,
170-
path=self.env.root_token,
173+
path=path,
171174
parts=(),
172175
root=_data,
173176
)

tests/pseudo_root_identifier.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"tests": [
3+
{
4+
"name": "conditionally select root value",
5+
"selector": "^[[email protected] > 7]",
6+
"document": { "some": { "thing": 42 } },
7+
"result": [{ "some": { "thing": 42 } }],
8+
"result_paths": ["^[0]"],
9+
"tags": ["extra"]
10+
},
11+
{
12+
"name": "embedded pseudo root query",
13+
"selector": "^[[email protected] > value(^.*.num)]",
14+
"document": { "some": { "thing": 42 }, "num": 7 },
15+
"result": [{ "some": { "thing": 42 }, "num": 7 }],
16+
"result_paths": ["^[0]"],
17+
"tags": ["extra"]
18+
},
19+
{
20+
"name": "embedded root query",
21+
"selector": "^[[email protected] > value($.num)]",
22+
"document": { "some": { "thing": 42 }, "num": 7 },
23+
"result": [{ "some": { "thing": 42 }, "num": 7 }],
24+
"result_paths": ["^[0]"],
25+
"tags": ["extra"]
26+
}
27+
]
28+
}

tests/test_current_key_identifier.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import json
23
import operator
34

@@ -34,6 +35,25 @@ def test_current_key_identifier(env: JSONPathEnvironment, case: Case) -> None:
3435
assert nodes.paths() == case.result_paths
3536

3637

38+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
39+
def test_current_key_identifier_async(env: JSONPathEnvironment, case: Case) -> None:
40+
async def coro() -> NodeList:
41+
assert case.document is not None
42+
it = await env.finditer_async(case.selector, case.document)
43+
return NodeList([node async for node in it])
44+
45+
nodes = asyncio.run(coro())
46+
47+
if case.results is not None:
48+
assert case.results_paths is not None
49+
assert nodes.values() in case.results
50+
assert nodes.paths() in case.results_paths
51+
else:
52+
assert case.result_paths is not None
53+
assert nodes.values() == case.result
54+
assert nodes.paths() == case.result_paths
55+
56+
3757
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
3858
def test_current_key_identifier_fails_in_strict_mode(case: Case) -> None:
3959
env = JSONPathEnvironment(strict=True)

tests/test_find.py

Lines changed: 0 additions & 89 deletions
This file was deleted.

tests/test_issues.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,15 @@ def test_issue_103() -> None:
6767
]
6868

6969
assert findall(query, data, filter_context=filter_context) == want
70+
71+
72+
def test_quoted_reserved_word_and() -> None:
73+
query = "$['and']"
74+
data = {"and": [1, 2, 3]}
75+
assert findall(query, data) == [[1, 2, 3]]
76+
77+
78+
def test_quoted_reserved_word_or() -> None:
79+
query = "$['or']"
80+
data = {"or": [1, 2, 3]}
81+
assert findall(query, data) == [[1, 2, 3]]

tests/test_key_selector.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import json
23
import operator
34

@@ -34,6 +35,25 @@ def test_key_selector(env: JSONPathEnvironment, case: Case) -> None:
3435
assert nodes.paths() == case.result_paths
3536

3637

38+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
39+
def test_key_selector_async(env: JSONPathEnvironment, case: Case) -> None:
40+
async def coro() -> NodeList:
41+
assert case.document is not None
42+
it = await env.finditer_async(case.selector, case.document)
43+
return NodeList([node async for node in it])
44+
45+
nodes = asyncio.run(coro())
46+
47+
if case.results is not None:
48+
assert case.results_paths is not None
49+
assert nodes.values() in case.results
50+
assert nodes.paths() in case.results_paths
51+
else:
52+
assert case.result_paths is not None
53+
assert nodes.values() == case.result
54+
assert nodes.paths() == case.result_paths
55+
56+
3757
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
3858
def test_key_selector_fails_in_strict_mode(case: Case) -> None:
3959
env = JSONPathEnvironment(strict=True)

tests/test_keys_filter_selector.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import json
23
import operator
34

@@ -34,6 +35,25 @@ def test_keys_filter_selector(env: JSONPathEnvironment, case: Case) -> None:
3435
assert nodes.paths() == case.result_paths
3536

3637

38+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
39+
def test_keys_filter_selector_async(env: JSONPathEnvironment, case: Case) -> None:
40+
async def coro() -> NodeList:
41+
assert case.document is not None
42+
it = await env.finditer_async(case.selector, case.document)
43+
return NodeList([node async for node in it])
44+
45+
nodes = asyncio.run(coro())
46+
47+
if case.results is not None:
48+
assert case.results_paths is not None
49+
assert nodes.values() in case.results
50+
assert nodes.paths() in case.results_paths
51+
else:
52+
assert case.result_paths is not None
53+
assert nodes.values() == case.result
54+
assert nodes.paths() == case.result_paths
55+
56+
3757
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
3858
def test_keys_filter_selector_fails_in_strict_mode(case: Case) -> None:
3959
env = JSONPathEnvironment(strict=True)

tests/test_keys_selector.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import json
23
import operator
34

@@ -34,6 +35,25 @@ def test_keys_selector(env: JSONPathEnvironment, case: Case) -> None:
3435
assert nodes.paths() == case.result_paths
3536

3637

38+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
39+
def test_keys_selector_async(env: JSONPathEnvironment, case: Case) -> None:
40+
async def coro() -> NodeList:
41+
assert case.document is not None
42+
it = await env.finditer_async(case.selector, case.document)
43+
return NodeList([node async for node in it])
44+
45+
nodes = asyncio.run(coro())
46+
47+
if case.results is not None:
48+
assert case.results_paths is not None
49+
assert nodes.values() in case.results
50+
assert nodes.paths() in case.results_paths
51+
else:
52+
assert case.result_paths is not None
53+
assert nodes.values() == case.result
54+
assert nodes.paths() == case.result_paths
55+
56+
3757
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
3858
def test_keys_selector_fails_in_strict_mode(case: Case) -> None:
3959
env = JSONPathEnvironment(strict=True)

tests/test_membership_operators.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import json
23
import operator
34

@@ -34,6 +35,25 @@ def test_membership_operators(env: JSONPathEnvironment, case: Case) -> None:
3435
assert nodes.paths() == case.result_paths
3536

3637

38+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
39+
def test_membership_operators_async(env: JSONPathEnvironment, case: Case) -> None:
40+
async def coro() -> NodeList:
41+
assert case.document is not None
42+
it = await env.finditer_async(case.selector, case.document)
43+
return NodeList([node async for node in it])
44+
45+
nodes = asyncio.run(coro())
46+
47+
if case.results is not None:
48+
assert case.results_paths is not None
49+
assert nodes.values() in case.results
50+
assert nodes.paths() in case.results_paths
51+
else:
52+
assert case.result_paths is not None
53+
assert nodes.values() == case.result
54+
assert nodes.paths() == case.result_paths
55+
56+
3757
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
3858
def test_membership_operators_fail_in_strict_mode(case: Case) -> None:
3959
env = JSONPathEnvironment(strict=True)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import asyncio
2+
import json
3+
import operator
4+
5+
import pytest
6+
7+
from jsonpath import JSONPathEnvironment
8+
from jsonpath import JSONPathSyntaxError
9+
from jsonpath import NodeList
10+
11+
from ._cts_case import Case
12+
13+
14+
@pytest.fixture()
15+
def env() -> JSONPathEnvironment:
16+
return JSONPathEnvironment(strict=False)
17+
18+
19+
with open("tests/pseudo_root_identifier.json", encoding="utf8") as fd:
20+
data = [Case(**case) for case in json.load(fd)["tests"]]
21+
22+
23+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
24+
def test_pseudo_root_identifier(env: JSONPathEnvironment, case: Case) -> None:
25+
assert case.document is not None
26+
nodes = NodeList(env.finditer(case.selector, case.document))
27+
28+
if case.results is not None:
29+
assert case.results_paths is not None
30+
assert nodes.values() in case.results
31+
assert nodes.paths() in case.results_paths
32+
else:
33+
assert case.result_paths is not None
34+
assert nodes.values() == case.result
35+
assert nodes.paths() == case.result_paths
36+
37+
38+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
39+
def test_pseudo_root_identifier_async(env: JSONPathEnvironment, case: Case) -> None:
40+
async def coro() -> NodeList:
41+
assert case.document is not None
42+
it = await env.finditer_async(case.selector, case.document)
43+
return NodeList([node async for node in it])
44+
45+
nodes = asyncio.run(coro())
46+
47+
if case.results is not None:
48+
assert case.results_paths is not None
49+
assert nodes.values() in case.results
50+
assert nodes.paths() in case.results_paths
51+
else:
52+
assert case.result_paths is not None
53+
assert nodes.values() == case.result
54+
assert nodes.paths() == case.result_paths
55+
56+
57+
@pytest.mark.parametrize("case", data, ids=operator.attrgetter("name"))
58+
def test_pseudo_root_identifier_fails_in_strict_mode(case: Case) -> None:
59+
env = JSONPathEnvironment(strict=True)
60+
61+
with pytest.raises(JSONPathSyntaxError):
62+
env.compile(case.selector)

0 commit comments

Comments
 (0)