162 lines
6.0 KiB
Python
162 lines
6.0 KiB
Python
"""
|
|
Tests for engine.websocket_display module.
|
|
"""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from engine.websocket_display import WebSocketDisplay
|
|
|
|
|
|
class TestWebSocketDisplayImport:
|
|
"""Test that websocket module can be imported."""
|
|
|
|
def test_import_does_not_error(self):
|
|
"""Module imports without error."""
|
|
from engine import websocket_display
|
|
|
|
assert websocket_display is not None
|
|
|
|
|
|
class TestWebSocketDisplayInit:
|
|
"""Tests for WebSocketDisplay initialization."""
|
|
|
|
def test_default_init(self):
|
|
"""Default initialization sets correct defaults."""
|
|
with patch("engine.websocket_display.websockets", None):
|
|
display = WebSocketDisplay()
|
|
assert display.host == "0.0.0.0"
|
|
assert display.port == 8765
|
|
assert display.http_port == 8766
|
|
assert display.width == 80
|
|
assert display.height == 24
|
|
|
|
def test_custom_init(self):
|
|
"""Custom initialization uses provided values."""
|
|
with patch("engine.websocket_display.websockets", None):
|
|
display = WebSocketDisplay(host="localhost", port=9000, http_port=9001)
|
|
assert display.host == "localhost"
|
|
assert display.port == 9000
|
|
assert display.http_port == 9001
|
|
|
|
def test_is_available_when_websockets_present(self):
|
|
"""is_available returns True when websockets is available."""
|
|
pytest.importorskip("websockets")
|
|
display = WebSocketDisplay()
|
|
assert display.is_available() is True
|
|
|
|
@pytest.mark.skipif(
|
|
pytest.importorskip("websockets") is not None, reason="websockets is available"
|
|
)
|
|
def test_is_available_when_websockets_missing(self):
|
|
"""is_available returns False when websockets is not available."""
|
|
display = WebSocketDisplay()
|
|
assert display.is_available() is False
|
|
|
|
|
|
class TestWebSocketDisplayProtocol:
|
|
"""Test that WebSocketDisplay satisfies Display protocol."""
|
|
|
|
def test_websocket_display_is_display(self):
|
|
"""WebSocketDisplay satisfies Display protocol."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay()
|
|
assert hasattr(display, "init")
|
|
assert hasattr(display, "show")
|
|
assert hasattr(display, "clear")
|
|
assert hasattr(display, "cleanup")
|
|
|
|
|
|
class TestWebSocketDisplayMethods:
|
|
"""Tests for WebSocketDisplay methods."""
|
|
|
|
def test_init_stores_dimensions(self):
|
|
"""init stores terminal dimensions."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay()
|
|
display.init(100, 40)
|
|
assert display.width == 100
|
|
assert display.height == 40
|
|
|
|
def test_client_count_initially_zero(self):
|
|
"""client_count returns 0 when no clients connected."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay()
|
|
assert display.client_count() == 0
|
|
|
|
def test_get_ws_port(self):
|
|
"""get_ws_port returns configured port."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay(port=9000)
|
|
assert display.get_ws_port() == 9000
|
|
|
|
def test_get_http_port(self):
|
|
"""get_http_port returns configured port."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay(http_port=9001)
|
|
assert display.get_http_port() == 9001
|
|
|
|
def test_frame_delay_defaults_to_zero(self):
|
|
"""get_frame_delay returns 0 by default."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay()
|
|
assert display.get_frame_delay() == 0.0
|
|
|
|
def test_set_frame_delay(self):
|
|
"""set_frame_delay stores the value."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay()
|
|
display.set_frame_delay(0.05)
|
|
assert display.get_frame_delay() == 0.05
|
|
|
|
|
|
class TestWebSocketDisplayCallbacks:
|
|
"""Tests for WebSocketDisplay callback methods."""
|
|
|
|
def test_set_client_connected_callback(self):
|
|
"""set_client_connected_callback stores callback."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay()
|
|
callback = MagicMock()
|
|
display.set_client_connected_callback(callback)
|
|
assert display._client_connected_callback is callback
|
|
|
|
def test_set_client_disconnected_callback(self):
|
|
"""set_client_disconnected_callback stores callback."""
|
|
with patch("engine.websocket_display.websockets", MagicMock()):
|
|
display = WebSocketDisplay()
|
|
callback = MagicMock()
|
|
display.set_client_disconnected_callback(callback)
|
|
assert display._client_disconnected_callback is callback
|
|
|
|
|
|
class TestWebSocketDisplayUnavailable:
|
|
"""Tests when WebSocket support is unavailable."""
|
|
|
|
@pytest.mark.skipif(
|
|
pytest.importorskip("websockets") is not None, reason="websockets is available"
|
|
)
|
|
def test_start_server_noop_when_unavailable(self):
|
|
"""start_server does nothing when websockets unavailable."""
|
|
display = WebSocketDisplay()
|
|
display.start_server()
|
|
assert display._server_thread is None
|
|
|
|
@pytest.mark.skipif(
|
|
pytest.importorskip("websockets") is not None, reason="websockets is available"
|
|
)
|
|
def test_start_http_server_noop_when_unavailable(self):
|
|
"""start_http_server does nothing when websockets unavailable."""
|
|
display = WebSocketDisplay()
|
|
display.start_http_server()
|
|
assert display._http_thread is None
|
|
|
|
@pytest.mark.skipif(
|
|
pytest.importorskip("websockets") is not None, reason="websockets is available"
|
|
)
|
|
def test_show_noops_when_unavailable(self):
|
|
"""show does nothing when websockets unavailable."""
|
|
display = WebSocketDisplay()
|
|
display.show(["line1", "line2"])
|