Skip to content

Commit

Permalink
Added test case for decorators. Improved the 'mutate' decorator.
Browse files Browse the repository at this point in the history
  • Loading branch information
johnbywater committed May 2, 2017
1 parent 8192200 commit 6df5898
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 6 deletions.
30 changes: 24 additions & 6 deletions eventsourcing/domain/model/decorators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from inspect import isfunction

from six import wraps

try:
# Python 3.4+
from functools import singledispatch
Expand Down Expand Up @@ -38,19 +40,35 @@ def wrap(handler_func):
return wrap


def mutator(func):
def mutator(arg=None):
"""Like singledispatch, but dispatches on type of last arg,
which fits better with reduce().
Can be used directly, invoked with the decorated
function. Can also be invoked with the type it
handles, to create a decorator that injects the type
when the given initial value is None.
"""

wrapped = singledispatch(func)
domain_class = None

def _mutator(func):
wrapped = singledispatch(func)

def wrapper(*args, **kw):
return wrapped.dispatch(args[-1].__class__)(*args, **kw)
@wraps(wrapped)
def wrapper(initial, event):
initial = initial or domain_class
return wrapped.dispatch(type(event))(initial, event)

wrapper.register = wrapped.register
wrapper.register = wrapped.register

return wrapper
return wrapper

if isfunction(arg):
return _mutator(arg)
else:
domain_class = arg
return _mutator


def attribute(getter):
Expand Down
3 changes: 3 additions & 0 deletions eventsourcing/tests/core_tests/test_aggregate_root.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ def id(self):

@mutator
def mutate_example_aggregate(self, event):
"""
Mutator function for class ExampleAggregateRoot.
"""
return mutate_entity(self, event)


Expand Down
60 changes: 60 additions & 0 deletions eventsourcing/tests/core_tests/test_decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from unittest.case import TestCase

from eventsourcing.domain.model.decorators import mutator


class TestDecorators(TestCase):

def test_mutate_without_arg(self):
# Define an entity class, and event class, and a mutator function.

class Entity(object): pass

class Event(object): pass

@mutator
def mutate_entity(initial, event):
"""Docstring for function mutate()."""
raise NotImplementedError()

# Check the function looks like the original.
self.assertEqual(mutate_entity.__doc__, "Docstring for function mutate().")

# Check it is capable of registering event handlers.
@mutate_entity.register(Event)
def mutate_with_event(initial, event):
return Entity()

# Check it dispatches on type of last arg.
self.assertIsInstance(mutate_entity(None, Event()), Entity)

# Check it handles unregistered types.
with self.assertRaises(NotImplementedError):
mutate_entity(None, None)

def test_mutate_with_arg(self):
# Define an entity class, and event class, and a mutator function.

class Entity(object): pass

class Event(object): pass

@mutator(Entity)
def mutate_entity(initial, event):
"""Docstring for function mutate()."""
raise NotImplementedError()

# Check the function looks like the original.
self.assertEqual(mutate_entity.__doc__, "Docstring for function mutate().")

# Check it is capable of registering event handlers.
@mutate_entity.register(Event)
def mutate_with_event(initial, event):
return initial()

# Check it dispatches on type of last arg.
self.assertIsInstance(mutate_entity(None, Event()), Entity)

# Check it handles unregistered types.
with self.assertRaises(NotImplementedError):
mutate_entity(None, None)
1 change: 1 addition & 0 deletions eventsourcing/tests/core_tests/test_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ def test_mutator_errors(self):
created_mutator(TimestampedVersionedEntity, mock.Mock(spec=Created)) # needs more than the mock obj has



class CustomValueObject(object):
def __init__(self, value):
self.value = value
Expand Down

0 comments on commit 6df5898

Please sign in to comment.