示例#1
0
def test_method_handler_invoking_other():
    
    h = event.HasEvents()
    
    # This used not not work
    # with raises(RuntimeError):
    #     class Foo(event.HasEvents):
    #         
    #         @h.connect('x1')
    #         def handler(self, *events):
    #             self.was_invoked = True
    
    # But now it does!
    
    class Foo(event.HasEvents):
        
        @h.connect('x1')
        def handler(self, *events):
            self.was_invoked = True
    
    foo = Foo()
    
    h.emit('x1')
    event.loop.iter()
    assert foo.was_invoked
示例#2
0
def test_dispose3():
    # Test that connecting a "volatile" object to a static object works well
    # w.r.t. cleanup.
    
    relay = event.HasEvents()
    
    class Foo:
        def bar(self, *events):
            pass
    
    foo = Foo()
    handler = relay.connect(foo.bar, 'xx')
    
    handler_ref = weakref.ref(handler)
    foo_ref = weakref.ref(foo)
    
    del foo
    del handler
    
    gc.collect()
    
    assert foo_ref() is None
    assert handler_ref() is not None
    
    relay.emit('xx')
    event.loop.iter()
    gc.collect()
    
    assert foo_ref() is None
    assert handler_ref() is None
示例#3
0
def test_connecting():
    
    # We've done all the normal connections. We test mosly fails here
    
    h = event.HasEvents()
    
    with raises(RuntimeError):  # connect() needs args
        @event.connect
        def foo(*events):
            pass
    with raises(RuntimeError):
        @h.connect
        def foo(*events):
            pass
    
    with raises(ValueError):  # connect() needs strings
        @event.connect(3)
        def foo(*events):
            pass
    with raises(ValueError):
        @h.connect(3)
        def foo(*events):
            pass
    
    with raises(TypeError):  # connect() needs callable
        event.connect('x')(3)
    with raises(TypeError):  # connect() needs callable
        h.connect('x')(3)
    
    with raises(RuntimeError):  # cannot connect
        h.xx = None
        @h.connect('xx.foobar')
        def foo(*events):
            pass
示例#4
0
def test_emit():

    h = event.HasEvents()
    events = []

    @h.connect('foo', 'bar')
    def handler(*evts):
        events.extend(evts)

    h.emit('foo', {})
    h.emit('bar', {'x': 1, 'y': 2})
    h.emit('spam', {})  # not registered
    handler.handle_now()

    assert len(events) == 2
    for ev in events:
        assert isinstance(ev, dict)
        assert ev.source is h
    assert len(events[0]) == 2
    assert len(events[1]) == 4
    assert events[0].type == 'foo'
    assert events[1].type == 'bar'
    assert events[1].x == 1
    assert events[1]['y'] == 2

    # Fail
    with raises(ValueError):
        h.emit('foo:a', {})
    with raises(TypeError):
        h.emit('foo', 4)
    with raises(TypeError):
        h.emit('foo', 'bla')
示例#5
0
def test_func_handler_invoking():
    called = []
    
    h = event.HasEvents()
    
    @h.connect('x1', 'x2')
    def handler(*events):
        called.append(len(events))
    
    handler()
    handler.handle_now()
    
    h.emit('x1', {})
    handler.handle_now()
    
    h.emit('x1', {})
    h.emit('x1', {})
    handler.handle_now()
    
    h.emit('x1', {})
    h.emit('x2', {})
    handler.handle_now()
    
    handler()
    handler.handle_now()
    
    assert called == [0, 1, 2, 2, 0]
示例#6
0
def test_basics():

    # Simplest
    h = event.HasEvents()
    assert not h.__handlers__
    assert not h.__emitters__

    # Test __emitters__
    class Foo(event.HasEvents):
        @event.prop
        def a_prop(self, v=0):
            return v

        @event.readonly
        def a_readonly(self, v=0):
            return v

        @event.emitter
        def a_emitter(self, v):
            return {}

        @event.emitter  # deliberately define it twice
        def a_emitter(self, v):
            return {'x': 1}

    #
    foo = Foo()
    assert not foo.__handlers__
    assert len(foo.__emitters__) == 1
    assert len(foo.__properties__) == 2
    assert 'a_prop' in foo.__properties__
    assert 'a_readonly' in foo.__properties__
    assert 'a_emitter' in foo.__emitters__
    #
    assert foo.get_event_types() == ['a_emitter', 'a_prop', 'a_readonly']
    assert foo.get_event_handlers('a_prop') == []

    # Test __handlers__
    class Bar(event.HasEvents):
        @event.connect('x')
        def spam(self, *events):
            pass

        @event.connect('eggs')
        def on_eggs(self, *events):
            pass

    #
    foo = Bar()
    assert not foo.__emitters__
    assert len(foo.__handlers__) == 2
    #assert len(foo.__handlers__) == 1
    assert 'spam' in foo.__handlers__
    assert 'on_eggs' in foo.__handlers__
    #
    assert foo.get_event_types() == ['eggs', 'x']
    assert foo.get_event_handlers('x') == [foo.spam]
示例#7
0
def test_method_handler_invoking_other():

    h = event.HasEvents()

    with raises(RuntimeError):

        class Foo(event.HasEvents):
            @h.connect('x1')
            def handler(self, *events):
                self.was_invoked = True
示例#8
0
def test_registering_handlers():
    h = event.HasEvents()

    @h.connect('foo')
    def handler1(*evts):
        events.extend(evts)

    @h.connect('foo')
    def handler2(*evts):
        events.extend(evts)

    @h.connect('foo')
    def handler3(*evts):
        events.extend(evts)

    handler1.dispose()
    handler2.dispose()
    handler3.dispose()

    # Checks before we start
    assert h.get_event_types() == ['foo']
    assert h.get_event_handlers('foo') == []

    # Test adding handlers
    h._register_handler('foo', handler1)
    h._register_handler('foo:a', handler2)
    h._register_handler('foo:z', handler3)
    assert h.get_event_handlers('foo') == [handler2, handler1, handler3]

    # Unregestering one handler
    h.disconnect('foo', handler2)
    assert h.get_event_handlers('foo') == [handler1, handler3]

    # Reset
    h._register_handler('foo:a', handler2)
    assert h.get_event_handlers('foo') == [handler2, handler1, handler3]

    # Unregestering one handler + invalid label -> no unregister
    h.disconnect('foo:xx', handler2)
    assert h.get_event_handlers('foo') == [handler2, handler1, handler3]

    # Reset
    assert h.get_event_handlers('foo') == [handler2, handler1, handler3]

    # Unregestering one handler by label
    h.disconnect('foo:a')
    assert h.get_event_handlers('foo') == [handler1, handler3]

    # Reset
    h._register_handler('foo:a', handler2)
    assert h.get_event_handlers('foo') == [handler2, handler1, handler3]

    # Unregestering by type
    h.disconnect('foo')
    assert h.get_event_handlers('foo') == []
示例#9
0
def test_connecting_and_getting_cached_event():
    
    h = event.HasEvents()
    h.emit('foo')
    
    res = []
    @h.connect('foo')
    def handle(ev):
        res.append(ev)
    
    event.loop.iter()
    event.loop.iter()
    assert len(res) == 1
示例#10
0
def test_dispose2():
    
    h = event.HasEvents()
    
    @h.connect('x1', 'x2')
    def handler(*events):
        pass
    
    handler_ref = weakref.ref(handler)
    del handler
    gc.collect()
    assert handler_ref() is not None  # h is holding on
    
    h.dispose()  # <=== only this line is different from test_dispose1()
    gc.collect()
    assert handler_ref() is None
示例#11
0
def test_dispose1():
    
    h = event.HasEvents()
    
    @h.connect('x1', 'x2')
    def handler(*events):
        pass
    
    handler_ref = weakref.ref(handler)
    del handler
    gc.collect()
    assert handler_ref() is not None  # h is holding on
    
    handler_ref().dispose()
    gc.collect()
    assert handler_ref() is None
def test_exceptions():
    h = event.HasEvents()

    @h.connect('foo')
    def handle_foo(*events):
        1 / 0

    h.emit('foo', {})

    sys.last_traceback = None
    assert sys.last_traceback is None

    # No exception should be thrown here
    event.loop.iter()
    event.loop.iter()

    # But we should have prepared for PM debugging
    assert sys.last_traceback

    # Its different for a direct call
    with raises(ZeroDivisionError):
        handle_foo()
示例#13
0
 def __init__(self):
     super().__init__()
     self.bar = event.HasEvents()
     self.bars = [self.bar]