-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The fact event generation logic was considering attributes from elements directly and constructing new value-object based event classes directly. This does not work well because the same attribute is shared between the actual element and the newly generated event class. This commit introduces a clone method at the field level so we can copy the field safely.
- Loading branch information
Showing
4 changed files
with
132 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
from unittest.mock import MagicMock | ||
|
||
from protean.fields import Text | ||
|
||
|
||
class TestFieldClone: | ||
def test_clone_basic_field(self): | ||
# Arrange | ||
field = Text( | ||
referenced_as="test_field", | ||
description="Test Text", | ||
identifier=True, | ||
default="default_value", | ||
required=True, | ||
unique=True, | ||
choices=None, | ||
validators=[], | ||
error_messages={"invalid": "Invalid value"}, | ||
) | ||
|
||
# Act | ||
cloned_field = field._clone() | ||
|
||
# Assert | ||
assert cloned_field is not field, "The cloned field should be a new instance" | ||
assert cloned_field.referenced_as == field.referenced_as | ||
assert cloned_field.description == field.description | ||
assert cloned_field.identifier == field.identifier | ||
assert cloned_field.default == field.default | ||
assert cloned_field.required == field.required | ||
assert cloned_field.unique == field.unique | ||
assert cloned_field.choices == field.choices | ||
assert cloned_field.validators == field.validators | ||
assert cloned_field.error_messages == field.error_messages | ||
|
||
def test_clone_with_choices(self): | ||
# Arrange | ||
choices_mock = MagicMock() | ||
field = Text( | ||
referenced_as="test_field", | ||
description="Test Text", | ||
identifier=False, | ||
default=None, | ||
required=False, | ||
unique=False, | ||
choices=choices_mock, | ||
validators=[], | ||
error_messages={"invalid_choice": "Invalid choice"}, | ||
) | ||
|
||
# Act | ||
cloned_field = field._clone() | ||
|
||
# Assert | ||
assert cloned_field is not field, "The cloned field should be a new instance" | ||
assert ( | ||
cloned_field.choices == field.choices | ||
), "Choices should be identical in the clone" | ||
|
||
def test_clone_with_validators(self): | ||
# Arrange | ||
validators = [lambda x: x > 0] | ||
field = Text( | ||
referenced_as="test_field", | ||
description="Test Text", | ||
identifier=False, | ||
default=None, | ||
required=False, | ||
unique=False, | ||
choices=None, | ||
validators=validators, | ||
error_messages={"required": "This field is required"}, | ||
) | ||
|
||
# Act | ||
cloned_field = field._clone() | ||
|
||
# Assert | ||
assert cloned_field is not field, "The cloned field should be a new instance" | ||
assert ( | ||
cloned_field.validators == field.validators | ||
), "Validators should be identical in the clone" | ||
|
||
def test_clone_with_default_callable(self): | ||
# Arrange | ||
field = Text( | ||
referenced_as="test_field", | ||
description="Test Text", | ||
identifier=False, | ||
default=lambda: "dynamic_default", | ||
required=False, | ||
unique=False, | ||
choices=None, | ||
validators=[], | ||
error_messages={"invalid": "Invalid value"}, | ||
) | ||
|
||
# Act | ||
cloned_field = field._clone() | ||
|
||
# Assert | ||
assert cloned_field is not field, "The cloned field should be a new instance" | ||
assert ( | ||
cloned_field.default is field.default | ||
), "Default callable should be identical in the clone" |