Skip to content

Commit 9d5748d

Browse files
authored
tidy up Pydantic tests (#1236)
1 parent 16276c6 commit 9d5748d

File tree

2 files changed

+117
-99
lines changed

2 files changed

+117
-99
lines changed

scripts/test-cockroach.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# To run a single test tests/test_foo.py::TestFoo::test_foo
66

77
export PICCOLO_CONF="tests.cockroach_conf"
8-
python3 -m pytest \
8+
python -m pytest \
99
--cov=piccolo \
1010
--cov-report=xml \
1111
--cov-report=html \

tests/utils/test_pydantic.py

Lines changed: 116 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929

3030
class TestVarcharColumn(TestCase):
3131
def test_varchar_length(self):
32-
class Director(Table):
32+
class Manager(Table):
3333
name = Varchar(length=10)
3434

35-
pydantic_model = create_pydantic_model(table=Director)
35+
pydantic_model = create_pydantic_model(table=Manager)
3636

3737
with self.assertRaises(ValidationError):
3838
pydantic_model(name="This is a really long name")
@@ -42,10 +42,10 @@ class Director(Table):
4242

4343
class TestEmailColumn(TestCase):
4444
def test_email(self):
45-
class Director(Table):
45+
class Manager(Table):
4646
email = Email()
4747

48-
pydantic_model = create_pydantic_model(table=Director)
48+
pydantic_model = create_pydantic_model(table=Manager)
4949

5050
self.assertEqual(
5151
pydantic_model.model_json_schema()["properties"]["email"]["anyOf"][
@@ -67,28 +67,28 @@ class TestNumericColumn(TestCase):
6767
"""
6868

6969
def test_numeric_digits(self):
70-
class Movie(Table):
71-
box_office = Numeric(digits=(5, 1))
70+
class Band(Table):
71+
royalties = Numeric(digits=(5, 1))
7272

73-
pydantic_model = create_pydantic_model(table=Movie)
73+
pydantic_model = create_pydantic_model(table=Band)
7474

7575
with self.assertRaises(ValidationError):
7676
# This should fail as there are too much numbers after the decimal
7777
# point
78-
pydantic_model(box_office=decimal.Decimal("1.11"))
78+
pydantic_model(royalties=decimal.Decimal("1.11"))
7979

8080
with self.assertRaises(ValidationError):
8181
# This should fail as there are too much numbers in total
82-
pydantic_model(box_office=decimal.Decimal("11111.1"))
82+
pydantic_model(royalties=decimal.Decimal("11111.1"))
8383

84-
pydantic_model(box_office=decimal.Decimal("1.0"))
84+
pydantic_model(royalties=decimal.Decimal("1.0"))
8585

8686
def test_numeric_without_digits(self):
87-
class Movie(Table):
88-
box_office = Numeric()
87+
class Band(Table):
88+
royalties = Numeric()
8989

9090
try:
91-
create_pydantic_model(table=Movie)
91+
create_pydantic_model(table=Band)
9292
except TypeError:
9393
self.fail(
9494
"Creating numeric field without"
@@ -297,13 +297,13 @@ class TestColumnHelpText(TestCase):
297297
def test_column_help_text_present(self):
298298
help_text = "In millions of US dollars."
299299

300-
class Movie(Table):
301-
box_office = Numeric(digits=(5, 1), help_text=help_text)
300+
class Band(Table):
301+
royalties = Numeric(digits=(5, 1), help_text=help_text)
302302

303-
pydantic_model = create_pydantic_model(table=Movie)
303+
pydantic_model = create_pydantic_model(table=Band)
304304

305305
self.assertEqual(
306-
pydantic_model.model_json_schema()["properties"]["box_office"][
306+
pydantic_model.model_json_schema()["properties"]["royalties"][
307307
"extra"
308308
]["help_text"],
309309
help_text,
@@ -317,12 +317,12 @@ class TestTableHelpText(TestCase):
317317
"""
318318

319319
def test_table_help_text_present(self):
320-
help_text = "Movies which were released in cinemas."
320+
help_text = "Bands playing concerts."
321321

322-
class Movie(Table, help_text=help_text):
322+
class Band(Table, help_text=help_text):
323323
name = Varchar()
324324

325-
pydantic_model = create_pydantic_model(table=Movie)
325+
pydantic_model = create_pydantic_model(table=Band)
326326

327327
self.assertEqual(
328328
pydantic_model.model_json_schema()["extra"]["help_text"],
@@ -332,10 +332,10 @@ class Movie(Table, help_text=help_text):
332332

333333
class TestUniqueColumn(TestCase):
334334
def test_unique_column_true(self):
335-
class Director(Table):
335+
class Manager(Table):
336336
name = Varchar(unique=True)
337337

338-
pydantic_model = create_pydantic_model(table=Director)
338+
pydantic_model = create_pydantic_model(table=Manager)
339339

340340
self.assertEqual(
341341
pydantic_model.model_json_schema()["properties"]["name"]["extra"][
@@ -345,10 +345,10 @@ class Director(Table):
345345
)
346346

347347
def test_unique_column_false(self):
348-
class Director(Table):
348+
class Manager(Table):
349349
name = Varchar()
350350

351-
pydantic_model = create_pydantic_model(table=Director)
351+
pydantic_model = create_pydantic_model(table=Manager)
352352

353353
self.assertEqual(
354354
pydantic_model.model_json_schema()["properties"]["name"]["extra"][
@@ -360,161 +360,179 @@ class Director(Table):
360360

361361
class TestJSONColumn(TestCase):
362362
def test_default(self):
363-
class Movie(Table):
364-
meta = JSON()
365-
meta_b = JSONB()
363+
class Studio(Table):
364+
facilities = JSON()
365+
facilities_b = JSONB()
366366

367-
pydantic_model = create_pydantic_model(table=Movie)
367+
pydantic_model = create_pydantic_model(table=Studio)
368368

369-
json_string = '{"code": 12345}'
369+
json_string = '{"guitar_amps": 6}'
370370

371-
model_instance = pydantic_model(meta=json_string, meta_b=json_string)
372-
self.assertEqual(model_instance.meta, json_string) # type: ignore
373-
self.assertEqual(model_instance.meta_b, json_string) # type: ignore
371+
model_instance = pydantic_model(
372+
facilities=json_string, facilities_b=json_string
373+
)
374+
self.assertEqual(
375+
model_instance.facilities,
376+
json_string,
377+
)
378+
self.assertEqual(
379+
model_instance.facilities_b,
380+
json_string,
381+
)
374382

375383
def test_deserialize_json(self):
376-
class Movie(Table):
377-
meta = JSON()
378-
meta_b = JSONB()
384+
class Studio(Table):
385+
facilities = JSON()
386+
facilities_b = JSONB()
379387

380388
pydantic_model = create_pydantic_model(
381-
table=Movie, deserialize_json=True
389+
table=Studio, deserialize_json=True
382390
)
383391

384-
json_string = '{"code": 12345}'
385-
output = {"code": 12345}
392+
json_string = '{"guitar_amps": 6}'
393+
output = {"guitar_amps": 6}
386394

387-
model_instance = pydantic_model(meta=json_string, meta_b=json_string)
388-
self.assertEqual(model_instance.meta, output) # type: ignore
389-
self.assertEqual(model_instance.meta_b, output) # type: ignore
395+
model_instance = pydantic_model(
396+
facilities=json_string, facilities_b=json_string
397+
)
398+
self.assertEqual(
399+
model_instance.facilities,
400+
output,
401+
)
402+
self.assertEqual(
403+
model_instance.facilities_b,
404+
output,
405+
)
390406

391407
def test_validation(self):
392-
class Movie(Table):
393-
meta = JSON()
394-
meta_b = JSONB()
408+
class Studio(Table):
409+
facilities = JSON()
410+
facilities_b = JSONB()
395411

396412
for deserialize_json in (True, False):
397413
pydantic_model = create_pydantic_model(
398-
table=Movie, deserialize_json=deserialize_json
414+
table=Studio, deserialize_json=deserialize_json
399415
)
400416

401417
json_string = "error"
402418

403419
with self.assertRaises(pydantic.ValidationError):
404-
pydantic_model(meta=json_string, meta_b=json_string)
420+
pydantic_model(
421+
facilities=json_string, facilities_b=json_string
422+
)
405423

406424
def test_json_widget(self):
407425
"""
408426
Make sure that we indicate that `JSON` / `JSONB` columns require a
409427
special widget in Piccolo Admin.
410428
"""
411429

412-
class Movie(Table):
413-
features = JSON()
430+
class Studio(Table):
431+
facilities = JSON()
414432

415-
pydantic_model = create_pydantic_model(table=Movie)
433+
pydantic_model = create_pydantic_model(table=Studio)
416434

417435
self.assertEqual(
418-
pydantic_model.model_json_schema()["properties"]["features"][
436+
pydantic_model.model_json_schema()["properties"]["facilities"][
419437
"extra"
420438
]["widget"],
421439
"json",
422440
)
423441

424442
def test_null_value(self):
425-
class Movie(Table):
426-
meta = JSON(null=True)
427-
meta_b = JSONB(null=True)
443+
class Studio(Table):
444+
facilities = JSON(null=True)
445+
facilities_b = JSONB(null=True)
428446

429-
pydantic_model = create_pydantic_model(table=Movie)
430-
movie = pydantic_model(meta=None, meta_b=None)
447+
pydantic_model = create_pydantic_model(table=Studio)
448+
movie = pydantic_model(facilities=None, facilities_b=None)
431449

432-
self.assertIsNone(movie.meta) # type: ignore
433-
self.assertIsNone(movie.meta_b) # type: ignore
450+
self.assertIsNone(movie.facilities)
451+
self.assertIsNone(movie.facilities_b)
434452

435453

436454
class TestExcludeColumns(TestCase):
437455
def test_all(self):
438-
class Computer(Table):
439-
CPU = Varchar()
440-
GPU = Varchar()
456+
class Band(Table):
457+
name = Varchar()
458+
bio = Text()
441459

442-
pydantic_model = create_pydantic_model(Computer, exclude_columns=())
460+
pydantic_model = create_pydantic_model(Band, exclude_columns=())
443461

444462
properties = pydantic_model.model_json_schema()["properties"]
445-
self.assertIsInstance(properties["GPU"], dict)
446-
self.assertIsInstance(properties["CPU"], dict)
463+
self.assertIsInstance(properties["name"], dict)
464+
self.assertIsInstance(properties["bio"], dict)
447465

448466
def test_exclude(self):
449-
class Computer(Table):
450-
CPU = Varchar()
451-
GPU = Varchar()
467+
class Band(Table):
468+
name = Varchar()
469+
album = Varchar()
452470

453471
pydantic_model = create_pydantic_model(
454-
Computer,
455-
exclude_columns=(Computer.CPU,),
472+
Band,
473+
exclude_columns=(Band.name,),
456474
)
457475

458476
properties = pydantic_model.model_json_schema()["properties"]
459-
self.assertIsInstance(properties.get("GPU"), dict)
460-
self.assertIsNone(properties.get("CPU"))
477+
self.assertIsInstance(properties.get("album"), dict)
478+
self.assertIsNone(properties.get("dict"))
461479

462480
def test_exclude_all_manually(self):
463-
class Computer(Table):
464-
GPU = Varchar()
465-
CPU = Varchar()
481+
class Band(Table):
482+
name = Varchar()
483+
album = Varchar()
466484

467485
pydantic_model = create_pydantic_model(
468-
Computer,
469-
exclude_columns=(Computer.GPU, Computer.CPU),
486+
Band,
487+
exclude_columns=(Band.name, Band.album),
470488
)
471489

472490
self.assertEqual(pydantic_model.model_json_schema()["properties"], {})
473491

474492
def test_exclude_all_meta(self):
475-
class Computer(Table):
476-
GPU = Varchar()
477-
CPU = Varchar()
493+
class Band(Table):
494+
name = Varchar()
495+
album = Varchar()
478496

479497
pydantic_model = create_pydantic_model(
480-
Computer,
481-
exclude_columns=tuple(Computer._meta.columns),
498+
Band,
499+
exclude_columns=tuple(Band._meta.columns),
482500
)
483501

484502
self.assertEqual(pydantic_model.model_json_schema()["properties"], {})
485503

486504
def test_invalid_column_str(self):
487-
class Computer(Table):
488-
CPU = Varchar()
489-
GPU = Varchar()
505+
class Band(Table):
506+
name = Varchar()
507+
album = Varchar()
490508

491509
with self.assertRaises(ValueError):
492510
create_pydantic_model(
493-
Computer,
494-
exclude_columns=("CPU",), # type: ignore
511+
Band,
512+
exclude_columns=("album",),
495513
)
496514

497515
def test_invalid_column_different_table(self):
498-
class Computer(Table):
499-
CPU = Varchar()
500-
GPU = Varchar()
516+
class Band(Table):
517+
name = Varchar()
518+
album = Varchar()
501519

502-
class Computer2(Table):
503-
SSD = Varchar()
520+
class Band2(Table):
521+
photo = Varchar()
504522

505523
with self.assertRaises(ValueError):
506-
create_pydantic_model(Computer, exclude_columns=(Computer2.SSD,))
524+
create_pydantic_model(Band, exclude_columns=(Band2.photo,))
507525

508526
def test_invalid_column_different_table_same_type(self):
509-
class Computer(Table):
510-
CPU = Varchar()
511-
GPU = Varchar()
527+
class Band(Table):
528+
name = Varchar()
529+
album = Varchar()
512530

513-
class Computer2(Table):
514-
CPU = Varchar()
531+
class Band2(Table):
532+
name = Varchar()
515533

516534
with self.assertRaises(ValueError):
517-
create_pydantic_model(Computer, exclude_columns=(Computer2.CPU,))
535+
create_pydantic_model(Band, exclude_columns=(Band2.name,))
518536

519537
def test_exclude_nested(self):
520538
class Manager(Table):
@@ -892,7 +910,7 @@ class Band(Table):
892910

893911
model = BandModel(regrettable_column_name="test")
894912

895-
self.assertEqual(model.name, "test") # type: ignore
913+
self.assertEqual(model.name, "test")
896914

897915

898916
class TestJSONSchemaExtra(TestCase):

0 commit comments

Comments
 (0)