import pytest import sqlalchemy as sa from sqlalchemy.dialects.postgresql import ARRAY from sqlalchemy_utils import ( assert_max_length, assert_max_value, assert_min_value, assert_non_nullable, assert_nullable ) @pytest.fixture() def User(Base): class User(Base): __tablename__ = 'user' id = sa.Column('_id', sa.Integer, primary_key=True) name = sa.Column('_name', sa.String(20)) age = sa.Column('_age', sa.Integer, nullable=False) email = sa.Column( '_email', sa.String(200), nullable=False, unique=True ) fav_numbers = sa.Column('_fav_numbers', ARRAY(sa.Integer)) __table_args__ = ( sa.CheckConstraint(sa.and_(age >= 0, age <= 150)), sa.CheckConstraint( sa.and_( sa.func.array_length(fav_numbers, 1) <= 8 ) ) ) return User @pytest.fixture() def user(User, session): user = User( name='Someone', email='someone@example.com', age=15, fav_numbers=[1, 2, 3] ) session.add(user) session.commit() return user @pytest.mark.usefixtures('postgresql_dsn') class TestAssertMaxLengthWithArray(object): def test_with_max_length(self, user): assert_max_length(user, 'fav_numbers', 8) assert_max_length(user, 'fav_numbers', 8) def test_smaller_than_max_length(self, user): with pytest.raises(AssertionError): assert_max_length(user, 'fav_numbers', 7) with pytest.raises(AssertionError): assert_max_length(user, 'fav_numbers', 7) def test_bigger_than_max_length(self, user): with pytest.raises(AssertionError): assert_max_length(user, 'fav_numbers', 9) with pytest.raises(AssertionError): assert_max_length(user, 'fav_numbers', 9) @pytest.mark.usefixtures('postgresql_dsn') class TestAssertNonNullable(object): def test_non_nullable_column(self, user): # Test everything twice so that session gets rolled back properly assert_non_nullable(user, 'age') assert_non_nullable(user, 'age') def test_nullable_column(self, user): with pytest.raises(AssertionError): assert_non_nullable(user, 'name') with pytest.raises(AssertionError): assert_non_nullable(user, 'name') @pytest.mark.usefixtures('postgresql_dsn') class TestAssertNullable(object): def test_nullable_column(self, user): assert_nullable(user, 'name') assert_nullable(user, 'name') def test_non_nullable_column(self, user): with pytest.raises(AssertionError): assert_nullable(user, 'age') with pytest.raises(AssertionError): assert_nullable(user, 'age') @pytest.mark.usefixtures('postgresql_dsn') class TestAssertMaxLength(object): def test_with_max_length(self, user): assert_max_length(user, 'name', 20) assert_max_length(user, 'name', 20) def test_with_non_nullable_column(self, user): assert_max_length(user, 'email', 200) assert_max_length(user, 'email', 200) def test_smaller_than_max_length(self, user): with pytest.raises(AssertionError): assert_max_length(user, 'name', 19) with pytest.raises(AssertionError): assert_max_length(user, 'name', 19) def test_bigger_than_max_length(self, user): with pytest.raises(AssertionError): assert_max_length(user, 'name', 21) with pytest.raises(AssertionError): assert_max_length(user, 'name', 21) @pytest.mark.usefixtures('postgresql_dsn') class TestAssertMinValue(object): def test_with_min_value(self, user): assert_min_value(user, 'age', 0) assert_min_value(user, 'age', 0) def test_smaller_than_min_value(self, user): with pytest.raises(AssertionError): assert_min_value(user, 'age', -1) with pytest.raises(AssertionError): assert_min_value(user, 'age', -1) def test_bigger_than_min_value(self, user): with pytest.raises(AssertionError): assert_min_value(user, 'age', 1) with pytest.raises(AssertionError): assert_min_value(user, 'age', 1) @pytest.mark.usefixtures('postgresql_dsn') class TestAssertMaxValue(object): def test_with_min_value(self, user): assert_max_value(user, 'age', 150) assert_max_value(user, 'age', 150) def test_smaller_than_max_value(self, user): with pytest.raises(AssertionError): assert_max_value(user, 'age', 149) with pytest.raises(AssertionError): assert_max_value(user, 'age', 149) def test_bigger_than_max_value(self, user): with pytest.raises(AssertionError): assert_max_value(user, 'age', 151) with pytest.raises(AssertionError): assert_max_value(user, 'age', 151)