Add utility decorator for registering backend dispatches based on modules

This commit is contained in:
Brett Sun 2016-12-02 17:29:14 +01:00 committed by Sylvain Bellemare
parent 2eb83b9993
commit daa0fe1f51
2 changed files with 93 additions and 0 deletions

View File

@ -0,0 +1,20 @@
class BackendModuleDispatchRegisterError(Exception):
"""Raised when there is a problem registering dispatched functions for a
backend module"""
def make_module_dispatch_registrar(module):
def dispatch_wrapper(obj_type):
def wrapper(func):
func_name = func.__name__
try:
dispatch_registrar = getattr(module, func_name)
return dispatch_registrar.register(obj_type)(func)
except AttributeError as ex:
raise BackendModuleDispatchRegisterError(
("'{module}' does not contain a single-dispatchable "
"function named '{func}'. The backend being used has not "
"been implemented correctly!").format(
func=func_name, module=module.__name__)) from ex
return wrapper
return dispatch_wrapper

View File

@ -0,0 +1,73 @@
import pytest
from types import ModuleType
@pytest.fixture
def mock_module():
return ModuleType('mock_module')
def test_module_dispatch_registers(mock_module):
from functools import singledispatch
from bigchaindb.backend.utils import make_module_dispatch_registrar
@singledispatch
def dispatcher(t):
pass
mock_module.dispatched = dispatcher
mock_dispatch = make_module_dispatch_registrar(mock_module)
@mock_dispatch(str)
def dispatched(t):
pass
assert mock_module.dispatched.registry[str] == dispatched
def test_module_dispatch_dispatches(mock_module):
from functools import singledispatch
from bigchaindb.backend.utils import make_module_dispatch_registrar
@singledispatch
def dispatcher(t):
return False
mock_module.dispatched = dispatcher
mock_dispatch = make_module_dispatch_registrar(mock_module)
@mock_dispatch(str)
def dispatched(t):
return True
assert mock_module.dispatched(1) is False # Goes to dispatcher()
assert mock_module.dispatched('1') is True # Goes to dispatched()
def test_module_dispatch_errors_on_missing_func(mock_module):
from bigchaindb.backend.utils import (
make_module_dispatch_registrar,
BackendModuleDispatchRegisterError,
)
mock_dispatch = make_module_dispatch_registrar(mock_module)
with pytest.raises(BackendModuleDispatchRegisterError):
@mock_dispatch(str)
def dispatched():
pass
def test_module_dispatch_errors_on_non_dispatchable_func(mock_module):
from bigchaindb.backend.utils import (
make_module_dispatch_registrar,
BackendModuleDispatchRegisterError,
)
def dispatcher():
pass
mock_module.dispatched = dispatcher
mock_dispatch = make_module_dispatch_registrar(mock_module)
with pytest.raises(BackendModuleDispatchRegisterError):
@mock_dispatch(str)
def dispatched():
pass