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
|
import asyncio
import dataclasses
import operator
from typing import Any
from typing import List
from typing import Mapping
from typing import Sequence
from typing import Union
import pytest
from jsonpath import JSONPathEnvironment
@dataclasses.dataclass
class Case:
description: str
path: str
data: Union[Sequence[Any], Mapping[str, Any]]
want: Union[Sequence[Any], Mapping[str, Any]]
SOME_OBJECT = object()
TEST_CASES = [
Case(
description="type of a string",
path="$.some[?is(@.thing, 'string')]",
data={"some": [{"thing": "foo"}]},
want=[{"thing": "foo"}],
),
Case(
description="not a string",
path="$.some[?is(@.thing, 'string')]",
data={"some": [{"thing": 1}]},
want=[],
),
Case(
description="type of undefined",
path="$.some[?is(@.other, 'undefined')]", # things without `other`
data={"some": [{"thing": "foo"}]},
want=[{"thing": "foo"}],
),
Case(
description="'missing' is an alias for 'undefined'",
path="$.some[?is(@.other, 'missing')]", # things without `other`
data={"some": [{"thing": "foo"}]},
want=[{"thing": "foo"}],
),
Case(
description="type of None",
path="$.some[?is(@.thing, 'null')]",
data={"some": [{"thing": None}]},
want=[{"thing": None}],
),
Case(
description="type of array-like",
path="$.some[?is(@.thing, 'array')]",
data={"some": [{"thing": [1, 2, 3]}]},
want=[{"thing": [1, 2, 3]}],
),
Case(
description="type of mapping",
path="$.some[?is(@.thing, 'object')]",
data={"some": [{"thing": {"other": 1}}]},
want=[{"thing": {"other": 1}}],
),
Case(
description="type of bool",
path="$.some[?is(@.thing, 'boolean')]",
data={"some": [{"thing": True}]},
want=[{"thing": True}],
),
Case(
description="type of int",
path="$.some[?is(@.thing, 'number')]",
data={"some": [{"thing": 1}]},
want=[{"thing": 1}],
),
Case(
description="type of float",
path="$.some[?is(@.thing, 'number')]",
data={"some": [{"thing": 1.1}]},
want=[{"thing": 1.1}],
),
Case(
description="none of the above",
path="$.some[?is(@.thing, 'object')]",
data={"some": [{"thing": SOME_OBJECT}]},
want=[{"thing": SOME_OBJECT}],
),
]
@pytest.fixture()
def env() -> JSONPathEnvironment:
return JSONPathEnvironment()
@pytest.mark.parametrize("case", TEST_CASES, ids=operator.attrgetter("description"))
def test_isinstance_function(env: JSONPathEnvironment, case: Case) -> None:
path = env.compile(case.path)
assert path.findall(case.data) == case.want
@pytest.mark.parametrize("case", TEST_CASES, ids=operator.attrgetter("description"))
def test_isinstance_function_async(env: JSONPathEnvironment, case: Case) -> None:
path = env.compile(case.path)
async def coro() -> List[object]:
return await path.findall_async(case.data)
assert asyncio.run(coro()) == case.want
|