| # -*- coding: utf-8 -*- |
| from collections import OrderedDict |
| |
| from mock import Mock |
| from pytest import raises |
| |
| from pyee import EventEmitter |
| |
| |
| class PyeeTestException(Exception): |
| pass |
| |
| |
| def test_emit_sync(): |
| """Basic synchronous emission works""" |
| |
| call_me = Mock() |
| ee = EventEmitter() |
| |
| @ee.on("event") |
| def event_handler(data, **kwargs): |
| call_me() |
| assert data == "emitter is emitted!" |
| |
| assert ee.event_names() == {"event"} |
| |
| # Making sure data is passed propers |
| ee.emit("event", "emitter is emitted!", error=False) |
| |
| call_me.assert_called_once() |
| |
| |
| def test_emit_error(): |
| """Errors raise with no event handler, otherwise emit on handler""" |
| |
| call_me = Mock() |
| ee = EventEmitter() |
| |
| test_exception = PyeeTestException("lololol") |
| |
| with raises(PyeeTestException): |
| ee.emit("error", test_exception) |
| |
| @ee.on("error") |
| def on_error(exc): |
| call_me() |
| |
| assert ee.event_names() == {"error"} |
| |
| # No longer raises and error instead return True indicating handled |
| assert ee.emit("error", test_exception) is True |
| call_me.assert_called_once() |
| |
| |
| def test_emit_return(): |
| """Emit returns True when handlers are registered on an event, and false |
| otherwise. |
| """ |
| |
| call_me = Mock() |
| ee = EventEmitter() |
| |
| assert ee.event_names() == set() |
| |
| # make sure emitting without a callback returns False |
| assert not ee.emit("data") |
| |
| # add a callback |
| ee.on("data")(call_me) |
| |
| # should return True now |
| assert ee.emit("data") |
| |
| |
| def test_new_listener_event(): |
| """The 'new_listener' event fires whenever a new listener is added.""" |
| |
| call_me = Mock() |
| ee = EventEmitter() |
| |
| ee.on("new_listener", call_me) |
| |
| # Should fire new_listener event |
| @ee.on("event") |
| def event_handler(data): |
| pass |
| |
| assert ee.event_names() == {"new_listener", "event"} |
| |
| call_me.assert_called_once_with("event", event_handler) |
| |
| |
| def test_listener_removal(): |
| """Removing listeners removes the correct listener from an event.""" |
| |
| ee = EventEmitter() |
| |
| # Some functions to pass to the EE |
| def first(): |
| return 1 |
| |
| ee.on("event", first) |
| |
| @ee.on("event") |
| def second(): |
| return 2 |
| |
| @ee.on("event") |
| def third(): |
| return 3 |
| |
| def fourth(): |
| return 4 |
| |
| ee.on("event", fourth) |
| |
| assert ee.event_names() == {"event"} |
| |
| assert ee._events["event"] == OrderedDict( |
| [(first, first), (second, second), (third, third), (fourth, fourth)] |
| ) |
| |
| ee.remove_listener("event", second) |
| |
| assert ee._events["event"] == OrderedDict( |
| [(first, first), (third, third), (fourth, fourth)] |
| ) |
| |
| ee.remove_listener("event", first) |
| assert ee._events["event"] == OrderedDict([(third, third), (fourth, fourth)]) |
| |
| ee.remove_all_listeners("event") |
| assert "event" not in ee._events["event"] |
| |
| |
| def test_listener_removal_on_emit(): |
| """Test that a listener removed during an emit is called inside the current |
| emit cycle. |
| """ |
| |
| call_me = Mock() |
| ee = EventEmitter() |
| |
| def should_remove(): |
| ee.remove_listener("remove", call_me) |
| |
| ee.on("remove", should_remove) |
| ee.on("remove", call_me) |
| |
| assert ee.event_names() == {"remove"} |
| |
| ee.emit("remove") |
| |
| call_me.assert_called_once() |
| |
| call_me.reset_mock() |
| |
| # Also test with the listeners added in the opposite order |
| ee = EventEmitter() |
| ee.on("remove", call_me) |
| ee.on("remove", should_remove) |
| |
| assert ee.event_names() == {"remove"} |
| |
| ee.emit("remove") |
| |
| call_me.assert_called_once() |
| |
| |
| def test_once(): |
| """Test that `once()` method works propers.""" |
| |
| # very similar to "test_emit" but also makes sure that the event |
| # gets removed afterwards |
| |
| call_me = Mock() |
| ee = EventEmitter() |
| |
| def once_handler(data): |
| assert data == "emitter is emitted!" |
| call_me() |
| |
| # Tests to make sure that after event is emitted that it's gone. |
| ee.once("event", once_handler) |
| |
| assert ee.event_names() == {"event"} |
| |
| ee.emit("event", "emitter is emitted!") |
| |
| call_me.assert_called_once() |
| |
| assert ee.event_names() == set() |
| |
| assert "event" not in ee._events |
| |
| |
| def test_once_removal(): |
| """Removal of once functions works""" |
| |
| ee = EventEmitter() |
| |
| def once_handler(data): |
| pass |
| |
| handle = ee.once("event", once_handler) |
| |
| assert handle == once_handler |
| assert ee.event_names() == {"event"} |
| |
| ee.remove_listener("event", handle) |
| |
| assert "event" not in ee._events |
| assert ee.event_names() == set() |
| |
| |
| def test_listeners(): |
| """`listeners()` returns a copied list of listeners.""" |
| |
| call_me = Mock() |
| ee = EventEmitter() |
| |
| @ee.on("event") |
| def event_handler(): |
| pass |
| |
| @ee.once("event") |
| def once_handler(): |
| pass |
| |
| listeners = ee.listeners("event") |
| |
| assert listeners[0] == event_handler |
| assert listeners[1] == once_handler |
| |
| # listeners is a copy, you can't mutate the innards this way |
| listeners[0] = call_me |
| |
| ee.emit("event") |
| |
| call_me.assert_not_called() |
| |
| |
| def test_listeners_does_work_with_unknown_listeners(): |
| """`listeners()` should not throw.""" |
| ee = EventEmitter() |
| listeners = ee.listeners("event") |
| assert listeners == [] |
| |
| |
| def test_properties_preserved(): |
| """Test that the properties of decorated functions are preserved.""" |
| |
| call_me = Mock() |
| call_me_also = Mock() |
| ee = EventEmitter() |
| |
| @ee.on("always") |
| def always_event_handler(): |
| """An event handler.""" |
| call_me() |
| |
| @ee.once("once") |
| def once_event_handler(): |
| """Another event handler.""" |
| call_me_also() |
| |
| assert always_event_handler.__doc__ == "An event handler." |
| assert once_event_handler.__doc__ == "Another event handler." |
| |
| always_event_handler() |
| call_me.assert_called_once() |
| |
| once_event_handler() |
| call_me_also.assert_called_once() |
| |
| call_me_also.reset_mock() |
| |
| # Calling the event handler directly doesn't clear the handler |
| ee.emit("once") |
| call_me_also.assert_called_once() |