diff --git a/test/async_/test_properties.py b/test/async_/test_properties.py index 655dfd87..6dec67b4 100644 --- a/test/async_/test_properties.py +++ b/test/async_/test_properties.py @@ -5,7 +5,13 @@ from pytest import mark, raises from pytz import timezone -from neomodel import AsyncRelationship, AsyncStructuredNode, AsyncStructuredRel, adb +from neomodel import ( + AsyncRelationship, + AsyncStructuredNode, + AsyncStructuredRel, + adb, + config, +) from neomodel.contrib import AsyncSemiStructuredNode from neomodel.exceptions import ( DeflateError, @@ -14,6 +20,7 @@ UniqueProperty, ) from neomodel.properties import ( + AliasProperty, ArrayProperty, BooleanProperty, DateProperty, @@ -115,7 +122,7 @@ def tartiflate(self, value): def test_boolean_property(): - prop = BooleanProperty() + prop = BooleanProperty(default=False) prop.name = "foo" prop.owner = FooBar assert prop.deflate(True) is True @@ -123,7 +130,7 @@ def test_boolean_property(): assert prop.inflate(True) is True assert prop.inflate(False) is False - assert prop.has_default is False + assert prop.default_value() is False def test_datetimes_timezones(): @@ -141,6 +148,18 @@ def test_datetimes_timezones(): assert time1.utctimetuple() < time2.utctimetuple() assert time1.tzname() == "UTC" + with raises(ValueError, match="too many defaults"): + _ = DateTimeFormatProperty( + default_now=True, default=datetime(1900, 1, 1, 0, 0, 0) + ) + + prev_force_timezone = config.FORCE_TIMEZONE + config.FORCE_TIMEZONE = True + with raises(ValueError, match=r".*No timezone provided."): + prop.deflate(datetime.now()) + + config.FORCE_TIMEZONE = prev_force_timezone + def test_date(): prop = DateProperty() @@ -150,6 +169,8 @@ def test_date(): assert prop.deflate(somedate) == "2012-12-15" assert prop.inflate("2012-12-15") == somedate + assert prop.inflate(time.DateTime(2007, 9, 27)) == date(2007, 9, 27) + def test_datetime_format(): some_format = "%Y-%m-%d %H:%M:%S" @@ -160,6 +181,22 @@ def test_datetime_format(): assert prop.deflate(some_datetime) == "2019-03-19 15:36:25" assert prop.inflate("2019-03-19 15:36:25") == some_datetime + with raises(ValueError, match=r"datetime object expected, got.*"): + prop.deflate(1234) + + with raises(ValueError, match="too many defaults"): + _ = DateTimeFormatProperty( + default_now=True, default=datetime(1900, 1, 1, 0, 0, 0) + ) + + secondProp = DateTimeFormatProperty(default_now=True) + assert secondProp.has_default + assert ( + timedelta(seconds=-2) + < secondProp.default - datetime.now() + < timedelta(seconds=2) + ) + def test_datetime_neo4j_format(): prop = DateTimeNeo4jFormatProperty() @@ -516,6 +553,20 @@ class CheckMyId(AsyncStructuredNode): cmid = await CheckMyId().save() assert len(cmid.uid) + matched_exception = r".*argument ignored by.*" + # Test ignored arguments + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(required=False) + + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(unique_index=False) + + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(index=False) + + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(default="kakapo") + class ArrayProps(AsyncStructuredNode): uid = StringProperty(unique_index=True) @@ -625,3 +676,17 @@ class UniqueNullableNameNode(AsyncStructuredNode): await x.delete() await y.delete() await z.delete() + + +def test_alias_property(): + class AliasedClass(AsyncStructuredNode): + name = StringProperty(index=True) + national_id = IntegerProperty(unique_index=True) + alias = AliasProperty(to="name") + alias_national_id = AliasProperty(to="national_id") + whatever = StringProperty() + alias_whatever = AliasProperty(to="whatever") + + assert AliasedClass.alias.index is True + assert AliasedClass.alias_national_id.unique_index is True + assert AliasedClass.alias_whatever.index is False diff --git a/test/sync_/test_properties.py b/test/sync_/test_properties.py index ef6ca3eb..83662f21 100644 --- a/test/sync_/test_properties.py +++ b/test/sync_/test_properties.py @@ -5,7 +5,7 @@ from pytest import mark, raises from pytz import timezone -from neomodel import Relationship, StructuredNode, StructuredRel, db +from neomodel import Relationship, StructuredNode, StructuredRel, config, db from neomodel.contrib import SemiStructuredNode from neomodel.exceptions import ( DeflateError, @@ -14,6 +14,7 @@ UniqueProperty, ) from neomodel.properties import ( + AliasProperty, ArrayProperty, BooleanProperty, DateProperty, @@ -115,7 +116,7 @@ def tartiflate(self, value): def test_boolean_property(): - prop = BooleanProperty() + prop = BooleanProperty(default=False) prop.name = "foo" prop.owner = FooBar assert prop.deflate(True) is True @@ -123,7 +124,7 @@ def test_boolean_property(): assert prop.inflate(True) is True assert prop.inflate(False) is False - assert prop.has_default is False + assert prop.default_value() is False def test_datetimes_timezones(): @@ -141,6 +142,18 @@ def test_datetimes_timezones(): assert time1.utctimetuple() < time2.utctimetuple() assert time1.tzname() == "UTC" + with raises(ValueError, match="too many defaults"): + _ = DateTimeFormatProperty( + default_now=True, default=datetime(1900, 1, 1, 0, 0, 0) + ) + + prev_force_timezone = config.FORCE_TIMEZONE + config.FORCE_TIMEZONE = True + with raises(ValueError, match=r".*No timezone provided."): + prop.deflate(datetime.now()) + + config.FORCE_TIMEZONE = prev_force_timezone + def test_date(): prop = DateProperty() @@ -150,6 +163,8 @@ def test_date(): assert prop.deflate(somedate) == "2012-12-15" assert prop.inflate("2012-12-15") == somedate + assert prop.inflate(time.DateTime(2007, 9, 27)) == date(2007, 9, 27) + def test_datetime_format(): some_format = "%Y-%m-%d %H:%M:%S" @@ -160,6 +175,22 @@ def test_datetime_format(): assert prop.deflate(some_datetime) == "2019-03-19 15:36:25" assert prop.inflate("2019-03-19 15:36:25") == some_datetime + with raises(ValueError, match=r"datetime object expected, got.*"): + prop.deflate(1234) + + with raises(ValueError, match="too many defaults"): + _ = DateTimeFormatProperty( + default_now=True, default=datetime(1900, 1, 1, 0, 0, 0) + ) + + secondProp = DateTimeFormatProperty(default_now=True) + assert secondProp.has_default + assert ( + timedelta(seconds=-2) + < secondProp.default - datetime.now() + < timedelta(seconds=2) + ) + def test_datetime_neo4j_format(): prop = DateTimeNeo4jFormatProperty() @@ -512,6 +543,20 @@ class CheckMyId(StructuredNode): cmid = CheckMyId().save() assert len(cmid.uid) + matched_exception = r".*argument ignored by.*" + # Test ignored arguments + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(required=False) + + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(unique_index=False) + + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(index=False) + + with raises(ValueError, match=matched_exception): + _ = UniqueIdProperty(default="kakapo") + class ArrayProps(StructuredNode): uid = StringProperty(unique_index=True) @@ -621,3 +666,17 @@ class UniqueNullableNameNode(StructuredNode): x.delete() y.delete() z.delete() + + +def test_alias_property(): + class AliasedClass(StructuredNode): + name = StringProperty(index=True) + national_id = IntegerProperty(unique_index=True) + alias = AliasProperty(to="name") + alias_national_id = AliasProperty(to="national_id") + whatever = StringProperty() + alias_whatever = AliasProperty(to="whatever") + + assert AliasedClass.alias.index is True + assert AliasedClass.alias_national_id.unique_index is True + assert AliasedClass.alias_whatever.index is False