File: test_env.py

package info (click to toggle)
python-jsonpath 2.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,028 kB
  • sloc: python: 9,473; makefile: 6
file content (220 lines) | stat: -rw-r--r-- 7,296 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
"""JSONPathEnvironment API test cases."""

import asyncio
from typing import List

import pytest

from jsonpath import JSONPathEnvironment
from jsonpath import JSONPathSyntaxError
from jsonpath import JSONPathTypeError


@pytest.fixture()
def env() -> JSONPathEnvironment:
    return JSONPathEnvironment()


def test_find_all_from_object(env: JSONPathEnvironment) -> None:
    """Test that we can pass a Python object to findall."""
    rv = env.findall("$.some", {"some": 1, "thing": 2})
    assert rv == [1]


def test_find_all_from_json_string(env: JSONPathEnvironment) -> None:
    """Test that we can pass a JSON string to findall."""
    rv = env.findall("$.some", '{"some": 1, "thing": 2}')
    assert rv == [1]


def test_find_all_with_extra_filter_context(env: JSONPathEnvironment) -> None:
    """Test that we can pass extra filter context to findall."""
    rv = env.findall(
        "$[?(@.some == _.other)]",
        {"foo": {"some": 1, "thing": 2}},
        filter_context={"other": 1},
    )
    assert rv == [{"some": 1, "thing": 2}]


def test_find_iter_from_object(env: JSONPathEnvironment) -> None:
    """Test that we can pass a Python object to finditer."""
    matches = env.finditer("$.some", {"some": 1, "thing": 2})
    assert [match.obj for match in matches] == [1]


def test_find_iter_from_json_string(env: JSONPathEnvironment) -> None:
    """Test that we can pass a JSON string to finditer."""
    matches = env.finditer("$.some", '{"some": 1, "thing": 2}')
    assert [match.obj for match in matches] == [1]


def test_find_iter_with_extra_filter_context(env: JSONPathEnvironment) -> None:
    """Test that we can pass extra filter context to finditer."""
    matches = env.finditer(
        "$[?(@.some == _.other)]",
        {"foo": {"some": 1, "thing": 2}},
        filter_context={"other": 1},
    )
    assert [match.obj for match in matches] == [{"some": 1, "thing": 2}]


def test_find_all_async_from_object(env: JSONPathEnvironment) -> None:
    """Test that we can pass a Python object to findall_async."""

    async def coro() -> List[object]:
        return await env.findall_async("$.some", {"some": 1, "thing": 2})

    assert asyncio.run(coro()) == [1]


def test_find_all_async_from_json_string(env: JSONPathEnvironment) -> None:
    """Test that we can pass a JSON string to findall."""

    async def coro() -> List[object]:
        return await env.findall_async("$.some", '{"some": 1, "thing": 2}')

    assert asyncio.run(coro()) == [1]


def test_find_all_async_with_extra_filter_context(env: JSONPathEnvironment) -> None:
    """Test that we can pass extra filter context to findall_async."""

    async def coro() -> List[object]:
        return await env.findall_async(
            "$[?(@.some == _.other)]",
            {"foo": {"some": 1, "thing": 2}},
            filter_context={"other": 1},
        )

    assert asyncio.run(coro()) == [{"some": 1, "thing": 2}]


def test_find_iter_async_from_object(env: JSONPathEnvironment) -> None:
    """Test that we can pass a Python object to finditer."""

    async def coro() -> List[object]:
        matches = await env.finditer_async("$.some", {"some": 1, "thing": 2})
        return [match.obj async for match in matches]

    assert asyncio.run(coro()) == [1]


def test_find_iter_async_from_json_string(env: JSONPathEnvironment) -> None:
    """Test that we can pass a JSON string to finditer."""

    async def coro() -> List[object]:
        matches = await env.finditer_async("$.some", '{"some": 1, "thing": 2}')
        return [match.obj async for match in matches]

    assert asyncio.run(coro()) == [1]


def test_find_iter_async_with_extra_filter_context(env: JSONPathEnvironment) -> None:
    """Test that we can pass extra filter context to finditer."""

    async def coro() -> List[object]:
        matches = await env.finditer_async(
            "$[?(@.some == _.other)]",
            {"foo": {"some": 1, "thing": 2}},
            filter_context={"other": 1},
        )
        return [match.obj async for match in matches]

    assert asyncio.run(coro()) == [{"some": 1, "thing": 2}]


def test_match(env: JSONPathEnvironment) -> None:
    """Test that we can get the first match of a path."""
    match = env.match("$.some", {"some": 1, "thing": 2})
    assert match is not None
    assert match.obj == 1


def test_no_match(env: JSONPathEnvironment) -> None:
    """Test that we get `None` if there are no matches."""
    match = env.match("$.other", {"some": 1, "thing": 2})
    assert match is None


def test_match_compound_path(env: JSONPathEnvironment) -> None:
    """Test that we can get the first match of a compound path."""
    match = env.match("$.some | $.thing", {"some": 1, "thing": 2})
    assert match is not None
    assert match.obj == 1


def test_no_match_compound_path(env: JSONPathEnvironment) -> None:
    """Test that we get `None` if there are no matches in a compound path."""
    match = env.match("$.other | $.foo", {"some": 1, "thing": 2})
    assert match is None


def test_no_unicode_escape() -> None:
    """Test that we can disable decoding of UTF-16 escape sequences."""
    document = {"𝄞": "A"}
    selector = '$["\\uD834\\uDD1E"]'

    env = JSONPathEnvironment(unicode_escape=True)
    assert env.findall(selector, document) == ["A"]

    env = JSONPathEnvironment(unicode_escape=False)
    assert env.findall(selector, document) == []
    assert env.findall(selector, {"\\uD834\\uDD1E": "B"}) == ["B"]


def test_custom_keys_selector_token() -> None:
    """Test that we can change the non-standard keys selector."""

    class MyJSONPathEnvironment(JSONPathEnvironment):
        keys_selector_token = "*~"

    env = MyJSONPathEnvironment()
    data = {"foo": {"a": 1, "b": 2, "c": 3}}
    assert env.findall("$.foo.*~", data) == ["a", "b", "c"]
    assert env.findall("$.foo.*", data) == [1, 2, 3]


def test_custom_fake_root_identifier_token() -> None:
    """Test that we can change the non-standard fake root identifier."""

    class MyJSONPathEnvironment(JSONPathEnvironment):
        pseudo_root_token = "$$"

    env = MyJSONPathEnvironment()
    data = {"foo": {"a": 1, "b": 2, "c": 3}}
    assert env.findall("$$[?@.foo.a == 1]", data) == [data]
    assert env.findall("$$[?@.foo.a == 7]", data) == []
    assert env.findall("$.*", data) == [{"a": 1, "b": 2, "c": 3}]


def test_disable_fake_root_identifier() -> None:
    """Test that we can disable the non-standard fake root identifier."""

    class MyJSONPathEnvironment(JSONPathEnvironment):
        pseudo_root_token = ""

    env = MyJSONPathEnvironment()
    with pytest.raises(JSONPathSyntaxError):
        env.compile("^[?@.a == 42]")


def test_disable_keys_selector() -> None:
    """Test that we can disable the non-standard keys selector."""

    class MyJSONPathEnvironment(JSONPathEnvironment):
        keys_selector_token = ""

    env = MyJSONPathEnvironment()
    with pytest.raises(JSONPathSyntaxError):
        env.compile("*..~")


def test_disable_well_typed_checks() -> None:
    """Test that we can disable checks for well-typedness."""
    env = JSONPathEnvironment(well_typed=True)
    with pytest.raises(JSONPathTypeError):
        env.compile("$[?@.* > 2]")

    env = JSONPathEnvironment(well_typed=False)
    env.compile("$[?@.* > 2]")