Skip to content

Commit e5f4467

Browse files
authored
Merge pull request #149 from MShekow/master
Added order and check_params_cbs parameter documentation (also to changelog)
2 parents eabecd1 + 07c0efe commit e5f4467

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ New Features
3939
is met or a timeout is reached. Useful for testing asynchronous features
4040
(like in X window environments for example).
4141

42-
* ``waitSignal`` and ``waitSignals`` can receive an optional callback that can
43-
evaluate if the arguments of emitted signals should resume execution or not.
42+
* ``waitSignal`` and ``waitSignals`` can receive an optional callback (or list of callbacks)
43+
that can evaluate if the arguments of emitted signals should resume execution or not.
44+
Additionally ``waitSignals`` has a new ``order`` parameter that allows to expect signals
45+
and their arguments in a strict, semi-strict or no specific order.
4446
Thanks `@MShekow`_ for the PR (`#141`_).
4547

4648
* Now which Qt binding ``pytest-qt`` will use can be configured by the ``qt_api`` config option.

docs/signals.rst

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,31 @@ value of the ``raising`` parameter of the ``qtbot.waitSignal`` and
6868
Calls which explicitly pass the ``raising`` parameter are not affected.
6969

7070

71+
check_params_cb parameter
72+
-------------------------
73+
74+
.. versionadded:: 2.0
75+
76+
If the signal has parameters you want to compare with expected values, you can pass
77+
``check_params_cb=some_callable`` that compares the provided signal parameters to some expected parameters.
78+
It has to match the signature of ``signal`` (just like a slot function would) and return ``True`` if
79+
parameters match, ``False`` otherwise.
80+
81+
.. code-block:: python
82+
83+
def test_status_100(status):
84+
"""Return true if status has reached 100%."""
85+
return status == 100
86+
87+
def test_status_complete(qtbot):
88+
app = Application()
89+
90+
# the following raises if the worker's status signal (which has an int parameter) wasn't raised
91+
# with value=100 within the default timeout
92+
with qtbot.waitSignal(app.worker.status, raising=True, check_params_cb=test_status_100) as blocker:
93+
app.worker.start()
94+
95+
7196
Getting arguments of the emitted signal
7297
---------------------------------------
7398

@@ -110,6 +135,65 @@ the ``raising`` parameter::
110135
# signal or a qtbot.SignalTimeoutError will be raised
111136
assert_application_results(app)
112137

138+
check_params_cbs parameter
139+
^^^^^^^^^^^^^^^^^^^^^^^^^^
140+
141+
.. versionadded:: 2.0
142+
143+
Corresponding to the ``check_params_cb`` parameter of ``waitSignal`` you can use the ``check_params_cbs``
144+
parameter to check whether one or more of the provided signals are emitted with expected parameters.
145+
Provide a list of callables, each matching the signature of the corresponding signal
146+
in ``signals`` (just like a slot function would). Like for ``waitSignal``, each callable has to
147+
return ``True`` if parameters match, ``False`` otherwise.
148+
Instead of a specific callable, ``None`` can be provided, to disable parameter checking for the
149+
corresponding signal.
150+
If the number of callbacks doesn't match the number of signals ``ValueError`` will be raised.
151+
152+
The following example shows that the ``app.worker.status`` signal has to be emitted with values 50 and
153+
100, and the ``app.worker.finished`` signal has to be emitted too (for which no signal parameter
154+
evaluation takes place).
155+
156+
157+
.. code-block:: python
158+
159+
def test_status_100(status):
160+
"""Return true if status has reached 100%."""
161+
return status == 100
162+
163+
def test_status_50(status):
164+
"""Return true if status has reached 50%."""
165+
return status == 50
166+
167+
def test_status_complete(qtbot):
168+
app = Application()
169+
170+
signals = [app.worker.status, app.worker.status, app.worker.finished]
171+
callbacks = [test_status_50, test_status_100, None]
172+
with qtbot.waitSignals(signals, raising=True, check_params_cbs=callbacks) as blocker:
173+
app.worker.start()
174+
175+
176+
order parameter
177+
^^^^^^^^^^^^^^^^^^^^^
178+
179+
.. versionadded:: 2.0
180+
181+
By default a test using ``qtbot.waitSignals`` completes successfully if *all* signals in ``signals``
182+
are emitted, irrespective of their exact order. The ``order`` parameter can be set to ``"strict"``
183+
to enforce strict signal order.
184+
Exemplary, this means that ``blocker.signal_triggered`` will be ``False`` if ``waitSignals`` expects
185+
the signals ``[a, b]`` but the sender emitted signals ``[a, a, b]``.
186+
187+
.. note::
188+
189+
The tested component can still emit signals unknown to the blocker. E.g.
190+
``blocker.waitSignals([a, b], raising=True, order="strict")`` won't raise if the signal-sender
191+
emits signals ``[a, c, b]``, as ``c`` is not part of the observed signals.
192+
193+
A third option is to set ``order="simple"`` which is like "strict", but signals may be emitted
194+
in-between the provided ones, e.g. if the expected signals are ``[a, b, c]`` and the sender
195+
actually emits ``[a, a, b, a, c]``, the test completes successfully (it would fail with ``order="strict"``).
196+
113197
Making sure a given signal is not emitted
114198
-----------------------------------------
115199

0 commit comments

Comments
 (0)