|
16 | 16 | # specific language governing permissions and limitations
|
17 | 17 | # under the License.
|
18 | 18 |
|
19 |
| -import sys |
20 | 19 | import uuid
|
21 | 20 | from datetime import datetime
|
22 | 21 | from decimal import Decimal
|
|
33 | 32 |
|
34 | 33 | from elasticsearch import Elasticsearch
|
35 | 34 | from elasticsearch.exceptions import SerializationError
|
36 |
| -from elasticsearch.serializer import JSONSerializer, TextSerializer |
| 35 | +from elasticsearch.serializer import JSONSerializer, OrjsonSerializer, TextSerializer |
37 | 36 |
|
38 | 37 | requires_numpy_and_pandas = pytest.mark.skipif(
|
39 |
| - np is None or pd is None, reason="Test requires numpy or pandas to be available" |
| 38 | + np is None or pd is None, reason="Test requires numpy and pandas to be available" |
40 | 39 | )
|
41 | 40 |
|
42 | 41 |
|
43 |
| -def test_datetime_serialization(): |
44 |
| - assert b'{"d":"2010-10-01T02:30:00"}' == JSONSerializer().dumps( |
| 42 | +@pytest.fixture(params=[JSONSerializer, OrjsonSerializer]) |
| 43 | +def json_serializer(request: pytest.FixtureRequest): |
| 44 | + yield request.param() |
| 45 | + |
| 46 | + |
| 47 | +def test_datetime_serialization(json_serializer): |
| 48 | + assert b'{"d":"2010-10-01T02:30:00"}' == json_serializer.dumps( |
45 | 49 | {"d": datetime(2010, 10, 1, 2, 30)}
|
46 | 50 | )
|
47 | 51 |
|
48 | 52 |
|
49 |
| -def test_decimal_serialization(): |
50 |
| - requires_numpy_and_pandas() |
51 |
| - |
52 |
| - if sys.version_info[:2] == (2, 6): |
53 |
| - pytest.skip("Float rounding is broken in 2.6.") |
54 |
| - assert b'{"d":3.8}' == JSONSerializer().dumps({"d": Decimal("3.8")}) |
| 53 | +@requires_numpy_and_pandas |
| 54 | +def test_decimal_serialization(json_serializer): |
| 55 | + assert b'{"d":3.8}' == json_serializer.dumps({"d": Decimal("3.8")}) |
55 | 56 |
|
56 | 57 |
|
57 |
| -def test_uuid_serialization(): |
58 |
| - assert b'{"d":"00000000-0000-0000-0000-000000000003"}' == JSONSerializer().dumps( |
| 58 | +def test_uuid_serialization(json_serializer): |
| 59 | + assert b'{"d":"00000000-0000-0000-0000-000000000003"}' == json_serializer.dumps( |
59 | 60 | {"d": uuid.UUID("00000000-0000-0000-0000-000000000003")}
|
60 | 61 | )
|
61 | 62 |
|
62 | 63 |
|
63 | 64 | @requires_numpy_and_pandas
|
64 |
| -def test_serializes_numpy_bool(): |
65 |
| - assert b'{"d":true}' == JSONSerializer().dumps({"d": np.bool_(True)}) |
| 65 | +def test_serializes_numpy_bool(json_serializer): |
| 66 | + assert b'{"d":true}' == json_serializer.dumps({"d": np.bool_(True)}) |
66 | 67 |
|
67 | 68 |
|
68 | 69 | @requires_numpy_and_pandas
|
69 |
| -def test_serializes_numpy_integers(): |
70 |
| - ser = JSONSerializer() |
| 70 | +def test_serializes_numpy_integers(json_serializer): |
71 | 71 | for np_type in (
|
72 | 72 | np.int_,
|
73 | 73 | np.int8,
|
74 | 74 | np.int16,
|
75 | 75 | np.int32,
|
76 | 76 | np.int64,
|
77 | 77 | ):
|
78 |
| - assert ser.dumps({"d": np_type(-1)}) == b'{"d":-1}' |
| 78 | + assert json_serializer.dumps({"d": np_type(-1)}) == b'{"d":-1}' |
79 | 79 |
|
80 | 80 | for np_type in (
|
81 | 81 | np.uint8,
|
82 | 82 | np.uint16,
|
83 | 83 | np.uint32,
|
84 | 84 | np.uint64,
|
85 | 85 | ):
|
86 |
| - assert ser.dumps({"d": np_type(1)}) == b'{"d":1}' |
| 86 | + assert json_serializer.dumps({"d": np_type(1)}) == b'{"d":1}' |
87 | 87 |
|
88 | 88 |
|
89 | 89 | @requires_numpy_and_pandas
|
90 |
| -def test_serializes_numpy_floats(): |
91 |
| - ser = JSONSerializer() |
| 90 | +def test_serializes_numpy_floats(json_serializer): |
92 | 91 | for np_type in (
|
93 | 92 | np.float_,
|
94 | 93 | np.float32,
|
95 | 94 | np.float64,
|
96 | 95 | ):
|
97 |
| - assert re.search(rb'^{"d":1\.2[\d]*}$', ser.dumps({"d": np_type(1.2)})) |
| 96 | + assert re.search( |
| 97 | + rb'^{"d":1\.2[\d]*}$', json_serializer.dumps({"d": np_type(1.2)}) |
| 98 | + ) |
98 | 99 |
|
99 | 100 |
|
100 | 101 | @requires_numpy_and_pandas
|
101 |
| -def test_serializes_numpy_datetime(): |
102 |
| - assert b'{"d":"2010-10-01T02:30:00"}' == JSONSerializer().dumps( |
| 102 | +def test_serializes_numpy_datetime(json_serializer): |
| 103 | + assert b'{"d":"2010-10-01T02:30:00"}' == json_serializer.dumps( |
103 | 104 | {"d": np.datetime64("2010-10-01T02:30:00")}
|
104 | 105 | )
|
105 | 106 |
|
106 | 107 |
|
107 | 108 | @requires_numpy_and_pandas
|
108 |
| -def test_serializes_numpy_ndarray(): |
109 |
| - assert b'{"d":[0,0,0,0,0]}' == JSONSerializer().dumps( |
| 109 | +def test_serializes_numpy_ndarray(json_serializer): |
| 110 | + assert b'{"d":[0,0,0,0,0]}' == json_serializer.dumps( |
110 | 111 | {"d": np.zeros((5,), dtype=np.uint8)}
|
111 | 112 | )
|
112 | 113 | # This isn't useful for Elasticsearch, just want to make sure it works.
|
113 |
| - assert b'{"d":[[0,0],[0,0]]}' == JSONSerializer().dumps( |
| 114 | + assert b'{"d":[[0,0],[0,0]]}' == json_serializer.dumps( |
114 | 115 | {"d": np.zeros((2, 2), dtype=np.uint8)}
|
115 | 116 | )
|
116 | 117 |
|
117 | 118 |
|
118 | 119 | @requires_numpy_and_pandas
|
119 | 120 | def test_serializes_numpy_nan_to_nan():
|
120 |
| - assert b'{"d":NaN}' == JSONSerializer().dumps({"d": np.nan}) |
| 121 | + assert b'{"d":NaN}' == JSONSerializer().dumps({"d": float("NaN")}) |
| 122 | + # NaN is invalid JSON, and orjson silently converts it to null |
| 123 | + assert b'{"d":null}' == OrjsonSerializer().dumps({"d": float("NaN")}) |
121 | 124 |
|
122 | 125 |
|
123 | 126 | @requires_numpy_and_pandas
|
124 |
| -def test_serializes_pandas_timestamp(): |
125 |
| - assert b'{"d":"2010-10-01T02:30:00"}' == JSONSerializer().dumps( |
| 127 | +def test_serializes_pandas_timestamp(json_serializer): |
| 128 | + assert b'{"d":"2010-10-01T02:30:00"}' == json_serializer.dumps( |
126 | 129 | {"d": pd.Timestamp("2010-10-01T02:30:00")}
|
127 | 130 | )
|
128 | 131 |
|
129 | 132 |
|
130 | 133 | @requires_numpy_and_pandas
|
131 |
| -def test_serializes_pandas_series(): |
132 |
| - assert b'{"d":["a","b","c","d"]}' == JSONSerializer().dumps( |
| 134 | +def test_serializes_pandas_series(json_serializer): |
| 135 | + assert b'{"d":["a","b","c","d"]}' == json_serializer.dumps( |
133 | 136 | {"d": pd.Series(["a", "b", "c", "d"])}
|
134 | 137 | )
|
135 | 138 |
|
136 | 139 |
|
137 | 140 | @requires_numpy_and_pandas
|
138 | 141 | @pytest.mark.skipif(not hasattr(pd, "NA"), reason="pandas.NA is required")
|
139 |
| -def test_serializes_pandas_na(): |
140 |
| - assert b'{"d":null}' == JSONSerializer().dumps({"d": pd.NA}) |
| 142 | +def test_serializes_pandas_na(json_serializer): |
| 143 | + assert b'{"d":null}' == json_serializer.dumps({"d": pd.NA}) |
141 | 144 |
|
142 | 145 |
|
143 | 146 | @requires_numpy_and_pandas
|
144 | 147 | @pytest.mark.skipif(not hasattr(pd, "NaT"), reason="pandas.NaT required")
|
145 |
| -def test_raises_serialization_error_pandas_nat(): |
| 148 | +def test_raises_serialization_error_pandas_nat(json_serializer): |
146 | 149 | with pytest.raises(SerializationError):
|
147 |
| - JSONSerializer().dumps({"d": pd.NaT}) |
| 150 | + json_serializer.dumps({"d": pd.NaT}) |
148 | 151 |
|
149 | 152 |
|
150 | 153 | @requires_numpy_and_pandas
|
151 |
| -def test_serializes_pandas_category(): |
| 154 | +def test_serializes_pandas_category(json_serializer): |
152 | 155 | cat = pd.Categorical(["a", "c", "b", "a"], categories=["a", "b", "c"])
|
153 |
| - assert b'{"d":["a","c","b","a"]}' == JSONSerializer().dumps({"d": cat}) |
| 156 | + assert b'{"d":["a","c","b","a"]}' == json_serializer.dumps({"d": cat}) |
154 | 157 |
|
155 | 158 | cat = pd.Categorical([1, 2, 3], categories=[1, 2, 3])
|
156 |
| - assert b'{"d":[1,2,3]}' == JSONSerializer().dumps({"d": cat}) |
| 159 | + assert b'{"d":[1,2,3]}' == json_serializer.dumps({"d": cat}) |
157 | 160 |
|
158 | 161 |
|
159 |
| -def test_json_raises_serialization_error_on_dump_error(): |
| 162 | +def test_json_raises_serialization_error_on_dump_error(json_serializer): |
160 | 163 | with pytest.raises(SerializationError):
|
161 |
| - JSONSerializer().dumps(object()) |
| 164 | + json_serializer.dumps(object()) |
162 | 165 |
|
163 | 166 |
|
164 |
| -def test_raises_serialization_error_on_load_error(): |
| 167 | +def test_raises_serialization_error_on_load_error(json_serializer): |
165 | 168 | with pytest.raises(SerializationError):
|
166 |
| - JSONSerializer().loads(object()) |
| 169 | + json_serializer.loads(object()) |
167 | 170 | with pytest.raises(SerializationError):
|
168 |
| - JSONSerializer().loads("") |
| 171 | + json_serializer.loads("") |
169 | 172 | with pytest.raises(SerializationError):
|
170 |
| - JSONSerializer().loads("{{") |
| 173 | + json_serializer.loads("{{") |
171 | 174 |
|
172 | 175 |
|
173 | 176 | def test_strings_are_left_untouched():
|
|
0 commit comments