Skip to content

Commit 0f11407

Browse files
committed
Add a raising parameter to waitSignal.
1 parent e66e58f commit 0f11407

File tree

2 files changed

+68
-21
lines changed

2 files changed

+68
-21
lines changed

pytestqt/_tests/test_wait_signal.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,53 @@ def test_signal_blocker_exception(qtbot):
1818
qtbot.waitSignal(None, None).wait()
1919

2020

21-
def explicit_wait(qtbot, signal, timeout):
21+
def explicit_wait(qtbot, signal, timeout, raising, raises):
2222
"""
2323
Explicit wait for the signal using blocker API.
2424
"""
25-
blocker = qtbot.waitSignal(signal, timeout)
25+
blocker = qtbot.waitSignal(signal, timeout, raising=raising)
2626
assert not blocker.signal_triggered
27-
blocker.wait()
27+
if raises:
28+
with pytest.raises(qtbot.SignalTimeout):
29+
blocker.wait()
30+
else:
31+
blocker.wait()
2832
return blocker
2933

3034

31-
def context_manager_wait(qtbot, signal, timeout):
35+
def context_manager_wait(qtbot, signal, timeout, raising, raises):
3236
"""
3337
Waiting for signal using context manager API.
3438
"""
35-
with qtbot.waitSignal(signal, timeout) as blocker:
36-
pass
39+
if raises:
40+
with pytest.raises(qtbot.SignalTimeout):
41+
with qtbot.waitSignal(signal, timeout, raising=raising) as blocker:
42+
pass
43+
else:
44+
with qtbot.waitSignal(signal, timeout, raising=raising) as blocker:
45+
pass
3746
return blocker
3847

3948

4049
@pytest.mark.parametrize(
41-
('wait_function', 'emit_delay', 'timeout', 'expected_signal_triggered'),
50+
('wait_function', 'emit_delay', 'timeout', 'expected_signal_triggered',
51+
'raising'),
4252
[
43-
(explicit_wait, 500, 2000, True),
44-
(explicit_wait, 500, None, True),
45-
(context_manager_wait, 500, 2000, True),
46-
(context_manager_wait, 500, None, True),
47-
(explicit_wait, 2000, 500, False),
48-
(context_manager_wait, 2000, 500, False),
53+
(explicit_wait, 500, 2000, True, False),
54+
(explicit_wait, 500, None, True, False),
55+
(context_manager_wait, 500, 2000, True, False),
56+
(context_manager_wait, 500, None, True, False),
57+
(explicit_wait, 2000, 500, False, False),
58+
(context_manager_wait, 2000, 500, False, False),
59+
60+
(explicit_wait, 2000, 500, False, True),
61+
(context_manager_wait, 2000, 500, False, True),
62+
(explicit_wait, 2000, 500, False, True),
63+
(context_manager_wait, 2000, 500, False, True),
4964
] * 2 # Running all tests twice to catch a QTimer segfault, see #42/#43.
5065
)
5166
def test_signal_triggered(qtbot, wait_function, emit_delay, timeout,
52-
expected_signal_triggered):
67+
expected_signal_triggered, raising):
5368
"""
5469
Testing for a signal in different conditions, ensuring we are obtaining
5570
the expected results.
@@ -62,7 +77,9 @@ def test_signal_triggered(qtbot, wait_function, emit_delay, timeout,
6277

6378
# block signal until either signal is emitted or timeout is reached
6479
start_time = time.time()
65-
blocker = wait_function(qtbot, signaller.signal, timeout)
80+
raises = raising and not expected_signal_triggered
81+
blocker = wait_function(qtbot, signaller.signal, timeout, raising=raising,
82+
raises=raises)
6683

6784
# Check that event loop exited.
6885
assert not blocker._loop.isRunning()

pytestqt/plugin.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,15 @@ class QtBot(object):
161161
162162
"""
163163

164+
class SignalTimeout(Exception):
165+
"""
166+
.. versionadded:: 1.4
167+
168+
The exception thrown by :meth:`QtBot.waitSignal` if the *raising*
169+
parameter has been given and there was a timeout.
170+
"""
171+
pass
172+
164173
def __init__(self):
165174
self._widgets = [] # list of weakref to QWidget instances
166175

@@ -233,10 +242,10 @@ def stopForInteraction(self):
233242

234243
stop = stopForInteraction
235244

236-
def waitSignal(self, signal=None, timeout=1000):
245+
def waitSignal(self, signal=None, timeout=1000, raising=False):
237246
"""
238247
.. versionadded:: 1.2
239-
248+
240249
Stops current test until a signal is triggered.
241250
242251
Used to stop the control flow of a test until a signal is emitted, or
@@ -255,18 +264,24 @@ def waitSignal(self, signal=None, timeout=1000):
255264
long_function_that_calls_signal()
256265
blocker.wait()
257266
267+
.. versionadded:: 1.4
268+
The *raising* parameter.
269+
258270
:param Signal signal:
259271
A signal to wait for. Set to ``None`` to just use timeout.
260272
:param int timeout:
261273
How many milliseconds to wait before resuming control flow.
274+
:param bool raising:
275+
If :class:`QtBot.TimeoutError` should be raised if a timeout
276+
occured.
262277
:returns:
263278
``SignalBlocker`` object. Call ``SignalBlocker.wait()`` to wait.
264279
265280
.. note::
266281
Cannot have both ``signals`` and ``timeout`` equal ``None``, or
267282
else you will block indefinitely. We throw an error if this occurs.
268283
"""
269-
blocker = SignalBlocker(timeout=timeout)
284+
blocker = SignalBlocker(timeout=timeout, raising=raising)
270285
if signal is not None:
271286
blocker.connect(signal)
272287
return blocker
@@ -288,13 +303,17 @@ class SignalBlocker(object):
288303
:ivar bool signal_triggered: set to ``True`` if a signal was triggered, or
289304
``False`` if timeout was reached instead. Until :meth:`wait` is called,
290305
this is set to ``None``.
306+
307+
:ivar bool raising:
308+
If :class:`QtBot.TimeoutError` should be raised if a timeout occured.
291309
"""
292310

293-
def __init__(self, timeout=1000):
311+
def __init__(self, timeout=1000, raising=False):
294312
self._loop = QtCore.QEventLoop()
295313
self._signals = []
296314
self.timeout = timeout
297315
self.signal_triggered = False
316+
self.raising = raising
298317

299318
def wait(self):
300319
"""
@@ -308,7 +327,7 @@ def wait(self):
308327
if self.timeout is None and len(self._signals) == 0:
309328
raise ValueError("No signals or timeout specified.")
310329
if self.timeout is not None:
311-
QtCore.QTimer.singleShot(self.timeout, self._loop.quit)
330+
QtCore.QTimer.singleShot(self.timeout, self._quit_loop_by_timeout)
312331
self._loop.exec_()
313332

314333
def connect(self, signal):
@@ -328,6 +347,17 @@ def _quit_loop_by_signal(self):
328347
self.signal_triggered = True
329348
self._loop.quit()
330349

350+
def _quit_loop_by_timeout(self):
351+
"""
352+
quits the event loop and marks that we finished because of a timeout.
353+
"""
354+
assert not self.signal_triggered
355+
self._loop.quit()
356+
if self.raising:
357+
raise QtBot.SignalTimeout("Didn't get signal after %sms." %
358+
self.timeout)
359+
360+
331361
def __enter__(self):
332362
return self
333363

@@ -435,4 +465,4 @@ def pytest_configure(config):
435465

436466

437467
def pytest_report_header():
438-
return ['qt-api: %s' % QT_API]
468+
return ['qt-api: %s' % QT_API]

0 commit comments

Comments
 (0)