Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an 'args' attribute to SignalBlocker. #115

Merged
merged 2 commits into from
Dec 16, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/signals.rst
Expand Up @@ -43,6 +43,22 @@ reached before the signal is triggered:
assert_application_results(app)


**Getting arguments of the emitted signal**

.. versionadded:: 1.10

The arguments emitted with the signal are available as the ``args`` attribute
of the blocker:


.. code-block:: python

def test_signal(qtbot):
...
with qtbot.waitSignal(app.got_cmd) as blocker:
app.listen()
assert blocker.args == ['test']


**waitSignals**

Expand Down
11 changes: 10 additions & 1 deletion pytestqt/wait_signal.py
Expand Up @@ -86,13 +86,21 @@ class SignalBlocker(_AbstractSignalBlocker):
:ivar bool raising:
If :class:`SignalTimeoutError` should be raised if a timeout occurred.

:ivar list args:
The arguments which were emitted by the signal, or None if the signal
wasn't emitted at all.

.. versionadded:: 1.10
The *args* attribute.

.. automethod:: wait
.. automethod:: connect
"""

def __init__(self, timeout=1000, raising=False):
super(SignalBlocker, self).__init__(timeout, raising=raising)
self._signals = []
self.args = None

def connect(self, signal):
"""
Expand All @@ -107,11 +115,12 @@ def connect(self, signal):
signal.connect(self._quit_loop_by_signal)
self._signals.append(signal)

def _quit_loop_by_signal(self):
def _quit_loop_by_signal(self, *args):
"""
quits the event loop and marks that we finished because of a signal.
"""
self.signal_triggered = True
self.args = list(args)
self._loop.quit()
self._cleanup()

Expand Down
38 changes: 38 additions & 0 deletions tests/test_wait_signal.py
Expand Up @@ -168,6 +168,8 @@ def signaller(timer):
class Signaller(QtCore.QObject):
signal = Signal()
signal_2 = Signal()
signal_args = Signal(str, int)
signal_args_2 = Signal(str, int)

assert timer

Expand Down Expand Up @@ -274,3 +276,39 @@ class Obj(QtCore.QObject):

assert sip.isdeleted(obj)


class TestArgs:

"""Try to get the signal arguments from the signal blocker."""

def test_simple(self, qtbot, signaller):
"""The blocker should store the signal args in an 'args' attribute."""
with qtbot.waitSignal(signaller.signal_args) as blocker:
signaller.signal_args.emit('test', 123)
assert blocker.args == ['test', 123]

def test_timeout(self, qtbot):
"""If there's a timeout, the args attribute is None."""
with qtbot.waitSignal(timeout=100) as blocker:
pass
assert blocker.args is None

def test_without_args(self, qtbot, signaller):
"""If a signal has no args, the args attribute is an empty list."""
with qtbot.waitSignal(signaller.signal) as blocker:
signaller.signal.emit()
assert blocker.args == []

def test_multi(self, qtbot, signaller):
"""A MultiSignalBlocker doesn't have an args attribute."""
with qtbot.waitSignals([signaller.signal]) as blocker:
signaller.signal.emit()
with pytest.raises(AttributeError):
blocker.args

def test_connected_signal(self, qtbot, signaller):
"""A second signal connected via .connect also works."""
with qtbot.waitSignal(signaller.signal_args) as blocker:
blocker.connect(signaller.signal_args_2)
signaller.signal_args_2.emit('foo', 2342)
assert blocker.args == ['foo', 2342]