blob: a09bf00e2da57b8866a67387856f967df1d3d84d [file] [log] [blame] [edit]
# -*- 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()