From 5ce365e0b4ba02395e229fac150aa1ce6106ae24 Mon Sep 17 00:00:00 2001 From: Lavindeep Dhillon Date: Sat, 27 Jun 2026 19:32:35 -0400 Subject: [PATCH] test(ui): make AppUI resize/cache tests environment-independent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The resize and cache-invalidation tests asserted byte-inequality of the rendered ANSI (ansi_80 != ansi_40). That conflates two things: whether AppUI re-rendered (what AppUI controls) and whether Rich produced different bytes for the two widths (terminal/Rich-version dependent). In an environment where Rich does not honor the explicit Console width, both widths render identical bytes and the value-inequality assertion fails spuriously — even though AppUI re-rendered correctly. Assert the contract AppUI actually owns instead: a width or content change is a cache miss that yields a fresh render object (identity, not value), mirroring test_cache_hit_at_same_width's 'is'. The resize test also pins the cache key to the new width. Verified red-first: a width-insensitive cache (no re-render) returns the same cached object and the identity assertion fails. The visible re-wrap stays a live-checklist item. --- tests/test_app_ui.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_app_ui.py b/tests/test_app_ui.py index 928d8d8..425bdba 100644 --- a/tests/test_app_ui.py +++ b/tests/test_app_ui.py @@ -283,16 +283,21 @@ def test_end_response_without_open_is_noop() -> None: def test_resize_rerenders_ansi() -> None: - """Changing the width from the width_fn triggers a re-render (cache miss).""" + """A width change re-renders. The width is re-read each call, so a different + width is a cache miss that yields a fresh render object re-keyed to the new + width — the environment-independent AppUI resize contract. (Whether the terminal + visibly re-wraps depends on the terminal/Rich and is a live-checklist item, so + we assert object identity + the cache key here, not byte-difference of output.) + """ width = [80] ui = AppUI(glyphs=GLYPHS, width_fn=lambda: width[0]) - # Add enough text that line-wrapping changes between 80 and 40 columns. ui.show_status("a" * 60 + " " + "b" * 60) ansi_80 = ui._render_ansi() width[0] = 40 ansi_40 = ui._render_ansi() - # The ANSI output must differ — different wrapping at different widths. - assert ansi_80 != ansi_40 + # Cache miss on the width change → a fresh object, re-keyed to the new width. + assert ansi_40 is not ansi_80 + assert ui._cache is not None and ui._cache[0] == 40 def test_cache_hit_at_same_width() -> None: @@ -311,7 +316,7 @@ def test_cache_invalidated_on_new_content() -> None: before = ui._render_ansi() ui.show_status("second") after = ui._render_ansi() - assert before != after + assert after is not before # cache invalidated → a fresh render, not the cached object assert "second" in plain(ui)