added basic save, update, load and delate methods
This commit is contained in:
3
tests/settings.py
Normal file
3
tests/settings.py
Normal file
@ -0,0 +1,3 @@
|
||||
import os
|
||||
|
||||
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///test.db")
|
||||
@ -1,100 +1,58 @@
|
||||
import datetime
|
||||
from typing import ClassVar
|
||||
|
||||
import pydantic
|
||||
import databases
|
||||
import pytest
|
||||
import sqlalchemy
|
||||
|
||||
import orm.fields as fields
|
||||
from orm.exceptions import ModelDefinitionError
|
||||
from orm.models import Model
|
||||
import orm
|
||||
from tests.settings import DATABASE_URL
|
||||
|
||||
database = databases.Database(DATABASE_URL, force_rollback=True)
|
||||
metadata = sqlalchemy.MetaData()
|
||||
|
||||
|
||||
class ExampleModel(Model):
|
||||
def time():
|
||||
return datetime.datetime.now().time()
|
||||
|
||||
|
||||
class Example(orm.Model):
|
||||
__tablename__ = "example"
|
||||
__metadata__ = metadata
|
||||
test = fields.Integer(primary_key=True)
|
||||
test_string = fields.String(length=250)
|
||||
test_text = fields.Text(default='')
|
||||
test_bool = fields.Boolean(nullable=False)
|
||||
test_float = fields.Float()
|
||||
test_datetime = fields.DateTime(default=datetime.datetime.now)
|
||||
test_date = fields.Date(default=datetime.date.today)
|
||||
test_time = fields.Time(default=datetime.time)
|
||||
test_json = fields.JSON(default={})
|
||||
test_bigint = fields.BigInteger(default=0)
|
||||
test_decimal = fields.Decimal(length=10, precision=2)
|
||||
__database__ = database
|
||||
|
||||
id = orm.Integer(primary_key=True)
|
||||
created = orm.DateTime(default=datetime.datetime.now)
|
||||
created_day = orm.Date(default=datetime.date.today)
|
||||
created_time = orm.Time(default=time)
|
||||
description = orm.Text(nullable=True)
|
||||
value = orm.Float(nullable=True)
|
||||
data = orm.JSON(default={})
|
||||
|
||||
|
||||
fields_to_check = ['test', 'test_text', 'test_string', 'test_datetime', 'test_date', 'test_text', 'test_float',
|
||||
'test_bigint', 'test_json']
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def create_test_database():
|
||||
engine = sqlalchemy.create_engine(DATABASE_URL)
|
||||
metadata.create_all(engine)
|
||||
yield
|
||||
metadata.drop_all(engine)
|
||||
|
||||
|
||||
class ExampleModel2(Model):
|
||||
__tablename__ = "example2"
|
||||
__metadata__ = metadata
|
||||
test = fields.Integer(name='test12', primary_key=True)
|
||||
test_string = fields.String('test_string2', length=250)
|
||||
@pytest.mark.asyncio
|
||||
async def test_model_crud():
|
||||
async with database:
|
||||
example = Example()
|
||||
await example.save()
|
||||
|
||||
await example.load()
|
||||
assert example.created.year == datetime.datetime.now().year
|
||||
assert example.created_day == datetime.date.today()
|
||||
assert example.description is None
|
||||
assert example.value is None
|
||||
assert example.data == {}
|
||||
|
||||
def test_not_nullable_field_is_required():
|
||||
with pytest.raises(pydantic.error_wrappers.ValidationError):
|
||||
ExampleModel(test=1, test_string='test')
|
||||
await example.update(data={"foo": 123}, value=123.456)
|
||||
await example.load()
|
||||
assert example.value == 123.456
|
||||
assert example.data == {"foo": 123}
|
||||
|
||||
|
||||
def test_model_attribute_access():
|
||||
example = ExampleModel(test=1, test_string='test', test_bool=True)
|
||||
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 == {}
|
||||
|
||||
example.test = 12
|
||||
assert example.test == 12
|
||||
|
||||
example.new_attr = 12
|
||||
assert 'new_attr' in example.__dict__
|
||||
|
||||
|
||||
def test_primary_key_access_and_setting():
|
||||
example = ExampleModel(pk=1, test_string='test', test_bool=True)
|
||||
assert example.pk == 1
|
||||
example.pk = 2
|
||||
|
||||
assert example.pk == 2
|
||||
assert example.test == 2
|
||||
|
||||
|
||||
def test_pydantic_model_is_created():
|
||||
example = ExampleModel(pk=1, test_string='test', test_bool=True)
|
||||
assert issubclass(example.values.__class__, pydantic.BaseModel)
|
||||
assert all([field in example.values.__fields__ for field in fields_to_check])
|
||||
assert example.values.test == 1
|
||||
|
||||
|
||||
def test_sqlalchemy_table_is_created():
|
||||
example = ExampleModel(pk=1, test_string='test', test_bool=True)
|
||||
assert issubclass(example.__table__.__class__, sqlalchemy.Table)
|
||||
assert all([field in example.__table__.columns for field in fields_to_check])
|
||||
|
||||
|
||||
def test_double_column_name_in_model_definition():
|
||||
with pytest.raises(ModelDefinitionError):
|
||||
class ExampleModel2(Model):
|
||||
__tablename__ = "example3"
|
||||
__metadata__ = metadata
|
||||
test_string = fields.String('test_string2', name='test_string2', length=250)
|
||||
|
||||
|
||||
def test_setting_pk_column_as_pydantic_only_in_model_definition():
|
||||
with pytest.raises(ModelDefinitionError):
|
||||
class ExampleModel2(Model):
|
||||
__tablename__ = "example4"
|
||||
__metadata__ = metadata
|
||||
test = fields.Integer(name='test12', primary_key=True, pydantic_only=True)
|
||||
await example.delete()
|
||||
|
||||
114
tests/test_model_definition.py
Normal file
114
tests/test_model_definition.py
Normal file
@ -0,0 +1,114 @@
|
||||
import datetime
|
||||
from typing import ClassVar
|
||||
|
||||
import pydantic
|
||||
import pytest
|
||||
import sqlalchemy
|
||||
|
||||
import orm.fields as fields
|
||||
from orm.exceptions import ModelDefinitionError
|
||||
from orm.models import Model
|
||||
|
||||
metadata = sqlalchemy.MetaData()
|
||||
|
||||
|
||||
class ExampleModel(Model):
|
||||
__tablename__ = "example"
|
||||
__metadata__ = metadata
|
||||
test = fields.Integer(primary_key=True)
|
||||
test_string = fields.String(length=250)
|
||||
test_text = fields.Text(default='')
|
||||
test_bool = fields.Boolean(nullable=False)
|
||||
test_float = fields.Float()
|
||||
test_datetime = fields.DateTime(default=datetime.datetime.now)
|
||||
test_date = fields.Date(default=datetime.date.today)
|
||||
test_time = fields.Time(default=datetime.time)
|
||||
test_json = fields.JSON(default={})
|
||||
test_bigint = fields.BigInteger(default=0)
|
||||
test_decimal = fields.Decimal(length=10, precision=2)
|
||||
|
||||
|
||||
fields_to_check = ['test', 'test_text', 'test_string', 'test_datetime', 'test_date', 'test_text', 'test_float',
|
||||
'test_bigint', 'test_json']
|
||||
|
||||
|
||||
class ExampleModel2(Model):
|
||||
__tablename__ = "example2"
|
||||
__metadata__ = metadata
|
||||
test = fields.Integer(name='test12', primary_key=True)
|
||||
test_string = fields.String('test_string2', length=250)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def example():
|
||||
return ExampleModel(pk=1, test_string='test', test_bool=True)
|
||||
|
||||
|
||||
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 == {}
|
||||
|
||||
example.test = 12
|
||||
assert example.test == 12
|
||||
|
||||
example.new_attr = 12
|
||||
assert 'new_attr' in example.__dict__
|
||||
|
||||
|
||||
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.values.__class__, pydantic.BaseModel)
|
||||
assert all([field in example.values.__fields__ for field in fields_to_check])
|
||||
assert example.values.test == 1
|
||||
|
||||
|
||||
def test_sqlalchemy_table_is_created(example):
|
||||
assert issubclass(example.__table__.__class__, sqlalchemy.Table)
|
||||
assert all([field in example.__table__.columns for field in fields_to_check])
|
||||
|
||||
|
||||
def test_double_column_name_in_model_definition():
|
||||
with pytest.raises(ModelDefinitionError):
|
||||
class ExampleModel2(Model):
|
||||
__tablename__ = "example3"
|
||||
__metadata__ = metadata
|
||||
test_string = fields.String('test_string2', name='test_string2', length=250)
|
||||
|
||||
|
||||
def test_no_pk_in_model_definition():
|
||||
with pytest.raises(ModelDefinitionError):
|
||||
class ExampleModel2(Model):
|
||||
__tablename__ = "example3"
|
||||
__metadata__ = metadata
|
||||
test_string = fields.String(name='test_string2', length=250)
|
||||
|
||||
|
||||
def test_setting_pk_column_as_pydantic_only_in_model_definition():
|
||||
with pytest.raises(ModelDefinitionError):
|
||||
class ExampleModel2(Model):
|
||||
__tablename__ = "example4"
|
||||
__metadata__ = metadata
|
||||
test = fields.Integer(name='test12', primary_key=True, pydantic_only=True)
|
||||
|
||||
|
||||
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)
|
||||
Reference in New Issue
Block a user