diff --git a/docs/signals.rst b/docs/signals.rst index 686e1671..0b035fb7 100644 --- a/docs/signals.rst +++ b/docs/signals.rst @@ -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** diff --git a/pytestqt/wait_signal.py b/pytestqt/wait_signal.py index c32a76c3..8d70f6e7 100644 --- a/pytestqt/wait_signal.py +++ b/pytestqt/wait_signal.py @@ -86,6 +86,13 @@ 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 """ @@ -93,6 +100,7 @@ class SignalBlocker(_AbstractSignalBlocker): def __init__(self, timeout=1000, raising=False): super(SignalBlocker, self).__init__(timeout, raising=raising) self._signals = [] + self.args = None def connect(self, signal): """ @@ -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() diff --git a/tests/test_wait_signal.py b/tests/test_wait_signal.py index e995cf3b..c867e6fe 100644 --- a/tests/test_wait_signal.py +++ b/tests/test_wait_signal.py @@ -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 @@ -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]