Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions src/pytestqt/qtbot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from collections.abc import Callable
from collections.abc import Callable, Sequence
import contextlib
from types import TracebackType
import weakref
Expand Down Expand Up @@ -505,15 +505,15 @@ def wait(self, ms: int) -> None:

@contextlib.contextmanager
def assertNotEmitted(
self, signal: SignalInstance, *, wait: int = 0
self, signal: SignalInstance | Sequence[SignalInstance], wait: int = 0
) -> Generator[None, None, None]:
"""
.. versionadded:: 1.11

Make sure the given ``signal`` doesn't get emitted.
Make sure the given ``signal``s don't get emitted.

:param wait:
How many milliseconds to wait to make sure the signal isn't emitted
How many milliseconds to wait to make sure the signals aren't emitted
asynchronously. By default, this method returns immediately and only
catches signals emitted inside the ``with``-block.

Expand All @@ -522,10 +522,21 @@ def assertNotEmitted(
.. note:: This method is also available as ``assert_not_emitted``
(pep-8 alias)
"""
spy = SignalEmittedSpy(signal)
with spy, self.waitSignal(signal, timeout=wait, raising=False):
yield
spy.assert_not_emitted()
signals = list(signal) if isinstance(signal, Sequence) else [signal]

with contextlib.ExitStack() as stack:
spies = [stack.enter_context(SignalEmittedSpy(sig)) for sig in signals]
with self.waitSignals(signals, timeout=wait, raising=False):
yield

if len(spies) == 1:
spies[0].assert_not_emitted()
else:
emittedSignals = [spy.signal for spy in spies if spy.emitted]
if emittedSignals:
raise SignalEmittedError(
f"Signals {emittedSignals!r} unexpectedly emitted"
)

def waitUntil(
self, callback: Callable[[], bool | None], *, timeout: int = 5000
Expand Down
1 change: 1 addition & 0 deletions src/pytestqt/wait_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ def slot(self, *args):

def __enter__(self):
self.signal.connect(self.slot)
return self

def __exit__(self, type, value, traceback):
self.signal.disconnect(self.slot)
Expand Down
32 changes: 21 additions & 11 deletions tests/test_wait_signal.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import functools
import fnmatch

import pytest
import sys
Expand Down Expand Up @@ -1262,31 +1261,42 @@ def test_not_emitted(self, qtbot, signaller):
with qtbot.assertNotEmitted(signaller.signal):
pass

def test_not_emitted_signals(self, qtbot, signaller):
with qtbot.assertNotEmitted((signaller.signal, signaller.signal_2)):
pass

def test_emitted(self, qtbot, signaller):
with pytest.raises(SignalEmittedError) as excinfo:
with pytest.raises(SignalEmittedError, match="Signal .* unexpectedly emitted"):
with qtbot.assertNotEmitted(signaller.signal):
signaller.signal.emit()

fnmatch.fnmatchcase(str(excinfo.value), "Signal * unexpectedly emitted.")
def test_emitted_signals(self, qtbot, signaller):
with pytest.raises(
SignalEmittedError, match="Signals \\[.*, .*\\] unexpectedly emitted"
):
with qtbot.assertNotEmitted([signaller.signal_args, signaller.signal_2]):
signaller.signal_args.emit("foo", 123)
signaller.signal_2.emit()

def test_emitted_args(self, qtbot, signaller):
with pytest.raises(SignalEmittedError) as excinfo:
with pytest.raises(
SignalEmittedError,
match="Signal .* unexpectedly emitted with arguments \\['foo', 123\\]",
):
with qtbot.assertNotEmitted(signaller.signal_args):
signaller.signal_args.emit("foo", 123)

fnmatch.fnmatchcase(
str(excinfo.value),
"Signal * unexpectedly emitted with arguments ['foo', 123]",
)

def test_disconnected(self, qtbot, signaller):
with qtbot.assertNotEmitted(signaller.signal):
with qtbot.assertNotEmitted([signaller.signal, signaller.signal_2]):
pass
signaller.signal.emit()
signaller.signal_2.emit()

def test_emitted_late(self, qtbot, signaller, timer):
with pytest.raises(SignalEmittedError):
with qtbot.assertNotEmitted(signaller.signal, wait=100):
with qtbot.assertNotEmitted(
[signaller.signal, signaller.signal_2], wait=100
):
timer.single_shot(signaller.signal, 10)

def test_continues_when_emitted(self, qtbot, signaller, stop_watch):
Expand Down