Skip to content

Commit 522b0ae

Browse files
committed
Fix some tests
1 parent 412b4cd commit 522b0ae

File tree

4 files changed

+55
-19
lines changed

4 files changed

+55
-19
lines changed

streamdeck/event_listener.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ def stop(self) -> None:
8888

8989
for thread in self.listeners_lookup_by_thread:
9090
logger.debug("Stopping listener %s.")
91+
self.listeners_lookup_by_thread[thread].stop()
9192
if thread.is_alive():
92-
self.listeners_lookup_by_thread[thread].stop()
9393
thread.join()
9494

9595
logger.info("All listeners have been stopped.")

tests/event_listener/test_event_listener.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import threading
22
import time
33
from collections.abc import Generator
4-
from queue import Empty
5-
from typing import ClassVar, List, Optional
6-
from unittest.mock import MagicMock, Mock, patch
4+
from typing import Any, ClassVar
5+
from unittest.mock import Mock, patch
76

87
import pytest
98
from streamdeck.event_listener import EventListener, EventListenerManager
109
from streamdeck.models.events import ApplicationDidLaunch, EventBase
1110

1211

13-
# Mock implementation of EventListener for testing
1412
class MockEventListener(EventListener):
13+
"""Mock implementation of EventListener for testing."""
1514
event_models: ClassVar[list[type[EventBase]]] = [ApplicationDidLaunch]
1615

1716
def __init__(self):
@@ -33,6 +32,7 @@ def stop(self) -> None:
3332

3433

3534
class SlowMockEventListener(EventListener):
35+
"""Mock implementation of EventListener that yields events with a delay."""
3636
event_models: ClassVar[list[type[EventBase]]] = [ApplicationDidLaunch]
3737

3838
def __init__(self, delay: float = 0.1):
@@ -52,11 +52,9 @@ def stop(self) -> None:
5252

5353

5454
class ExceptionEventListener(EventListener):
55+
"""Mock implementation of EventListener that raises an exception."""
5556
event_models: ClassVar[list[type[EventBase]]] = [ApplicationDidLaunch]
5657

57-
# def __init__(self):
58-
# self._running = True
59-
6058
def listen(self) -> Generator[str, None, None]:
6159
self._running = True
6260
# Raise exception after yielding one event
@@ -65,7 +63,6 @@ def listen(self) -> Generator[str, None, None]:
6563

6664
def stop(self) -> None:
6765
pass
68-
# self._running = False
6966

7067

7168

@@ -148,15 +145,15 @@ def test_stop():
148145

149146

150147
@patch("streamdeck.event_listener.logger")
151-
def test_listener_exception_handling(mock_logger):
148+
def test_listener_exception_handling(mock_logger: Mock):
152149
"""Test that exceptions in listeners are properly caught and logged."""
153150
manager = EventListenerManager()
154151
listener = ExceptionEventListener()
155152

156153
manager.add_listener(listener)
157154

158155
# Collect events - should get one event before the exception
159-
events = []
156+
events: list[Any] = []
160157
for event in manager.event_stream():
161158
events.append(event)
162159
if len(events) >= 1: # We expect 1 event before exception
@@ -166,7 +163,7 @@ def test_listener_exception_handling(mock_logger):
166163

167164
assert "event_before_exception" in events
168165
# Check that the exception was logged
169-
mock_logger.exception.assert_called_with("Error in wrapped listener.")
166+
mock_logger.exception.assert_called_with("Unexpected error in wrapped listener %s. Stopping just this listener.", listener)
170167

171168

172169
def test_listener_wrapper():

tests/plugin_manager/test_plugin_manager.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def test_plugin_manager_sends_registration_event(
8888

8989
mock_command_sender.send_action_registration.assert_called_once_with(
9090
register_event=plugin_manager._register_event,
91-
plugin_registration_uuid=plugin_manager._registration_uuid,
9291
)
9392

9493

tests/test_websocket.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
from __future__ import annotations
22

33
import json
4-
from typing import TYPE_CHECKING
4+
from functools import partial
5+
from typing import TYPE_CHECKING, Any
56
from unittest.mock import Mock
67

78
import pytest
9+
from streamdeck.event_listener import StopStreaming
810
from streamdeck.websocket import WebSocketClient
9-
from websockets import ConnectionClosedOK, WebSocketException
11+
from websockets import (
12+
ConnectionClosed,
13+
ConnectionClosedError,
14+
ConnectionClosedOK,
15+
InvalidHeader,
16+
WebSocketException,
17+
)
1018

1119

1220
if TYPE_CHECKING:
@@ -18,13 +26,16 @@ def mock_connection() -> Mock:
1826
"""Fixture to mock the ClientConnection object returned by websockets.sync.client.connect."""
1927
return Mock()
2028

29+
2130
@pytest.fixture
2231
def patched_connect(mocker: MockerFixture, mock_connection: Mock) -> Mock:
2332
"""Fixture to mock the ClientConnection object returned by websockets.sync.client.connect."""
2433
return mocker.patch("streamdeck.websocket.connect", return_value=mock_connection)
2534

2635

27-
def test_initialization_calls_connect_correctly(patched_connect: Mock, mock_connection: Mock, port_number: int) -> None:
36+
def test_initialization_calls_connect_correctly(
37+
patched_connect: Mock, mock_connection: Mock, port_number: int
38+
) -> None:
2839
"""Test that WebSocketClient initializes correctly by calling the connect function with the appropriate URI."""
2940
with WebSocketClient(port=port_number) as client:
3041
# Assert that 'connect' was called once with the correct URI.
@@ -50,9 +61,38 @@ def test_send_event_serializes_and_sends(mock_connection: Mock, port_number: int
5061
def test_listen_yields_messages(mock_connection: Mock, port_number: int) -> None:
5162
"""Test that listen yields messages from the WebSocket connection."""
5263
# Set up the mocked connection to return messages until closing
53-
mock_connection.recv.side_effect = ["message1", b"message2", WebSocketException()]
64+
expected_results = ["message1", b"message2", "message3"]
65+
mock_connection.recv.side_effect = expected_results
5466

5567
with WebSocketClient(port=port_number) as client:
56-
messages = list(client.listen())
68+
actual_messages: list[Any] = []
69+
for i, msg in enumerate(client.listen()):
70+
actual_messages.append(msg)
71+
if i == 2:
72+
break
73+
74+
assert actual_messages == expected_results
75+
76+
77+
@pytest.mark.parametrize(
78+
"exception_class",
79+
[
80+
partial(ConnectionClosedOK, None, None),
81+
partial(ConnectionClosedError, None, None),
82+
partial(InvalidHeader, "header-name", None),
83+
partial(ConnectionClosed, None, None),
84+
WebSocketException,
85+
],
86+
)
87+
@pytest.mark.usefixtures("patched_connect")
88+
def test_listen_raises_StopStreaming_from_WebSocketException(
89+
mock_connection: Mock, port_number: int, exception_class: type[WebSocketException]
90+
) -> None:
91+
"""Test that listen raises a StopStreaming exception when a WebSocketException is raised."""
92+
# Set up the mocked connection to return messages until closing
93+
mock_connection.recv.side_effect = ["message1", b"message2", exception_class()]
5794

58-
assert messages == ["message1", b"message2"]
95+
# This should raise a StopStreaming exception when any WebSocketException is raised
96+
with WebSocketClient(port=port_number) as client, pytest.raises(StopStreaming):
97+
for _ in client.listen():
98+
pass

0 commit comments

Comments
 (0)