From 2ba570a7ef3c416810a93fff8fe31150c36feef9 Mon Sep 17 00:00:00 2001 From: michael Date: Thu, 16 Jul 2026 12:43:58 -0700 Subject: [PATCH] test(rawcli): guard Ctrl-t breadcrumb flips 0x<->0b + redraw Closes the last loose end from the byte-line autocomplete fix: the entry-mode toggle correctly flips the breadcrumb prefix (0x <-> 0b) and requests a redraw. Adds test_toggle_updates_breadcrumb_prefix and updates the roadmap. Co-Authored-By: Claude Opus 4.8 --- docs/rawcli-todo.md | 6 ++++-- tests/test_rawcli.py | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/rawcli-todo.md b/docs/rawcli-todo.md index 979670f..f0d33ec 100644 --- a/docs/rawcli-todo.md +++ b/docs/rawcli-todo.md @@ -23,8 +23,10 @@ appends (optionally after an auto-space) or drops, so the change is always a pur key handler: the menu now populates on every digit in both modes. Regression: `TestKeyBindings::test_digit_binding_fires_completion_trigger_for_raw_bytes`. -Still worth a quick live-REPL eyeball with a tag on the antenna, and confirming the Ctrl-t / Ctrl-_ -toggle flips the breadcrumb to `0b` (separate from the completion trigger, not yet re-verified). +The Ctrl-t / Ctrl-_ toggle correctly flips the breadcrumb `0x` <-> `0b` and requests a redraw +(verified, guarded by `test_toggle_updates_breadcrumb_prefix`). An end-to-end live-session test +(`TestRawcliLiveSession`) drives the real PromptSession via a pipe input. A human eyeball of the +rendered dropdown on a real terminal is the only thing left unautomated. ## Priority 1 — MIFARE Classic (do this first) diff --git a/tests/test_rawcli.py b/tests/test_rawcli.py index 87438f6..d0945c5 100644 --- a/tests/test_rawcli.py +++ b/tests/test_rawcli.py @@ -886,6 +886,26 @@ class TestKeyBindings: toggle.handler(event) assert s.entry_mode == "bin" and buf.text == "30" # mode flipped, buffer intact + def test_toggle_updates_breadcrumb_prefix(self): + # the toggle flips the breadcrumb entry prefix 0x <-> 0b and requests a redraw + from types import SimpleNamespace + from prompt_toolkit.key_binding import KeyBindings + from prompt_toolkit.buffer import Buffer + from pm3py.cli.rawcli.entry import install_key_bindings + s = RawSession() + kb = KeyBindings() + install_key_bindings(kb, s) + toggle = next(b for b in kb.bindings + if getattr(b.keys[0], "value", b.keys[0]) in ("c-t", "c-_")) + redraws = [] + ev = SimpleNamespace(current_buffer=Buffer(), data="", + app=SimpleNamespace(invalidate=lambda: redraws.append(1))) + assert "0x" in s.breadcrumb() and "0b" not in s.breadcrumb() + toggle.handler(ev) + assert "0b" in s.breadcrumb() and s.entry_prefix == "0b" and redraws # flipped + redraw + toggle.handler(ev) + assert "0x" in s.breadcrumb() and "0b" not in s.breadcrumb() # and back + def test_digit_binding_tracks_per_byte_base(self): # replay keystrokes through the real digit binding: 30 (hex) then binary -> 30 00000100 from types import SimpleNamespace