def test_chain_class_lookup_all(): reg1 = Registry() reg2 = Registry() reg1.register(target, (), 'reg1') reg2.register(target, (), 'reg2') lookup = ChainClassLookup(reg1, reg2) assert list(lookup.all(target, ())) == ['reg1', 'reg2']
def test_list_class_lookup_all(): reg1 = Registry() reg2 = Registry() reg1.register(target, (), 'reg1') reg2.register(target, (), 'reg2') lookup = ListClassLookup([reg1, reg2]) assert list(lookup.all(target, ())) == ['reg1', 'reg2']
def test_list_class_lookup(): reg1 = Registry() reg2 = Registry() reg2.register(target, (), 'reg2 component') lookup = ListClassLookup([reg1, reg2]) assert lookup.get(target, ()) == 'reg2 component' reg1.register(target, (), 'reg1 component') assert lookup.get(target, ()) == 'reg1 component'
def test_chain_class_lookup(): reg1 = Registry() reg2 = Registry() reg2.register(target, (), 'reg2 component') lookup = ChainClassLookup(reg1, reg2) assert lookup.get(target, ()) == 'reg2 component' reg1.register(target, (), 'reg1 component') assert lookup.get(target, ()) == 'reg1 component'
def test_matcher_inheritance(): reg = Registry() class Document(object): def __init__(self, id): self.id = id class SpecialDocument(Document): pass def linecount(obj): pass class DocumentMatcher(Matcher): def __call__(self, doc): if doc.id == 1: return 'normal' else: return 'special' class SpecialDocumentMatcher(Matcher): def __call__(self, doc): if doc.id == 2: return 'extra normal' else: return None reg.register(linecount, [Document], DocumentMatcher()) reg.register(linecount, [SpecialDocument], SpecialDocumentMatcher()) assert reg.component(linecount, [Document(1)]) == 'normal' assert reg.component(linecount, [Document(2)]) == 'special' assert reg.component(linecount, [SpecialDocument(1)]) == 'normal' assert reg.component(linecount, [SpecialDocument(2)]) == 'extra normal' assert reg.component(linecount, [SpecialDocument(3)]) == 'special'
def test_registry_target_find_specific(): reg = Registry() class Document(object): pass class SpecialDocument(Document): pass def linecount(obj): pass def special_linecount(obj): pass reg.register(linecount, [Document], 'line count') reg.register(special_linecount, [Document], 'special line count') assert reg.component(linecount, [Document()]) == 'line count' assert (reg.component(special_linecount, [Document()]) == 'special line count') assert reg.component(linecount, [SpecialDocument()]) == 'line count' assert (reg.component(special_linecount, [SpecialDocument()]) == 'special line count')
def test_registry_sources(): reg = Registry() class Document(object): pass class SpecialDocument(Document): pass def linecount(obj): pass reg.register(linecount, [Document], 'document line count') reg.register(linecount, [SpecialDocument], 'special document line count') assert (reg.component(linecount, [Document()]) == 'document line count') assert (reg.component( linecount, [SpecialDocument()]) == 'special document line count') class AnotherDocument(Document): pass assert (reg.component(linecount, [AnotherDocument()]) == 'document line count') class Other(object): pass assert reg.component(linecount, [Other()], default=None) is None
def test_call_two_sources(): reg = Registry() @generic def target(a, b): pass class Adapted(object): def __init__(self, alpha, beta): self.alpha = alpha self.beta = beta def foo(self): pass reg.register(target, [IAlpha, IBeta], Adapted) alpha = Alpha() beta = Beta() adapted = reg.call(target, [alpha, beta]) assert isinstance(adapted, Adapted) assert adapted.alpha is alpha assert adapted.beta is beta adapted = target(alpha, beta, lookup=reg) assert isinstance(adapted, Adapted) assert adapted.alpha is alpha assert adapted.beta is beta
def test_all(): class Base(object): pass class Sub(Base): pass @generic def target(obj): pass registry = Registry() registry.register(target, (Sub, ), 'registered for sub') registry.register(target, (Base, ), 'registered for base') base = Base() sub = Sub() assert list(registry.all( target, [sub])) == ['registered for sub', 'registered for base'] assert list(registry.all(target, [base])) == ['registered for base'] assert list(target.all(sub, lookup=registry)) == [ 'registered for sub', 'registered for base' ] assert list(target.all(base, lookup=registry)) == ['registered for base']
def test_lookup_passed_along_fallback(): @generic def a(lookup): return "fallback" reg = Registry() assert a(lookup=reg) == 'fallback'
def test_register_twice_without_sources(): reg = Registry() def linecount(obj): pass reg.register(linecount, [], 'once') reg.register(linecount, [], 'twice') assert reg.component(linecount, []) == 'twice'
def test_default(): reg = Registry() @generic def target(): pass assert target.component(lookup=reg, default='blah') == 'blah' assert target(lookup=reg, default='blah') == 'blah'
def test_component(): @generic def foo(): pass registry = Registry() registry.register(foo, (), "test component") assert foo.component(lookup=registry) == 'test component'
def test_implicit_component_lookup(): @generic def func(): pass reg = Registry() reg.register(func, (), 'test component') implicit.initialize(reg) assert func.component() == 'test component'
def test_component_no_source(): reg = Registry() foo = object() @generic def target(): pass reg.register(target, (), foo) assert reg.component(target, []) is foo assert target.component(lookup=reg) is foo
def test_registry_no_sources(): reg = Registry() class Animal(object): pass def something(): pass reg.register(something, (), 'elephant') assert reg.component(something, ()) == 'elephant'
def test_clear(): reg = Registry() def linecount(obj): pass reg.register(linecount, [], 'once') assert reg.component(linecount, []) == 'once' reg.clear() with pytest.raises(ComponentLookupError): reg.component(linecount, [])
def test_register_twice_with_sources(): reg = Registry() class Document(object): pass def linecount(obj): pass reg.register(linecount, [Document], 'document line count') reg.register(linecount, [Document], 'another line count') assert reg.component(linecount, [Document()]) == 'another line count'
def test_component_two_sources(): reg = Registry() foo = object() @generic def target(): pass reg.register(target, (IAlpha, IBeta), foo) alpha = Alpha() beta = Beta() assert reg.component(target, [alpha, beta]) is foo assert target.component(alpha, beta, lookup=reg) is foo
def test_non_function_called(): reg = Registry() foo = object() @generic def target(obj): pass reg.register(target, [Alpha], foo) alpha = Alpha() with pytest.raises(TypeError): target(alpha, lookup=reg)
def test_func_returns_none(): @generic def target(obj): raise NotImplementedError def adapt(obj): return None reg = Registry() reg.register(target, [Alpha], adapt) alpha = Alpha() assert target(alpha, lookup=reg) is None assert target(alpha, lookup=reg, default='default') == 'default'
def test_fallback(): @generic def target(obj): return 'fallback' reg = Registry() def specific_target(obj): return 'specific' reg.register(target, [Alpha], specific_target) beta = Beta() assert target(beta, lookup=reg) == 'fallback'
def test_component_one_source(): reg = Registry() foo = object() @generic def target(): pass reg.register(target, [Alpha], foo) alpha = Alpha() assert reg.component(target, [alpha]) is foo assert target.component(alpha, lookup=reg) is foo
def test_cached_class_lookup_all(): reg = Registry() reg.register(target, (), 'reg component') cached = CachingClassLookup(reg) assert list(cached.all(target, ())) == ['reg component'] # we change the registration reg.register(target, (), 'reg component changed') # the cache won't know assert list(cached.all(target, ())) == ['reg component']
def test_extra_kw_for_component(): @generic def target(obj): pass reg = Registry() foo = object() reg.register(target, [Alpha], foo) alpha = Alpha() with pytest.raises(TypeError) as e: target.component(alpha, lookup=reg, extra="illegal") assert str(e.value) == ("component() got an unexpected keyword " "argument 'extra'")
def test_call_no_source(): reg = Registry() foo = object() @generic def target(): pass def factory(): return foo reg.register(target, (), factory) assert reg.call(target, []) is foo assert target(lookup=reg) is foo
def test_call_with_wrong_args(): @generic def target(obj): pass class Adapter(object): # takes no args def __init__(self): pass reg = Registry() reg.register(target, [Alpha], Adapter) alpha = Alpha() with pytest.raises(TypeError): target(alpha, lookup=reg)
def test_calling_twice(): @generic def target(obj): return 'fallback' reg = Registry() def a(obj): return 'a' def b(obj): return 'b' reg.register(target, [Alpha], a) reg.register(target, [Beta], b) assert target(Alpha(), lookup=reg) == 'a' assert target(Beta(), lookup=reg) == 'b'
def test_exact(): reg = Registry() class Document(object): pass class SubDocument(Document): pass def linecount(obj): pass def other(obj): pass reg.register(linecount, [Document], 'once') assert reg.exact(linecount, [Document]) == 'once' assert reg.exact(linecount, [SubDocument]) is None assert reg.exact(other, [Document]) is None
def test_extra_kw_for_call(): @generic def target(obj, extra): return "General: %s" % extra reg = Registry() def specific(obj, extra): return "Specific: %s" % extra reg.register(target, [Alpha], specific) alpha = Alpha() beta = Beta() assert target(alpha, lookup=reg, extra="allowed") == 'Specific: allowed' assert target(beta, lookup=reg, extra="allowed") == 'General: allowed' assert target(alpha, lookup=reg, default='default', extra='allowed') == 'Specific: allowed' assert target(beta, lookup=reg, default='default', extra='allowed') == 'default'