Coverage for databases/tests/types/test_decimal.py: 100%
82 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
1from decimal import Decimal, getcontext
3import pytest
4from dirty_equals import IsPartialDict
6from prisma import Prisma
7from prisma.models import Types
8from prisma._compat import PYDANTIC_V2, model_json_schema
10DEFAULT_PRECISION = getcontext().prec
13@pytest.fixture(autouse=True)
14def setup_decimal_module() -> None:
15 # ensure that any modifications to the decimal precision
16 # are not leaked between tests
17 getcontext().prec = DEFAULT_PRECISION
20@pytest.mark.asyncio
21async def test_serialising(client: Prisma) -> None:
22 """Decimal values of any precision are correctly serialised / deserialised"""
23 model = await client.types.create(
24 data={
25 'decimal_': Decimal(1),
26 },
27 )
28 assert model.decimal_ == Decimal(1)
30 getcontext().prec = 16
32 value = Decimal(1) / Decimal(7)
33 model = await client.types.create(
34 data={
35 'decimal_': value,
36 },
37 )
38 assert value == model.decimal_
39 assert str(model.decimal_) == '0.1428571428571429'
42# TODO: split up this test into multiple tests
45@pytest.mark.asyncio
46async def test_filtering(client: Prisma) -> None:
47 """Finding records by a Decimal value"""
48 async with client.batch_() as batcher:
49 batcher.types.create({'decimal_': Decimal(1)})
50 batcher.types.create({'decimal_': Decimal('2.1234')})
51 batcher.types.create({'decimal_': Decimal(3)})
53 total = await client.types.count(
54 where={
55 'decimal_': Decimal(1),
56 },
57 )
58 assert total == 1
60 found = await client.types.find_first(
61 where={
62 'decimal_': {
63 'equals': Decimal('2.1234'),
64 },
65 },
66 )
67 assert found is not None
68 assert str(found.decimal_) == '2.1234'
70 results = await client.types.find_many(
71 where={
72 'decimal_': {
73 'not_in': [Decimal(1), Decimal(3)],
74 },
75 },
76 )
77 assert len(results) == 1
78 assert results[0].decimal_ == Decimal('2.1234')
80 results = await client.types.find_many(
81 where={
82 'decimal_': {
83 'lt': Decimal(2),
84 },
85 },
86 )
87 assert len(results) == 1
88 assert results[0].decimal_ == Decimal(1)
90 found = await client.types.find_first(
91 where={
92 'decimal_': {
93 'lt': Decimal(1),
94 },
95 },
96 )
97 assert found is None
99 results = await client.types.find_many(
100 where={
101 'decimal_': {
102 'lte': Decimal(3),
103 },
104 },
105 )
106 assert len(results) == 3
108 found = await client.types.find_first(
109 where={
110 'decimal_': {
111 'lte': Decimal(1),
112 },
113 },
114 )
115 assert found is not None
116 assert found.decimal_ == Decimal(1)
118 found = await client.types.find_first(
119 where={
120 'decimal_': {
121 'lte': Decimal('0.99999'),
122 },
123 },
124 )
125 assert found is None
127 found = await client.types.find_first(
128 where={
129 'decimal_': {
130 'gt': Decimal('0.99999'),
131 },
132 },
133 )
134 assert found is not None
135 assert found.decimal_ == Decimal(1)
137 found = await client.types.find_first(
138 where={
139 'decimal_': {
140 'gt': Decimal('4'),
141 },
142 },
143 )
144 assert found is None
146 found = await client.types.find_first(
147 where={
148 'decimal_': {
149 'gte': Decimal('1'),
150 },
151 },
152 )
153 assert found is not None
154 assert found.decimal_ == Decimal('1')
156 found = await client.types.find_first(
157 where={
158 'decimal_': {
159 'gte': Decimal('4'),
160 },
161 },
162 )
163 assert found is None
165 results = await client.types.find_many(
166 where={
167 'decimal_': {
168 'in': [Decimal(3), Decimal(1), Decimal(2)],
169 },
170 },
171 order={
172 'decimal_': 'asc',
173 },
174 )
175 assert len(results) == 2
176 assert results[0].decimal_ == Decimal(1)
177 assert results[1].decimal_ == Decimal(3)
179 found = await client.types.find_first(
180 where={
181 'decimal_': {
182 'not': Decimal('1'),
183 },
184 },
185 order={
186 'decimal_': 'asc',
187 },
188 )
189 assert found is not None
190 assert found.decimal_ == Decimal('2.1234')
192 found = await client.types.find_first(
193 where={
194 'decimal_': {
195 'not': {'equals': Decimal('1')},
196 },
197 },
198 order={
199 'decimal_': 'asc',
200 },
201 )
202 assert found is not None
203 assert found.decimal_ == Decimal('2.1234')
206@pytest.mark.asyncio
207async def test_filtering_nulls(client: Prisma) -> None:
208 """None is a valid filter for nullable Decimal fields"""
209 await client.types.create(
210 {
211 'string': 'a',
212 'optional_decimal': None,
213 },
214 )
215 await client.types.create(
216 {
217 'string': 'b',
218 'optional_decimal': Decimal('3'),
219 },
220 )
221 await client.types.create(
222 {
223 'string': 'c',
224 'optional_decimal': Decimal('4'),
225 },
226 )
228 found = await client.types.find_first(
229 where={
230 'NOT': [
231 {
232 'optional_decimal': None,
233 },
234 ],
235 },
236 order={
237 'string': 'asc',
238 },
239 )
240 assert found is not None
241 assert found.string == 'b'
242 assert found.optional_decimal == Decimal('3')
244 count = await client.types.count(
245 where={
246 'optional_decimal': None,
247 },
248 )
249 assert count == 1
251 count = await client.types.count(
252 where={
253 'NOT': [
254 {
255 'optional_decimal': None,
256 },
257 ],
258 },
259 )
260 assert count == 2
263def test_json_schema() -> None:
264 """Ensure a JSON Schema definition can be created"""
265 if PYDANTIC_V2:
266 assert model_json_schema(Types) == IsPartialDict(
267 properties=IsPartialDict(
268 {
269 'decimal_': {
270 'title': 'Decimal ',
271 'anyOf': [{'type': 'number'}, {'type': 'string'}],
272 },
273 'optional_decimal': {
274 'title': 'Optional Decimal',
275 'anyOf': [
276 {'type': 'number'},
277 {'type': 'string'},
278 {'type': 'null'},
279 ],
280 'default': None,
281 },
282 }
283 )
284 )
285 else:
286 assert model_json_schema(Types) == IsPartialDict(
287 properties=IsPartialDict(
288 {
289 'decimal_': {
290 'title': 'Decimal ',
291 'type': 'number',
292 },
293 'optional_decimal': {
294 'title': 'Optional Decimal',
295 'type': 'number',
296 },
297 }
298 )
299 )