瀏覽代碼

Fixed flaky test

Efren Yevale Varela 1 月之前
父節點
當前提交
805c5f1def
共有 2 個文件被更改,包括 24 次插入 和 1 次删除
  1. 8 1
      src/stt_daemon/tui/app.py
  2. 16 0
      tests/test_tui_app.py

+ 8 - 1
src/stt_daemon/tui/app.py

@@ -45,6 +45,7 @@ class AssistantTUI(App):
         self._seen_transcripts = 0
         self._seen_lower = 0
         self._seen_epoch = 0
+        self._timer = None
 
     def compose(self) -> ComposeResult:
         yield Static(id="status")
@@ -71,7 +72,7 @@ class AssistantTUI(App):
         self.client.start(
             lambda event: self._events.put(event), on_state=self._on_conn_state
         )
-        self.set_interval(0.1, self._drain)
+        self._timer = self.set_interval(0.1, self._drain)
 
     def _on_conn_state(self, connected: bool) -> None:
         self.state.connected = connected
@@ -86,6 +87,10 @@ class AssistantTUI(App):
         self._render()
 
     def _render(self) -> None:
+        if not self.query("#status"):
+            # A timer tick can land while the app is shutting down, after the
+            # widgets are unmounted; there is nothing left to draw into.
+            return
         state = self.state
         health = "ok" if state.health_ok() else "DOWN"
         conn = "ok" if state.connected else "LOST"
@@ -149,6 +154,8 @@ class AssistantTUI(App):
         edit.display = False
 
     def on_unmount(self) -> None:
+        if self._timer is not None:
+            self._timer.stop()
         self.client.close()
 
 

+ 16 - 0
tests/test_tui_app.py

@@ -148,6 +148,22 @@ def test_tui_mounts_subscribes_and_ingests_broadcasts(server):
     assert app.state.mode == "command_armed"
 
 
+def test_render_after_unmount_is_safe(server):
+    """A timer tick can land during teardown; rendering must not raise."""
+    pytest.importorskip("textual")
+    from stt_daemon.tui.app import AssistantTUI
+
+    path, _service = server
+    app = AssistantTUI(path)
+
+    async def scenario():
+        async with app.run_test() as pilot:
+            await pilot.pause()
+
+    asyncio.run(scenario())
+    app._render()  # must not raise NoMatches
+
+
 def test_tui_records_connect_failure(tmp_path):
     pytest.importorskip("textual")
     from stt_daemon.tui.app import AssistantTUI