# type: ignore import datetime import decimal import typing import ormar import pydantic import pytest import sqlalchemy from ormar.exceptions import ModelDefinitionError from ormar.models import Model from tests.lifespan import init_tests from tests.settings import create_config base_ormar_config = create_config() class ExampleModel(Model): ormar_config = base_ormar_config.copy(tablename="example") 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_smallint: int = ormar.SmallInteger(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): ormar_config = base_ormar_config.copy(tablename="example2") test: int = ormar.Integer(primary_key=True) test_string: str = ormar.String(max_length=250) create_test_database = init_tests(base_ormar_config) @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.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): ormar_config = ormar.OrmarConfig( tablename="jsons2", database=base_ormar_config.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): ormar_config = ormar.OrmarConfig(tablename="jsons3") id: int = ormar.Integer(primary_key=True) test_json = ormar.JSON(nullable=True) def test_wrong_pydantic_config(): with pytest.raises(ModelDefinitionError): class ErrorSample(ormar.Model): model_config = ["test"] ormar_config = ormar.OrmarConfig(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.model_fields for field in fields_to_check]) assert example.test == 1 def test_sqlalchemy_table_is_created(example): assert issubclass(example.ormar_config.table.__class__, sqlalchemy.Table) assert all( [field in example.ormar_config.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 ormar_config = base_ormar_config.copy(tablename="example2") 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): ormar_config = base_ormar_config.copy(tablename="example3") id: int = ormar.Integer(primary_key=True) test_string: str = ormar.String(max_length=250, primary_key=True) @typing.no_type_check def test_decimal_error_in_model_definition(): with pytest.raises(ModelDefinitionError): class ExampleModel2(Model): ormar_config = base_ormar_config.copy(tablename="example5") test: decimal.Decimal = ormar.Decimal(primary_key=True) @typing.no_type_check def test_binary_error_without_length_model_definition(): with pytest.raises(ModelDefinitionError): class ExampleModel2(Model): ormar_config = base_ormar_config.copy(tablename="example6") test: bytes = ormar.LargeBinary(primary_key=True, max_length=-1) @typing.no_type_check def test_string_error_in_model_definition(): with pytest.raises(ModelDefinitionError): class ExampleModel2(Model): ormar_config = base_ormar_config.copy(tablename="example6") test: str = ormar.String(primary_key=True, max_length=0) @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, )