Exemple #1
0
    def __init__(self, clazz):
        self.clazz = clazz
        flattened = AttrDict()
        self.flattened = flattened
        assert clazz is not None
        resolved_mro = inspect.getmro(clazz)
        for parentclass in reversed(resolved_mro):
            flattened.update(parentclass.__dict__)

        self._proxy_for = (clazz, )

        init = flattened['__init__']
        if _get_method_regs(init):
            raise NotInstantiableError(
                "%r: cannot register class %r for instantiation with listening __init__"
                % (self, clazz))

        self.method_regs = set()
        self.registered = False
        for name, attribute in flattened.items():
            regs = _get_method_regs(attribute)
            if regs:
                for reg in regs:
                    self.method_regs.add((name, reg))

        self.instance_methods = {}
        self.instances = {}
Exemple #2
0
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)
Exemple #3
0
def test_mainloop():
    counter = Counter()

    def run():
        counter.tick()

    reactor = AttrDict(run=run)
    event = AttrDict(reactor=reactor)

    main.mainloop(event)

    assert counter.incremented(1)
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
    def fire(self, *contexts, **keywords):
        try:
            if not self.mainloop:
                return
        except AttributeError:
            raise AlreadyRunningError()

        from crow2.util import AttrDict
        event = AttrDict()
        for context in contexts + (keywords,):
            event.update(context)
        mainloop = self.mainloop # if a plugin tries to start the mainloop again, it should fail
        del self.mainloop
        mainloop(event)
        self.mainloop = mainloop
Exemple #7
0
    def test_errors(self, capsys):
        class Clazz(object):
            def __init__(self, event):
                pass
            def delete(self):
                should_never_run()

        reg = _HandlerClass(Clazz)

        event = AttrDict()
        instance2 = Clazz(event)

        with pytest.raises(exceptions.NotRegisteredError):
            reg.free_instance(instance2)

        out, err = capsys.readouterr()

        reg(event)

        out, err = capsys.readouterr()
        assert "WARNING" in out or "WARNING" in err

        class OtherClazz(object):
            def __init__(self, event):
                should_never_run()
            __init__._crow2_instancehookregs = [DummyAttributeRegistration()]
        with pytest.raises(exceptions.NotInstantiableError):
            otherreg = _HandlerClass(OtherClazz)
Exemple #8
0
def test_lazy_missing():
    lazycall = LazyCall(("doesnt", "exist", "attribute"), ("argument",), {"key": "value"}, False)

    exist = AttrDict()
    doesnt = AttrDict(exist=exist)
    obj = AttrDict(doesnt=doesnt)
    try:
        lazycall.resolve(obj)
    except AttributeError as e:
        assert "doesnt.exist" in e.message
        assert "attribute" in e.message
        assert "key" in e.message
        assert "value" in e.message
        assert "argument" in e.message
        assert repr(obj) in e.message
    else:
        should_never_run()
Exemple #9
0
 def _make_eventobj(self, *dicts, **keywords):
     """
     Prepare the objects which will be passed into handlers
     """
     event = AttrDict()
     for context_dict in dicts:
         event.update(context_dict)
     event.update(keywords)
     event.update({"calling_hook": self})
     return event
Exemple #10
0
def to_attrdict(obj, recurse=True):
    # todo: this should probably be interface-based since it does type checking
    if isinstance(obj, dict):
        obj = AttrDict(obj)
        if recurse:
            for key in obj:
                res = to_attrdict(obj[key])
                obj[key] = res
    return obj
Exemple #11
0
def test_server_connect(monkeypatch):
    connections = []

    def fakeconnecttcp(address, port, factory):
        connections.append((address, port, factory))

    reactor = AttrDict(connectTCP=fakeconnecttcp)

    options = AttrDict({
        "server": object(),
        "port": object(),
        "nick": object(),
        "user": object(),
        "realname": object(),
        "channels": object(),
        "newline": object()
    })

    fakeconnectionfactories = []

    class FakeConnectionFactory(object):
        def __init__(self, serverobj):
            self.serverobj = serverobj
            fakeconnectionfactories.append(self)

    monkeypatch.setattr(main, "ConnectionFactory", FakeConnectionFactory)

    server = main.Server(reactor, "connection_name", options)
    assert server.address is options.server
    assert server.port is options.port
    assert server.nick is options.nick
    assert server.user is options.user
    assert server.realname is options.realname
    assert server.channels is options.channels
    assert server.delimiter is options.newline

    assert server.factory.serverobj is server  # yay reference loop!
    assert not len(connections)

    server.connect()

    assert connections == [(options.server, options.port,
                            fakeconnectionfactories[0])]
Exemple #12
0
def test_init_unconfigured(monkeypatch):
    monkeypatch.setattr(main, "log",
                        AttrDict(startLogging=lambda out, setStdout: None))

    class FakeServer(object):
        def __init__(self, reactor, name, options):
            should_never_run()

        def connect(self):
            should_never_run()

    monkeypatch.setattr(main, "Server", FakeServer)

    reactor_sentinel = object()

    event = AttrDict(config=AttrDict())
    main.defaultconfig(event)

    with pytest.raises(main.UnconfiguredError):
        main.init(event)
Exemple #13
0
def test_defaultconfig(monkeypatch):
    event = AttrDict(config=AttrDict())

    assert event == {"config": {}}

    main.defaultconfig(event)

    assert event == {
        "config": {
            "connections": {
                "example": {
                    "server": "irc.example.net",
                    "nick": "example",
                    "user": "******",
                    "realname": "example",
                    "channels": ["#changeme"]
                }
            }
        }
    }
Exemple #14
0
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"]
Exemple #15
0
def test_exception_in_call():
    lazycall = LazyCall(("herp", "derp"), ("positional_arg",), {"keyword": "kwarg"}, False)

    class SentinelException(Exception):
        pass

    def target(positional_arg, keyword):
        assert positional_arg == "positional_arg"
        assert keyword == "kwarg"
        raise SentinelException()

    herp = AttrDict(derp=target)
    obj = AttrDict(herp=herp)
    try:
        lazycall.resolve(obj)
    except exceptions.ExceptionInCallError as e:
        assert "SentinelException" in e.message
        assert "target" in e.message
        assert "herp.derp" in e.message
    else:
        should_never_run()
Exemple #16
0
 def _make_eventobj(self, *dicts, **keywords):
     """
     Prepare the objects which will be passed into handlers
     """
     event = AttrDict()
     for context_dict in dicts:
         event.update(context_dict)
     event.update(keywords)
     event.update({"calling_hook": self})
     return event
Exemple #17
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)
Exemple #18
0
def test_class_reg():
    registrations = []
    def register(handler, *args, **keywords):
        registrations.append((handler, args, keywords))

    hook = AttrDict(register=register)
    @handlerclass(hook)
    @handlerclass(hook, "derp")
    @handlerclass(hook, derp=True)
    class Target(object):
        pass

    assert registrations == [(Target._crow2_classreg, (), {"derp": True}),
                             (Target._crow2_classreg, ("derp",), {}),
                             (Target._crow2_classreg, (), {})]
Exemple #19
0
def test_deferred_adaptation():
    hook1 = Hook()

    @hook1
    @yielding
    def handler(event):
        event.handler_called = True
        deferred_result = yield event.deferred
        deferred_result.handler_called = True

    event = hook1.fire(deferred=Deferred())

    newevent = AttrDict()
    event.deferred.callback(newevent)
    assert newevent.handler_called
Exemple #20
0
def test_instancehandler_missinghook():
    class MissingHook(object):
        @instancehandler.doesnt.exist
        def a_method(self, event):
            should_never_run()

    target = MissingHook()
    a_method = target.a_method.im_func
    regs = a_method._crow2_instancehookregs
    reg = regs[0]

    event = AttrDict()

    with pytest.raises(AttributeError):
        reg.add_bound_method(target.a_method, event)
Exemple #21
0
def config(event):
    print "loading config"
    config_type = "json"
    filename = "config." + config_type
    config = AttrDict()

    load_event = loadhook.fire(event,
                               config_type=config_type,
                               filename=filename,
                               config=config)
    config = to_attrdict(load_event.config)

    write_event = writehook.fire(event,
                                 config_type=config_type,
                                 filename=filename,
                                 config=config)
    config = to_attrdict(write_event.config)

    event.main.config = config
    event.config = config
Exemple #22
0
def test_instancehandler_badarguments():
    class BadArguments(object):
        @instancehandler.func(doesnt="take", arguments=True)
        def a_method(self, event):
            should_never_run()

    target = BadArguments()
    a_method = target.a_method.im_func
    regs = a_method._crow2_instancehookregs
    reg = regs[0]

    def func():
        """
        A function that takes no arguments
        """
        should_never_run()

    event = AttrDict(func=func)

    with pytest.raises(exceptions.ExceptionInCallError):
        reg.add_bound_method(target.a_method, event)
Exemple #23
0
    def test_simple(self):
        class Clazz(object):
            def __init__(self, event):
                pass
            def herp(self):
                should_never_run()
            herp._crow2_instancehookregs = [DummyAttributeRegistration()]
            def derp(self):
                self.delete()
        herp = vars(Clazz)["herp"]
        dummy = herp._crow2_instancehookregs[0]

        reg = _HandlerClass(Clazz)
        assert len(dummy.registereds) == 0
        assert len(dummy.bounds) == 0

        event = AttrDict()
        instance = reg(event)
        assert dummy.registereds == [(Clazz, "herp")]
        assert dummy.bounds == [(instance.herp, event)]

        instance.derp()
        assert dummy.unbounds == [instance.herp]
        assert dummy.unregistereds == [(Clazz, "herp")]
Exemple #24
0
def test_server_defaults(monkeypatch):

    options = AttrDict({
        "server": object(),
        "nick": object(),
        "channels": object()
    })

    reactor_sentinel = object()
    monkeypatch.setattr(main, "ConnectionFactory", lambda server: None)

    server = main.Server(reactor_sentinel, "connection_name", options)
    assert server.name == "connection_name"
    assert server.port == 6667

    assert server.address is options.server
    assert server.nick is options.nick
    assert server.channels is options.channels

    assert server.user is options.nick
    assert server.realname is options.nick
    assert server.delimiter == "\r\n"

    assert server.reactor is reactor_sentinel
Exemple #25
0
def test_lazy_decorate_missing():
    lazycall = LazyCall((), (), {}, True, True)

    with pytest.raises(exceptions.DecoratedFuncMissingError):
        lazycall.resolve(AttrDict(), None)
Exemple #26
0
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)
Exemple #27
0
def test_loadreactor(monkeypatch):
    from twisted.internet import reactor

    event = AttrDict()
    main.loadreactor(event)
    assert event == {"reactor": reactor}