110 lines
5.1 KiB
Python
110 lines
5.1 KiB
Python
#TODO: Test LocationsGeojson
|
|
#TODO: Test MTM
|
|
|
|
from django.test import TestCase, TransactionTestCase
|
|
from pt_map.test_data import *
|
|
from pt_map.models import *
|
|
import unittest
|
|
from django.db import models, transaction
|
|
import random
|
|
import time
|
|
import inspect
|
|
import pt_map.models
|
|
import datetime
|
|
|
|
def _get_test_data(f):
|
|
"""Get test data for a field type."""
|
|
def wrapper(self, field, model, d, *args, **kwargs):
|
|
if field["name"] == "service_id":
|
|
self.add += 1
|
|
return f"{d['pk']}{self.add}"
|
|
match field["type"]:
|
|
case "fk":
|
|
if isinstance(field["references"], list):
|
|
field["references"] = random.choice(field["references"])
|
|
if not field["references"] == model and field["references"] not in [LocationsGeojson]:
|
|
fk = field["references"].objects.create(**{**{f["name"]: self.get_test_data(f, field["references"], d) for f in self.gtfs_fields[field["references"]._meta.object_name] if not f["type"] == "mtm"}, "feed_info_id": self.feed_info})
|
|
return fk
|
|
return None
|
|
case "unique":
|
|
return (d[field["pk"]], "unique")
|
|
case "enum":
|
|
return random.choice(field["allowed_values"])
|
|
case "date":
|
|
return datetime.datetime.fromisoformat(d["date"])
|
|
case "pk":
|
|
self.add += 1
|
|
return f"{d['pk']}{self.add}"
|
|
case _:
|
|
return d[field["type"]]
|
|
return wrapper
|
|
|
|
def _test_constructor(index):
|
|
def decorate(f):
|
|
def wrapper(self, *args, **kwargs):
|
|
for name, model in [tpl for tpl in inspect.getmembers(pt_map.models, inspect.isclass) if tpl[1] not in [FeedInfo, LocationsGeojson]]:
|
|
with self.subTest(name=name):
|
|
d = data[index]
|
|
values = {**{f["name"]: self.get_test_data(f, model, d) for f in self.gtfs_fields[name] if not f["type"] == "mtm"}, "feed_info_id": self.feed_info}
|
|
obj = model.objects.create(**values)
|
|
self.assertIsNotNone(obj)
|
|
self.assertIsInstance(obj, models.Model)
|
|
return wrapper
|
|
return decorate
|
|
|
|
class AllFieldsPresentTestCase(TestCase):
|
|
"""Test for the presence of all the fields of all the models, the GTFS reference describes."""
|
|
def setUp(self):
|
|
self.model_fields = {name: [*[f.name for f in model._meta.fields], *[f.name for f in model._meta.many_to_many]] for name, model in inspect.getmembers(pt_map.models, inspect.isclass) if not model == LocationsGeojson}
|
|
self.gtfs_fields = {name: get_all_fields(name) for name,model in inspect.getmembers(pt_map.models, inspect.isclass) if not model == LocationsGeojson}
|
|
|
|
def test_all_fields_present(self):
|
|
"""Make sure the model has properties for all fields - regardless if required - provided by the GTFS standard."""
|
|
for name in self.model_fields.keys():
|
|
with self.subTest(name=name):
|
|
for f in self.gtfs_fields[name]:
|
|
with self.subTest(f=f):
|
|
self.assertIn(f["name"], self.model_fields[name])
|
|
|
|
class ConstructorAllFieldsTestCase(TransactionTestCase):
|
|
"""Test all the models can be initialized using appropriate data as specified by the GTFS."""
|
|
def setUp(self):
|
|
self.model_fields = {name: [f.name for f in model._meta.fields] for name, model in inspect.getmembers(pt_map.models, inspect.isclass) if not model == FeedInfo}
|
|
self.model_mtm = {name: [f.name for f in model._meta.many_to_many] for name, model in inspect.getmembers(pt_map.models, inspect.isclass) if not model == FeedInfo}
|
|
self.gtfs_fields = {name: get_all_fields(name) for name, model in inspect.getmembers(pt_map.models, inspect.isclass) if not model == FeedInfo}
|
|
self.feed_info = FeedInfo.objects.create(**{f["name"]: data[0][f["type"]] for f in get_all_fields("FeedInfo")})
|
|
self.add = 0
|
|
|
|
@_get_test_data
|
|
def get_test_data(self, field, model, d):
|
|
pass
|
|
|
|
@_test_constructor(0)
|
|
def test_constructor_all_fields_fixed(self):
|
|
"""Make sure all of the model's fields are initializable with appropriate values. Fixed test data."""
|
|
pass
|
|
|
|
@_test_constructor(random.randint(0, len(data)-1))
|
|
def test_constructor_all_fields_other(self):
|
|
"""Make sure all of the model's fields are initializable with appropriate values. A second set of test data."""
|
|
pass
|
|
|
|
class ConstructorRequiredFieldsOnlyTestCase(TransactionTestCase):
|
|
def setUp(self):
|
|
self.gtfs_fields = {name: get_required_fields(name) for name, model in inspect.getmembers(pt_map.models, inspect.isclass) if model not in [FeedInfo, LocationsGeojson]}
|
|
self.feed_info = FeedInfo.objects.create(**{f["name"]: data[0][f["type"]] for f in get_required_fields("FeedInfo")})
|
|
self.add = 0
|
|
|
|
@_get_test_data
|
|
def get_test_data(self):
|
|
pass
|
|
|
|
@_test_constructor(0)
|
|
def test_constructor_required_fields_only_fixed(self):
|
|
pass
|
|
|
|
@_test_constructor(random.randint(0, len(data)-1))
|
|
def test_constructor_required_fields_only_other(self):
|
|
pass
|
|
|