Skip to content

Commit ae8669f

Browse files
committed
test(tui): cover after-render update-notice snapshot cleanup
Extract the after_render frame-clear closure into a named _clear_prompt_frame_snapshot method so the lifecycle cleanup is directly testable, and assert a completed frame leaves _prompt_frame_update_notice as None.
1 parent 7078692 commit ae8669f

2 files changed

Lines changed: 16 additions & 7 deletions

File tree

src/pythinker_code/ui/shell/prompt.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,14 +2842,8 @@ def _capture_prompt_frame(app: Application[str]) -> None:
28422842
terminal_rows=size.rows,
28432843
)
28442844

2845-
def _clear_prompt_frame(_app: Application[str]) -> None:
2846-
self._current_prompt_frame = None
2847-
# Drop the per-frame notice snapshot with the frame so a later render
2848-
# can never read a value captured for a stale frame/mode.
2849-
self._prompt_frame_update_notice = None
2850-
28512845
self._session.app.before_render.add_handler(_capture_prompt_frame)
2852-
self._session.app.after_render.add_handler(_clear_prompt_frame)
2846+
self._session.app.after_render.add_handler(self._clear_prompt_frame_snapshot)
28532847

28542848
# Throttle redraws so the fast streaming-reveal cadence can't overwhelm
28552849
# slower terminals (best practice for "invalidate is called a lot").
@@ -3278,6 +3272,13 @@ def _make_prompt_frame_collector(self) -> PromptFrameCollector:
32783272
turn_is_starting=lambda: getattr(self, "_turn_starting", False),
32793273
)
32803274

3275+
def _clear_prompt_frame_snapshot(self, _app: Application[str] | None = None) -> None:
3276+
"""after_render handler: drop the captured frame and its per-frame update
3277+
notice together, so a later render can never read a snapshot captured for a
3278+
stale frame/mode."""
3279+
self._current_prompt_frame = None
3280+
self._prompt_frame_update_notice = None
3281+
32813282
def _prompt_frame_for_render(self, *, columns: int | None = None) -> PromptFrame:
32823283
current = getattr(self, "_current_prompt_frame", None)
32833284
if current is not None:

tests/ui_and_conv/test_prompt_height_budget.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ def test_shell_render_refreshes_update_notice_snapshot(
179179
session._append_update_notice(fragments, 80)
180180
assert fragments == []
181181

182+
# The registered after_render cleanup drops the snapshot with the frame, so a
183+
# completed frame never leaves a value for the next render to read.
184+
session._current_prompt_frame = object() # type: ignore[assignment]
185+
session._prompt_frame_update_notice = "↑ Update available"
186+
session._clear_prompt_frame_snapshot()
187+
assert session._current_prompt_frame is None
188+
assert session._prompt_frame_update_notice is None
189+
182190

183191
def test_two_row_modal_uses_hint_then_tail(monkeypatch: pytest.MonkeyPatch) -> None:
184192
session = _session_for_scene(

0 commit comments

Comments
 (0)