Files
ormar/tests/test_model_definition/test_model_definition.py
2021-03-30 12:48:39 +02:00

243 lines
6.3 KiB
Python

# type: ignore
import asyncio
import datetime
import decimal
import databases
import pydantic
import pytest
import sqlalchemy
import typing
import ormar
from ormar.exceptions import ModelDefinitionError
from ormar.models import Model
from tests.settings import DATABASE_URL
metadata = sqlalchemy.MetaData()
database = databases.Database(DATABASE_URL, force_rollback=True)
class ExampleModel(Model):
class Meta:
tablename = "example"
metadata = metadata
database = database
test: int = ormar.Integer(primary_key=True)
test_string: str = ormar.String(max_length=250)
test_text: str = ormar.Text(default="")
test_bool: bool = ormar.Boolean(nullable=False)
test_float = ormar.Float(nullable=True)
test_datetime = ormar.DateTime(default=datetime.datetime.now)
test_date = ormar.Date(default=datetime.date.today)
test_time = ormar.Time(default=datetime.time)
test_json = ormar.JSON(default={})
test_bigint: int = ormar.BigInteger(default=0)
test_decimal = ormar.Decimal(scale=2, precision=10)
test_decimal2 = ormar.Decimal(max_digits=10, decimal_places=2)
fields_to_check = [
"test",
"test_text",
"test_string",
"test_datetime",
"test_date",
"test_text",
"test_float",
"test_bigint",
"test_json",
]
class ExampleModel2(Model):
class Meta:
tablename = "examples"
metadata = metadata
database = database
test: int = ormar.Integer(primary_key=True)
test_string: str = ormar.String(max_length=250)
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
loop.close()
@pytest.fixture(autouse=True, scope="module")
async def create_test_database():
engine = sqlalchemy.create_engine(DATABASE_URL)
metadata.create_all(engine)
yield
metadata.drop_all(engine)
@pytest.fixture()
def example():
return ExampleModel(
pk=1,
test_string="test",
test_bool=True,
test_decimal=decimal.Decimal(3.5),
test_decimal2=decimal.Decimal(5.5),
)
def test_not_nullable_field_is_required():
with pytest.raises(pydantic.error_wrappers.ValidationError):
ExampleModel(test=1, test_string="test")
def test_model_attribute_access(example):
assert example.test == 1
assert example.test_string == "test"
assert example.test_datetime.year == datetime.datetime.now().year
assert example.test_date == datetime.date.today()
assert example.test_text == ""
assert example.test_float is None
assert example.test_bigint == 0
assert example.test_json == {}
assert example.test_decimal == 3.5
assert example.test_decimal2 == 5.5
example.test = 12
assert example.test == 12
example._orm_saved = True
assert example._orm_saved
def test_model_attribute_json_access(example):
example.test_json = dict(aa=12)
assert example.test_json == dict(aa=12)
def test_missing_metadata():
with pytest.raises(ModelDefinitionError):
class JsonSample2(ormar.Model):
class Meta:
tablename = "jsons2"
database = database
id: int = ormar.Integer(primary_key=True)
test_json = ormar.JSON(nullable=True)
def test_missing_database():
with pytest.raises(ModelDefinitionError):
class JsonSample3(ormar.Model):
class Meta:
tablename = "jsons3"
id: int = ormar.Integer(primary_key=True)
test_json = ormar.JSON(nullable=True)
def test_non_existing_attr(example):
with pytest.raises(ValueError):
example.new_attr = 12
def test_primary_key_access_and_setting(example):
assert example.pk == 1
example.pk = 2
assert example.pk == 2
assert example.test == 2
def test_pydantic_model_is_created(example):
assert issubclass(example.__class__, pydantic.BaseModel)
assert all([field in example.__fields__ for field in fields_to_check])
assert example.test == 1
def test_sqlalchemy_table_is_created(example):
assert issubclass(example.Meta.table.__class__, sqlalchemy.Table)
assert all([field in example.Meta.table.columns for field in fields_to_check])
@typing.no_type_check
def test_no_pk_in_model_definition():
with pytest.raises(ModelDefinitionError): # type: ignore
class ExampleModel2(Model): # type: ignore
class Meta:
tablename = "example2"
database = database
metadata = metadata
test_string: str = ormar.String(max_length=250) # type: ignore
@typing.no_type_check
def test_two_pks_in_model_definition():
with pytest.raises(ModelDefinitionError):
@typing.no_type_check
class ExampleModel2(Model):
class Meta:
tablename = "example3"
database = database
metadata = metadata
id: int = ormar.Integer(primary_key=True)
test_string: str = ormar.String(max_length=250, primary_key=True)
@typing.no_type_check
def test_setting_pk_column_as_pydantic_only_in_model_definition():
with pytest.raises(ModelDefinitionError):
class ExampleModel2(Model):
class Meta:
tablename = "example4"
database = database
metadata = metadata
test: int = ormar.Integer(primary_key=True, pydantic_only=True)
@typing.no_type_check
def test_decimal_error_in_model_definition():
with pytest.raises(ModelDefinitionError):
class ExampleModel2(Model):
class Meta:
tablename = "example5"
database = database
metadata = metadata
test: decimal.Decimal = ormar.Decimal(primary_key=True)
@typing.no_type_check
def test_string_error_in_model_definition():
with pytest.raises(ModelDefinitionError):
class ExampleModel2(Model):
class Meta:
tablename = "example6"
database = database
metadata = metadata
test: str = ormar.String(primary_key=True)
@typing.no_type_check
def test_json_conversion_in_model():
with pytest.raises(pydantic.ValidationError):
ExampleModel(
test_json=datetime.datetime.now(),
test=1,
test_string="test",
test_bool=True,
)