Skip to content

Commit e3e2c52

Browse files
authored
feat: allow testing to accept connection kwargs (#378)
1 parent 26195d3 commit e3e2c52

File tree

1 file changed

+69
-19
lines changed

1 file changed

+69
-19
lines changed

src/psygnal/testing.py

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,21 @@
1111

1212
if TYPE_CHECKING:
1313
from collections.abc import Iterator
14-
from typing import Any
14+
from threading import Thread
15+
from typing import Any, Literal
1516

16-
from typing_extensions import Self
17+
from typing_extensions import Self, TypedDict
18+
19+
class ConnectKwargs(TypedDict, total=False):
20+
"""Kwargs for SignalInstance.connect."""
21+
22+
thread: Thread | Literal["main", "current"] | None
23+
check_nargs: bool | None
24+
check_types: bool | None
25+
unique: bool | Literal["raise"]
26+
max_args: int | None
27+
on_ref_error: Literal["raise", "warn", "ignore"]
28+
priority: int
1729

1830

1931
__all__ = [
@@ -46,6 +58,9 @@ class SignalTester:
4658
----------
4759
signal : SignalInstance | SignalGroup
4860
The signal instance or group to test.
61+
connect_kwargs : ConnectKwargs
62+
Keyword arguments to pass to the
63+
[`SignalInstance.connect()`][psygnal.SignalInstance.connect] method.
4964
5065
Attributes
5166
----------
@@ -82,14 +97,19 @@ class MyObject:
8297
```
8398
"""
8499

85-
def __init__(self, signal: SignalInstance | SignalGroup) -> None:
100+
def __init__(
101+
self,
102+
signal: SignalInstance | SignalGroup,
103+
connect_kwargs: ConnectKwargs | None = None,
104+
) -> None:
86105
super().__init__()
87106
self.mock = Mock()
88107
if isinstance(signal, SignalGroup):
89108
signal_instance: SignalInstance = signal._psygnal_relay
90109
else:
91110
signal_instance = signal
92111
self.signal_instance: SignalInstance = signal_instance
112+
self.connect_kwargs = connect_kwargs or {}
93113

94114
def reset(self) -> None:
95115
"""Reset the underlying mock object."""
@@ -115,7 +135,7 @@ def emit_args_list(self) -> list[tuple[Any, ...]]:
115135

116136
def connect(self) -> None:
117137
"""Connect the mock to the signal."""
118-
self.signal_instance.connect(self.mock)
138+
self.signal_instance.connect(self.mock, **self.connect_kwargs)
119139

120140
def disconnect(self) -> None:
121141
"""Disconnect the mock from the signal."""
@@ -207,129 +227,159 @@ def assert_ever_emitted_with(self, /, *args: Any) -> None:
207227

208228

209229
@contextmanager
210-
def assert_emitted(signal: SignalInstance | SignalGroup) -> Iterator[SignalTester]:
230+
def assert_emitted(
231+
signal: SignalInstance | SignalGroup, connect_kwargs: ConnectKwargs | None = None
232+
) -> Iterator[SignalTester]:
211233
"""Assert that a signal was emitted at least once.
212234
213235
Parameters
214236
----------
215237
signal : SignalInstance | SignalGroup
216238
The signal instance or group to test.
239+
connect_kwargs : ConnectKwargs
240+
Keyword arguments to pass to the
241+
[`SignalInstance.connect()`][psygnal.SignalInstance.connect] method.
217242
218243
Raises
219244
------
220245
AssertionError
221246
If the signal was never emitted.
222247
"""
223-
with SignalTester(signal) as mock:
248+
with SignalTester(signal, connect_kwargs) as mock:
224249
yield mock
225250
mock.assert_emitted()
226251

227252

228253
@contextmanager
229-
def assert_emitted_once(signal: SignalInstance | SignalGroup) -> Iterator[SignalTester]:
254+
def assert_emitted_once(
255+
signal: SignalInstance | SignalGroup, connect_kwargs: ConnectKwargs | None = None
256+
) -> Iterator[SignalTester]:
230257
"""Assert that a signal was emitted exactly once.
231258
232259
Parameters
233260
----------
234261
signal : SignalInstance | SignalGroup
235262
The signal instance or group to test.
263+
connect_kwargs : ConnectKwargs
264+
Keyword arguments to pass to the
265+
[`SignalInstance.connect()`][psygnal.SignalInstance.connect] method.
236266
237267
Raises
238268
------
239269
AssertionError
240270
If the signal was emitted more than once.
241271
"""
242-
with SignalTester(signal) as mock:
272+
with SignalTester(signal, connect_kwargs) as mock:
243273
yield mock
244274
mock.assert_emitted_once()
245275

246276

247277
@contextmanager
248-
def assert_not_emitted(signal: SignalInstance | SignalGroup) -> Iterator[SignalTester]:
278+
def assert_not_emitted(
279+
signal: SignalInstance | SignalGroup, connect_kwargs: ConnectKwargs | None = None
280+
) -> Iterator[SignalTester]:
249281
"""Assert that a signal was never emitted.
250282
251283
Parameters
252284
----------
253285
signal : SignalInstance | SignalGroup
254286
The signal instance or group to test.
287+
connect_kwargs : ConnectKwargs
288+
Keyword arguments to pass to the
289+
[`SignalInstance.connect()`][psygnal.SignalInstance.connect] method.
255290
256291
Raises
257292
------
258293
AssertionError
259294
If the signal was emitted at least once.
260295
"""
261-
with SignalTester(signal) as mock:
296+
with SignalTester(signal, connect_kwargs) as mock:
262297
yield mock
263298
mock.assert_not_emitted()
264299

265300

266301
@contextmanager
267302
def assert_emitted_with(
268-
signal: SignalInstance | SignalGroup, *args: Any
303+
signal: SignalInstance | SignalGroup,
304+
*args: Any,
305+
connect_kwargs: ConnectKwargs | None = None,
269306
) -> Iterator[SignalTester]:
270307
"""Assert that the *last* emission of the signal had the given arguments.
271308
272309
Parameters
273310
----------
274311
signal : SignalInstance | SignalGroup
275312
The signal instance or group to test.
276-
args : Any
313+
*args : Any
277314
The arguments to check for in the last emission of the signal.
315+
connect_kwargs : ConnectKwargs
316+
Keyword arguments to pass to the
317+
[`SignalInstance.connect()`][psygnal.SignalInstance.connect] method.
278318
279319
Raises
280320
------
281321
AssertionError
282322
If the signal was never emitted or if the last emission did not have the
283323
expected arguments.
284324
"""
285-
with assert_emitted(signal) as mock:
325+
with assert_emitted(signal, connect_kwargs) as mock:
286326
yield mock
287327
mock.assert_emitted_with(*args)
288328

289329

290330
@contextmanager
291331
def assert_emitted_once_with(
292-
signal: SignalInstance | SignalGroup, *args: Any
332+
signal: SignalInstance | SignalGroup,
333+
*args: Any,
334+
connect_kwargs: ConnectKwargs | None = None,
293335
) -> Iterator[SignalTester]:
294336
"""Assert that the signal was emitted exactly once with the given arguments.
295337
296338
Parameters
297339
----------
298340
signal : SignalInstance | SignalGroup
299341
The signal instance or group to test.
300-
args : Any
342+
*args : Any
301343
The arguments to check for in the last emission of the signal.
344+
connect_kwargs : ConnectKwargs
345+
Keyword arguments to pass to the
346+
[`SignalInstance.connect()`][psygnal.SignalInstance.connect] method.
302347
303348
Raises
304349
------
305350
AssertionError
306351
If the signal was not emitted or was emitted more than once or if the last
307352
emission did not have the expected arguments.
308353
"""
309-
with assert_emitted_once(signal) as mock:
354+
with assert_emitted_once(signal, connect_kwargs) as mock:
310355
yield mock
311356
mock.assert_emitted_once_with(*args)
312357

313358

314359
@contextmanager
315360
def assert_ever_emitted_with(
316-
signal: SignalInstance | SignalGroup, *args: Any
361+
signal: SignalInstance | SignalGroup,
362+
*args: Any,
363+
connect_kwargs: ConnectKwargs | None = None,
317364
) -> Iterator[SignalTester]:
318365
"""Assert that the signal was emitted *ever* with the given arguments.
319366
320367
Parameters
321368
----------
322369
signal : SignalInstance | SignalGroup
323370
The signal instance or group to test.
324-
args : Any
371+
*args : Any
325372
The arguments to check for in any emission of the signal.
373+
connect_kwargs : ConnectKwargs
374+
Keyword arguments to pass to the
375+
[`SignalInstance.connect()`][psygnal.SignalInstance.connect] method.
326376
327377
Raises
328378
------
329379
AssertionError
330380
If the signal was never emitted or if it was emitted but not with the expected
331381
arguments.
332382
"""
333-
with assert_emitted(signal) as mock:
383+
with assert_emitted(signal, connect_kwargs) as mock:
334384
yield mock
335385
mock.assert_ever_emitted_with(*args)

0 commit comments

Comments
 (0)