def test_preparer(self): hook = HookMultiplexer(preparer=Hook()) counter1 = Counter() counter2 = Counter() counter_mapped = Counter() counter_preparer = Counter() @hook def derp(event): counter1.tick() @hook("herp") def herp(event): counter2.tick() mapping = {"dink": "herp", "donk": "derp"} @hook.preparer def prepare(event): if event.name in mapping: event.name = mapping[event.name] counter_mapped.tick() counter_preparer.tick() assert counter1.count == 0 assert counter2.count == 0 assert counter_preparer.count == 0 assert counter_mapped.count == 0 hook.fire(name="dink") assert counter1.count == 0 assert counter2.count == 1 assert counter_preparer.count == 1 assert counter_mapped.count == 1 hook.fire(name="donk") assert counter1.count == 1 assert counter2.count == 1 assert counter_preparer.count == 2 assert counter_mapped.count == 2 hook.fire(name="herp") assert counter1.count == 1 assert counter2.count == 2 assert counter_preparer.count == 3 assert counter_mapped.count == 2 hook.fire(name="derp") assert counter1.count == 2 assert counter2.count == 2 assert counter_preparer.count == 4 assert counter_mapped.count == 2
def test_protocol(monkeypatch): conn_hooks = AttrDict() monkeypatch.setattr(hook, "connection", conn_hooks) delimiter_sentinel = object() server = AttrDict(delimiter=delimiter_sentinel) factory = main.ConnectionFactory(server) assert factory.server is server protocol = factory.buildProtocol("irc.example.net") assert server._reactor_connection is protocol assert protocol.server is server assert protocol.delimiter is server.delimiter conn_hooks.made = Hook() result = AttrDict() updated = Counter() @conn_hooks.made def onmade(event): result.update(event) updated.tick() protocol.connectionMade() assert updated.incremented(1) # goes out of its way to not assert that the connection # object is actually what is passed into the event call @result.conn.received def received(event): assert event.line == "incoming line" event.received = True event.command = "command" commands = Counter() @result.conn.received("command") def received_command(event): assert event.received == True commands.tick() protocol.lineReceived("incoming line") assert commands.incremented(1) disconnect_count = Counter() reason_sentinel = object() @result.conn.disconnect def disconnected(event): assert event.reason is reason_sentinel disconnect_count.tick() protocol.connectionLost(reason_sentinel) assert disconnect_count.incremented(1)
def test_simple_dependency(self, target): """ Test that simple three-in-a-row dependencies work """ counter = Counter() hook = target() @hook def second(event): "handler with no dependencies" assert event.first_was_called event.second_was_called = True assert counter.count == 1 counter.tick() @hook(before=second) def first(event): "handler which reverse-depends only on the second handler" assert counter.count == 0 counter.tick() event.first_was_called = True @hook(after=second) def third(event): "handler which depends on the second handler" assert counter.count == 2 counter.tick() assert event.first_was_called assert event.second_was_called hook.fire() assert counter.count == 3
def test_tags(self, target): counter = Counter() hook = target(["early", "normal", "late"]) @hook(tag="normal") def func_normal(event): assert event.first_was_called event.second_was_called = True assert counter.count == 1 counter.tick() @hook(tag="early") def func_early(event): assert counter.count == 0 counter.tick() event.first_was_called = True @hook(tag="late") def func_late(event): assert counter.count == 2 counter.tick() assert event.first_was_called assert event.second_was_called assert event.somewhere_was_called @hook(before=":late", after="early") def func_somewhere(event): assert event.first_was_called event.somewhere_was_called = True assert counter.count > 0 hook.fire() assert counter.count == 3
def test_createhook_lazyness(self): counter = Counter() hooktree = HookTree(start_lazy=True, hook_class=counter.tick) hooktree.createhook('child_hook') assert counter.incremented(0) hooktree._unlazy() assert counter.incremented(1)
def test_command_nameinfer(self): hook = HookMultiplexer() counter = Counter() @hook def derp(event): counter.tick() hook.fire(name="derp") assert counter.count == 1
def test_error_logging(self, capsys, target): safe_hook = target(stop_exceptions=True) safe_counter = Counter() class TestErrorLoggingError(Exception): pass @safe_hook def raising_handler(event): event.before = True raise TestErrorLoggingError("derp") @safe_hook(after="raising_handler") def check_success(event): safe_counter.tick() assert event.before oldout, olderr = capsys.readouterr() # check that it works safe_hook.fire() assert safe_counter.count == 1 out, err = capsys.readouterr() # test that the error was logged assert "TestErrorLoggingError" in out assert "derp" in out assert "raising_handler" in out unsafe_hook = target(stop_exceptions=False) unsafe_counter = Counter() @unsafe_hook def raising_handler_2(event): event.before = True raise TestErrorLoggingError("herp") @unsafe_hook(after="raising_handler_2") def should_never_run(event): # pragma: no cover assert event.before unsafe_counter.tick() with pytest.raises(TestErrorLoggingError): unsafe_hook.fire() assert unsafe_counter.count == 0
def test_custom_childarg(self): hook = HookMultiplexer(childarg="subject_home_town_here") counter = Counter() @hook def child(event): counter.tick() hook.fire(subject_home_town_here="child") assert counter.incremented(1)
def test_simple(self, target): """ Test that simple use of the Hook class works """ counter = Counter() hook = target() @hook def testfunc(event): "call check" counter.tick() hook.fire() assert counter.count == 1
def test_explicit_name(self): hook = HookMultiplexer() counter = Counter() @hook("herp") def derp(event): counter.tick() hook.fire(name="herp") assert counter.count == 1 with pytest.raises(NameResolutionError): hook.fire(name="derp")
def test_mainloop(): counter = Counter() def run(): counter.tick() reactor = AttrDict(run=run) event = AttrDict(reactor=reactor) main.mainloop(event) assert counter.incremented(1)
def test_complex_decorator(): lazycall = LazyCall((), ("arg1", "arg2"), {"key": "word"}, True, False) complex_counter = Counter() actual_counter = Counter() def sentinel_func(): should_never_run() def complex_decorator(arg1, arg2, key=False): assert arg1 == "arg1" assert arg2 == "arg2" assert key == "word" def actual_decorator(func): assert func is sentinel_func actual_counter.tick() complex_counter.tick() return actual_decorator lazycall.resolve(complex_decorator, sentinel_func) assert complex_counter.incremented(1) assert actual_counter.incremented(1)
def test_mainloop_refire(self): hook = crow2.main.MainloopHook() counter = Counter() @hook def mainloop(event): with pytest.raises(crow2.main.AlreadyRunningError): hook.fire(event) counter.tick() hook.fire() assert counter.incremented(1)
def test_register_once_explicitname(self): hook = HookMultiplexer() counter = Counter() def handler(event): counter.tick() hook.register_once(handler, "handler_name") hook.fire(name="handler_name") assert counter.incremented(1) with pytest.raises(NameResolutionError): hook.fire(name="handler_name")
def test_integration(): hook1 = Hook() hook2 = Hook() hook_method = Hook() @handlerclass(hook1) @handlerclass(hook2) class Clazz(object): def __init__(self, event): event.counter.tick() @handlermethod(hook_method) def a_method(self, event): event.other_counter.tick() @instancehandler.hook(tag="derp") def a_handler(self, event): event.counter2.tick() @instancehandler.hook_destroy def destroy(self, event): self.delete() result = hook_method.fire(other_counter=Counter()) assert result.other_counter.incremented(0) hook1_result = hook1.fire(hook=Hook(), hook_destroy=Hook(), counter=Counter()) hook2_result = hook2.fire(hook=Hook(), hook_destroy=Hook(), counter=Counter()) assert hook1_result.counter.incremented(1) assert hook2_result.counter.incremented(1) result = hook_method.fire(other_counter=Counter()) assert result.other_counter.incremented(2) print hook2_result.hook hook3_result = hook2_result.hook.fire(counter2=Counter()) assert hook3_result.counter2.incremented(1) hook1_result.hook_destroy.fire() result = hook_method.fire(other_counter=Counter()) assert result.other_counter.incremented(1) hook2_result.hook_destroy.fire() result = hook_method.fire(other_counter=Counter()) assert result.other_counter.incremented(0) hook3_result = hook2_result.hook.fire(counter2=Counter()) assert hook3_result.counter2.incremented(0)
def test_lazy_decorate(): lazycall = LazyCall(("decorator",), (), {}, True, True) decorate_count = Counter() def sentinel_func(): should_never_run() def simple_decorator(func): assert func is sentinel_func decorate_count.tick() obj = AttrDict(decorator=simple_decorator) lazycall.resolve(obj, sentinel_func) assert decorate_count.incremented(1)
def test_lazy_call(): lazycall = LazyCall(("herp", "derp"), ("args",), {"key": "words"}, False) counter = Counter() def target(value, key): assert value == "args" assert key == "words" counter.tick() herp = AttrDict(derp=target) obj = AttrDict(herp=herp) assert counter.incremented(0) lazycall.resolve(obj) assert counter.incremented(1)
def test_calldicts(self, target): hook = target() counter = Counter() @hook def check(event): assert event.foo assert event.bar event.baz = True originalcontext = {"foo": True} context = dict(originalcontext) result = hook.fire(context, bar=True) assert result.foo assert result.bar assert result.baz assert context == originalcontext
def test_once(self, target): hook = target(["tag", "tag2"]) counter = Counter() def callonce(event): counter.tick() assert counter.count == 1 hook.register_once(callonce, tag="tag") def callsecond(event): counter.tick() assert counter.count == 2 hook.register_once(callsecond, tag="tag2") def forgetme(event): pass # tests tag garbage collection hook.register_once(forgetme, tag="temporary_tag") hook.fire() assert counter.incremented(2) hook.fire() assert counter.incremented(0) def tag_stub(event): should_never_run() hook.register_once(tag_stub, tag="tag") def tag2_stub(event): should_never_run() hook.register_once(tag2_stub, tag="tag2") def impossible_link(event): should_never_run() hook.register_once(impossible_link, before="tag", after="tag2") # if this fails, the tags were lost when there was nothing # pointed to them with pytest.raises(exceptions.CyclicDependencyError): hook.fire() with pytest.raises(exceptions.NotRegisteredError): hook.unregister(callonce)
def test_init(monkeypatch): startLogging_counter = Counter() def startLogging(outfile, setStdout=True): assert setStdout == False assert outfile is sys.stdout startLogging_counter.tick() logstub = AttrDict(startLogging=startLogging) fakeservers = {} class FakeServer(object): def __init__(self, reactor, name, options): self.reactor = reactor self.name = name self.options = options self.connected = False fakeservers[name] = self def connect(self): self.connected = True monkeypatch.setattr(main, "log", logstub) monkeypatch.setattr(main, "Server", FakeServer) reactor_sentinel = object() connections = {"test_1": object(), "test_2": object()} config = AttrDict(connections=connections) event = AttrDict(config=config, reactor=reactor_sentinel) main.init(event) assert startLogging_counter.incremented(1) assert len(fakeservers) == len(connections) assert all(fakeserver.reactor is reactor_sentinel for fakeserver in fakeservers.values()) assert all(fakeserver.connected for fakeserver in fakeservers.values()) assert fakeservers["test_1"].options is connections["test_1"] assert fakeservers["test_2"].options is connections["test_2"]
def test_multi_unregister_samehook(self): hook = HookMultiplexer() counter = Counter() @hook("derp") def handler1(event): counter.tick() @hook("derp") def handler2(event): counter.tick() hook.fire(name="derp") assert counter.incremented(2) hook.unregister(handler1) hook.fire(name="derp") assert counter.incremented(1) hook.unregister(handler2) with pytest.raises(NameResolutionError): hook.fire(name="derp")
def test_instancehandler(): class Target(object): def __init__(self): self.counter = Counter() @instancehandler.thing.hook @instancehandler.otherthing.otherhook() @instancehandler.argthing.arg(derp=True) def a_method(self, event): should_never_run() a_method = vars(Target)["a_method"] regs = a_method._crow2_instancehookregs by_names = dict([(reg.attributes, reg) for reg in regs]) assert set(by_names.keys()) == set((("thing", "hook"), ("otherthing", "otherhook"), ("argthing", "arg"))) instances = [Target(), Target()] unregister_counter = Counter() for instance in instances: simple_counter = Counter() partial_counter = Counter() arg_counter = Counter() def simpledecorator(func): simple_counter.tick() def partialdecorator(): partial_counter.tick() def partial(func): partial_counter.tick() return partial def argdecorator(derp): arg_counter.tick() def partial(func): arg_counter.tick() return partial argdecorator.unregister = lambda func: unregister_counter.tick() partialdecorator.unregister = lambda func: unregister_counter.tick() simpledecorator.unregister = lambda func: unregister_counter.tick() event = AttrDict() event.thing = AttrDict(hook=simpledecorator) event.otherthing = AttrDict(otherhook=partialdecorator) event.argthing = AttrDict(arg=argdecorator) by_names["thing", "hook"].add_bound_method(instance.a_method, event) assert simple_counter.incremented(1) by_names["otherthing", "otherhook"].add_bound_method(instance.a_method, event) assert partial_counter.incremented(2) by_names["argthing", "arg"].add_bound_method(instance.a_method, event) assert arg_counter.incremented(2) for instance in instances: by_names["thing", "hook"].remove_bound_method(instance.a_method) by_names["otherthing", "otherhook"].remove_bound_method(instance.a_method) by_names["argthing", "arg"].remove_bound_method(instance.a_method) assert unregister_counter.incremented(3)
def __init__(self): self.counter = Counter()