Skip to content

Commit

Permalink
Merge pull request #474 from minos-framework/0.7.1
Browse files Browse the repository at this point in the history
0.7.1.dev1
  • Loading branch information
Sergio García Prado authored Jun 2, 2022
2 parents 5c647f0 + af4b0e9 commit 1b33fee
Show file tree
Hide file tree
Showing 30 changed files with 509 additions and 352 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

__author__ = "Minos Framework Devs"
__email__ = "[email protected]"
__version__ = "0.7.0"
__version__ = "0.7.1.dev1"

from .actions import (
Action,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ def simplified_name(self) -> str:
return self.name.rsplit(".", 1)[-1]

def __lt__(self, other: Any) -> bool:
return isinstance(other, type(self)) and self.version < other.version
return isinstance(other, type(self)) and (
(self.uuid == other.uuid and self.version < other.version) or (self.created_at < other.created_at)
)

def __getitem__(self, item: str) -> Any:
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ def _evaluate(self, value: Model) -> bool:
return self._get_field(value) in self.parameter


class _ContainsCondition(_SimpleCondition):
def _evaluate(self, value: Model) -> bool:
return self.parameter in self._get_field(value)


class _LikeCondition(_SimpleCondition):
def _evaluate(self, value: Model) -> bool:
return bool(self._pattern.fullmatch(self._get_field(value)))
Expand Down Expand Up @@ -205,6 +210,7 @@ class Condition:
EQUAL = _EqualCondition
NOT_EQUAL = _NotEqualCondition
IN = _InCondition
CONTAINS = _ContainsCondition
LIKE = _LikeCondition


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ class SnapshotRepositoryTestCase(MinosTestCase, ABC):

snapshot_repository: SnapshotRepository

class NumbersList(RootEntity):
"""For testing purposes"""

numbers: list[int]

class Number(RootEntity):
"""For testing purposes"""

value: int

class Owner(RootEntity):
"""For testing purposes"""

Expand Down Expand Up @@ -386,6 +396,52 @@ async def test_find_by_uuid(self):
]
self.assertEqual(expected, observed)

async def test_find_contains(self):
a = FieldDiffContainer([FieldDiff("numbers", list[int], [1, 2, 3])])
b = FieldDiffContainer([FieldDiff("numbers", list[int], [4, 5, 6])])
c = FieldDiffContainer([FieldDiff("numbers", list[int], [3, 8, 9])])
await self.event_repository.create(
EventEntry(name=self.NumbersList.classname, data=a.avro_bytes, uuid=self.uuid_1)
)
await self.event_repository.create(
EventEntry(name=self.NumbersList.classname, data=b.avro_bytes, uuid=self.uuid_2)
)
await self.event_repository.create(
EventEntry(name=self.NumbersList.classname, data=c.avro_bytes, uuid=self.uuid_3)
)
await self.synchronize()

condition = Condition.CONTAINS("numbers", 3)

iterable = self.snapshot_repository.find(self.NumbersList, condition, ordering=Ordering.ASC("updated_at"))
observed = [v async for v in iterable]

expected = [
await self.snapshot_repository.get(self.NumbersList, self.uuid_1),
await self.snapshot_repository.get(self.NumbersList, self.uuid_3),
]
self.assertEqual(expected, observed)

async def test_find_equal(self):
a = FieldDiffContainer([FieldDiff("value", int, 1)])
b = FieldDiffContainer([FieldDiff("value", int, 2)])
c = FieldDiffContainer([FieldDiff("value", int, 1)])
await self.event_repository.create(EventEntry(name=self.Number.classname, data=a.avro_bytes, uuid=self.uuid_1))
await self.event_repository.create(EventEntry(name=self.Number.classname, data=b.avro_bytes, uuid=self.uuid_2))
await self.event_repository.create(EventEntry(name=self.Number.classname, data=c.avro_bytes, uuid=self.uuid_3))
await self.synchronize()

condition = Condition.EQUAL("value", 1)

iterable = self.snapshot_repository.find(self.Number, condition, ordering=Ordering.ASC("updated_at"))
observed = [v async for v in iterable]

expected = [
await self.snapshot_repository.get(self.Number, self.uuid_1),
await self.snapshot_repository.get(self.Number, self.uuid_3),
]
self.assertEqual(expected, observed)

async def test_find_with_transaction(self):
await self.populate_and_synchronize()
condition = Condition.IN("uuid", [self.uuid_2, self.uuid_3])
Expand Down
126 changes: 63 additions & 63 deletions packages/core/minos-microservice-aggregate/poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/core/minos-microservice-aggregate/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "minos-microservice-aggregate"
version = "0.7.0"
version = "0.7.1.dev1"
description = "The Aggregate pattern of the Minos Framework"
readme = "README.md"
repository = "https://github.com/minos-framework/minos-python"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,17 @@ def test_simplified_name(self):
self.assertEqual("Car", self.diff.simplified_name)

def test_total_ordering(self):
observed = [
values = [
Event.from_root_entity(Car(3, "blue", version=4)),
Event.from_root_entity(Car(3, "blue", version=1)),
Event.from_root_entity(Car(3, "blue", version=3)),
Event.from_root_entity(Car(3, "blue", version=2)),
Event.from_root_entity(Owner("foo", "bar", version=4, updated_at=current_datetime())),
Event.from_root_entity(Owner("foo", "bar", version=3, updated_at=current_datetime())),
]
observed.sort()
observed = sorted(values)

expected = [
Event.from_root_entity(Car(3, "blue", version=1)),
Event.from_root_entity(Car(3, "blue", version=2)),
Event.from_root_entity(Car(3, "blue", version=3)),
Event.from_root_entity(Car(3, "blue", version=4)),
]
expected = [values[5], values[4], values[1], values[3], values[2], values[0]]
self.assertEqual(expected, observed)

def test_from_root_entity(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class _Text(DeclarativeModel):
value: str


class _ListInt(DeclarativeModel):
value: list[int]


class TestCondition(unittest.TestCase):
def test_hash(self):
self.assertIsInstance(hash(Condition.EQUAL("value", 3)), int)
Expand Down Expand Up @@ -126,6 +130,13 @@ def test_condition_in(self):
self.assertFalse(condition.evaluate(_Number(42)))
self.assertTrue(condition.evaluate(_Number(56)))

def test_condition_contains(self):
condition = Condition.CONTAINS("value", 1)
self.assertEqual("_ContainsCondition('value', 1)", repr(condition))

self.assertFalse(condition.evaluate(_ListInt([42, 3, -5])))
self.assertTrue(condition.evaluate(_ListInt([1, 2, 3])))

def test_condition_like(self):
condition = Condition.LIKE("value", "a%[^ou]")
self.assertEqual("_LikeCondition('value', 'a%[^ou]')", repr(condition))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,44 @@ async def test_find_by_uuid(self):
):
await super().test_find_by_uuid()

async def test_find_contains(self):
entities = [
SnapshotRepositoryTestCase.NumbersList([1, 2, 3], uuid=self.uuid_2),
SnapshotRepositoryTestCase.NumbersList([3, 8, 9], uuid=self.uuid_3),
]
with patch.object(DatabaseClient, "fetch_one", return_value=(9999,)):
with patch.object(
DatabaseClient,
"fetch_all",
side_effect=[
FakeAsyncIterator(
[tuple(SnapshotEntry.from_root_entity(entity).as_raw().values()) for entity in entities]
),
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[0]).as_raw().values())]),
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[1]).as_raw().values())]),
],
):
await super().test_find_contains()

async def test_find_equal(self):
entities = [
SnapshotRepositoryTestCase.Number(1, uuid=self.uuid_2),
SnapshotRepositoryTestCase.Number(1, uuid=self.uuid_3),
]
with patch.object(DatabaseClient, "fetch_one", return_value=(9999,)):
with patch.object(
DatabaseClient,
"fetch_all",
side_effect=[
FakeAsyncIterator(
[tuple(SnapshotEntry.from_root_entity(entity).as_raw().values()) for entity in entities]
),
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[0]).as_raw().values())]),
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[1]).as_raw().values())]),
],
):
await super().test_find_equal()

async def test_find_with_transaction(self):
entities = [
SnapshotRepositoryTestCase.Car(3, "blue", uuid=self.uuid_2, version=4),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""The common core of the Minos Framework."""
__author__ = "Minos Framework Devs"
__email__ = "[email protected]"
__version__ = "0.7.0"
__version__ = "0.7.1.dev1"

from .builders import (
BuildableMixin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
TYPE_CHECKING,
Any,
Optional,
Type,
TypeVar,
Union,
get_args,
Expand Down Expand Up @@ -241,7 +240,7 @@ def _build_uuid(data: Any, **kwargs) -> UUID:
pass
raise DataDecoderTypeException(UUID, data)

def _build_model(self, type_: Type[Model], data: Any, **kwargs) -> Any:
def _build_model(self, type_: type[Model], data: Any, **kwargs) -> Any:
if is_type_subclass(type_) and isinstance(data, type_):
return data
return self._build_model_type(ModelType.from_model(type_), data, **kwargs)
Expand All @@ -254,7 +253,7 @@ def _build_model_type(self, type_: ModelType, data: Any, **kwargs) -> Any:
if (ans := type_.model_cls.decode_data(self, data, type_, **kwargs)) is not MissingSentinel:
return ans

if isinstance(data, dict):
if isinstance(data, Mapping):
with suppress(Exception):
decoded_data = {
field_name: self._build(field_type, data[field_name], **kwargs)
Expand Down
Loading

0 comments on commit 1b33fee

Please sign in to comment.