Archived
Deprecation message
This commit is contained in:
@@ -99,6 +99,7 @@ async def run_connector_session() -> None:
|
||||
handshake: HandshakeAccepted
|
||||
|
||||
peer = writer.get_extra_info("peername")
|
||||
value_task: asyncio.Task[None] | None = None
|
||||
print(f"Connected to DynaLab at {peer}")
|
||||
|
||||
try:
|
||||
@@ -129,6 +130,8 @@ async def run_connector_session() -> None:
|
||||
elif isinstance(message, HandshakeRejected):
|
||||
print(f"Connector handshake rejected: {message.reason}")
|
||||
return
|
||||
else:
|
||||
raise ValueError(f"Expected handshake response, received {message.type}")
|
||||
|
||||
value_task = asyncio.create_task(_value_sender(writer, connector_hello))
|
||||
# Keep the connection alive by returning heartbeat messages.
|
||||
@@ -137,15 +140,15 @@ async def run_connector_session() -> None:
|
||||
print(f"Received {message}")
|
||||
|
||||
if isinstance(message, Heartbeat):
|
||||
if message.sequence < 10:
|
||||
message.return_timestamp = machine_timestamp_ms()
|
||||
await write_message(writer, message)
|
||||
message.return_timestamp = machine_timestamp_ms()
|
||||
await write_message(writer, message)
|
||||
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
|
||||
finally:
|
||||
value_task.cancel()
|
||||
if value_task is not None:
|
||||
value_task.cancel()
|
||||
print("Disconnecting")
|
||||
writer.close()
|
||||
await writer.wait_closed()
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
||||
|
||||
dearpygui = types.ModuleType("dearpygui")
|
||||
dearpygui_dearpygui = types.ModuleType("dearpygui.dearpygui")
|
||||
sys.modules.setdefault("dearpygui", dearpygui)
|
||||
sys.modules.setdefault("dearpygui.dearpygui", dearpygui_dearpygui)
|
||||
sys.modules.setdefault("dpg_gauges", types.ModuleType("dpg_gauges"))
|
||||
|
||||
from dynalab.ui import windows
|
||||
|
||||
|
||||
class LoadingLayoutTests(unittest.TestCase):
|
||||
def test_center_loading_content_positions_logo_and_bottom_text(self) -> None:
|
||||
calls: list[tuple[str, str, object]] = []
|
||||
|
||||
windows.dpg.does_item_exist = lambda tag: tag == "loading_window"
|
||||
windows.dpg.get_viewport_client_width = lambda: 600
|
||||
windows.dpg.get_viewport_client_height = lambda: 400
|
||||
windows.dpg.set_item_width = lambda tag, width: calls.append(
|
||||
("width", tag, width)
|
||||
)
|
||||
windows.dpg.set_item_height = lambda tag, height: calls.append(
|
||||
("height", tag, height)
|
||||
)
|
||||
windows.dpg.set_item_pos = lambda tag, pos: calls.append(("pos", tag, pos))
|
||||
windows.dpg.get_item_rect_size = lambda tag: {
|
||||
"loading_logo": (300, 100),
|
||||
"loading_text": (100, 20),
|
||||
}[tag]
|
||||
|
||||
windows.center_loading_content()
|
||||
|
||||
self.assertIn(("pos", "loading_logo_group", [150, 150]), calls)
|
||||
self.assertIn(("pos", "loading_text_row", [0, 356]), calls)
|
||||
self.assertIn(("width", "loading_text_left_spacer", 250), calls)
|
||||
self.assertNotIn(
|
||||
"loading_text",
|
||||
[tag for call_type, tag, _ in calls if call_type == "pos"],
|
||||
)
|
||||
|
||||
def test_loading_layout_handles_text_wider_than_logo(self) -> None:
|
||||
logo_pos, text_row_pos, text_spacer_width = windows._loading_content_layout(
|
||||
viewport_size=(600, 400),
|
||||
logo_size=(120, 50),
|
||||
text_size=(200, 20),
|
||||
)
|
||||
|
||||
self.assertEqual(logo_pos, [240, 175])
|
||||
self.assertEqual(text_row_pos, [0, 356])
|
||||
self.assertEqual(text_spacer_width, 200)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,81 @@
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from uuid import uuid4
|
||||
|
||||
from dynalab.connectors.events import (
|
||||
SignalConnectedEvent,
|
||||
SignalDisconnectedEvent,
|
||||
SignalValueEvent,
|
||||
)
|
||||
from dynalab.state import AppState
|
||||
from dynalab.ui.live_data.controller import handle_connector_event
|
||||
from dynalab.ui.live_data.tags import signal_gauge_tag
|
||||
from dynalab_protocol.models import SignalDescriptor
|
||||
|
||||
|
||||
class ApplicationStateTests(unittest.TestCase):
|
||||
def test_instances_do_not_share_threading_state(self) -> None:
|
||||
first = AppState()
|
||||
second = AppState()
|
||||
|
||||
first.stop_event.set()
|
||||
first.connector_events.put(SignalValueEvent(uuid4(), 1.0))
|
||||
|
||||
self.assertFalse(second.stop_event.is_set())
|
||||
self.assertTrue(second.connector_events.empty())
|
||||
|
||||
|
||||
class LiveDataControllerTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.state = AppState()
|
||||
self.connector_id = uuid4()
|
||||
self.signal = SignalDescriptor(
|
||||
id=uuid4(),
|
||||
name="Engine speed",
|
||||
type="number",
|
||||
min_value=0,
|
||||
max_value=9000,
|
||||
unit="rpm",
|
||||
)
|
||||
|
||||
@patch("dynalab.ui.live_data.controller.dpgg")
|
||||
def test_signal_lifecycle_updates_state_and_gauge(self, gauges) -> None:
|
||||
handle_connector_event(
|
||||
self.state, SignalConnectedEvent(self.connector_id, self.signal)
|
||||
)
|
||||
handle_connector_event(
|
||||
self.state, SignalValueEvent(self.signal.id, 3250.0)
|
||||
)
|
||||
handle_connector_event(
|
||||
self.state, SignalDisconnectedEvent(self.connector_id, self.signal.id)
|
||||
)
|
||||
|
||||
gauges.digital_gauge.assert_called_once()
|
||||
gauges.set_value.assert_called_once_with(
|
||||
tag=signal_gauge_tag(self.signal.id), value=3250.0
|
||||
)
|
||||
gauges.delete_gauge.assert_called_once_with(
|
||||
tag=signal_gauge_tag(self.signal.id)
|
||||
)
|
||||
self.assertNotIn(self.signal.id, self.state.signals.descriptors)
|
||||
self.assertNotIn(self.signal.id, self.state.signals.values)
|
||||
|
||||
@patch("dynalab.ui.live_data.controller.dpgg")
|
||||
def test_shared_signal_remains_until_last_connector_disconnects(self, gauges) -> None:
|
||||
other_connector_id = uuid4()
|
||||
handle_connector_event(
|
||||
self.state, SignalConnectedEvent(self.connector_id, self.signal)
|
||||
)
|
||||
handle_connector_event(
|
||||
self.state, SignalConnectedEvent(other_connector_id, self.signal)
|
||||
)
|
||||
handle_connector_event(
|
||||
self.state, SignalDisconnectedEvent(self.connector_id, self.signal.id)
|
||||
)
|
||||
|
||||
gauges.delete_gauge.assert_not_called()
|
||||
self.assertIn(self.signal.id, self.state.signals.descriptors)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user