From d1463efa360d358f29c81c721d368b5f73f86483 Mon Sep 17 00:00:00 2001 From: mikecarper Date: Sat, 26 Sep 2026 08:11:12 -0700 Subject: [PATCH] Refresh CI contracts for manual radio pages and build wrapper --- test/test_full_build_flag_dedup.py | 2 +- test/test_indicator_exclusive_transport.py | 2 +- test/test_indicator_messages_profile.py | 16 +++++----- test/test_indicator_render_profile.py | 2 +- test/test_message_navigation.py | 35 +++++++++++++++++----- test/test_nrf52_variant_contracts.py | 2 +- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/test/test_full_build_flag_dedup.py b/test/test_full_build_flag_dedup.py index 9ee2568ba..337724d9c 100644 --- a/test/test_full_build_flag_dedup.py +++ b/test/test_full_build_flag_dedup.py @@ -13,7 +13,7 @@ from unittest import mock ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "scripts" / "deduplicate_full_build_flags.py" -BUILD_SCRIPT = ROOT / "build.sh" +BUILD_SCRIPT = ROOT / "build_legacy.sh" class FakeEnvironment: diff --git a/test/test_indicator_exclusive_transport.py b/test/test_indicator_exclusive_transport.py index d95c9cdb3..390930f5f 100644 --- a/test/test_indicator_exclusive_transport.py +++ b/test/test_indicator_exclusive_transport.py @@ -8,7 +8,7 @@ root = Path(__file__).resolve().parents[1] header = (root / "examples/companion_radio/CompanionWiFi.h").read_text() main = (root / "examples/companion_radio/main.cpp").read_text() mesh = (root / "examples/companion_radio/MyMesh.cpp").read_text() -build = (root / "build.sh").read_text() +build = (root / "build_legacy.sh").read_text() readme = (root / "variants/sensecap_indicator-espnow/README.md").read_text() webconfig = (root / "src/helpers/esp32/WebConfigServer.cpp").read_text() mqtt = (root / "src/helpers/bridges/MQTTBridge.cpp").read_text() diff --git a/test/test_indicator_messages_profile.py b/test/test_indicator_messages_profile.py index 1830ad856..a30ff0bc2 100644 --- a/test/test_indicator_messages_profile.py +++ b/test/test_indicator_messages_profile.py @@ -40,7 +40,7 @@ class IndicatorMessagesProfileTest(unittest.TestCase): self.assertIn("#if UI_MESSAGES_HOME_PAGE == 1\n MESSAGES,", ui) self.assertIn("_page == HomePage::MESSAGES", ui) - def test_wifi_setup_is_eighth_without_reordering_existing_pages(self): + def test_radio_pages_precede_transport_and_wifi_setup(self): ui = UI.read_text(encoding="utf-8") enum_start = ui.index(" enum HomePage {") enum_end = ui.index("\n };", enum_start) + len("\n };") @@ -59,12 +59,14 @@ static_assert(FIRST == 0, "first"); static_assert(MESSAGES == 1, "messages"); static_assert(RECENT == 2, "recent"); static_assert(RADIO == 3, "radio"); -static_assert(TRANSPORT == 4, "transport"); -static_assert(ADVERT == 5, "advert"); -static_assert(SENSORS == 6, "sensors"); -static_assert(WIFI_SETUP == 7, "wifi setup"); -static_assert(DISCOVERY == 8, "discovery appended without reordering"); -static_assert(Count == 9, "count"); +static_assert(RADIO2 == 4, "second radio"); +static_assert(RADIO_STATUS == 5, "radio status"); +static_assert(TRANSPORT == 6, "transport"); +static_assert(ADVERT == 7, "advert"); +static_assert(SENSORS == 8, "sensors"); +static_assert(WIFI_SETUP == 9, "wifi setup"); +static_assert(DISCOVERY == 10, "discovery follows setup"); +static_assert(Count == 11, "count"); int main() {{ return 0; }} """ with tempfile.TemporaryDirectory() as temp_dir: diff --git a/test/test_indicator_render_profile.py b/test/test_indicator_render_profile.py index edcf95a58..ea2cb303a 100644 --- a/test/test_indicator_render_profile.py +++ b/test/test_indicator_render_profile.py @@ -9,7 +9,7 @@ import unittest ROOT = Path(__file__).resolve().parents[1] -BUILD = ROOT / "build.sh" +BUILD = ROOT / "build_legacy.sh" MAIN = ROOT / "examples" / "companion_radio" / "main.cpp" MESH = ROOT / "examples" / "companion_radio" / "MyMesh.cpp" DATA_STORE = ROOT / "examples" / "companion_radio" / "DataStore.cpp" diff --git a/test/test_message_navigation.py b/test/test_message_navigation.py index 2f5068c27..41c6a3f79 100644 --- a/test/test_message_navigation.py +++ b/test/test_message_navigation.py @@ -46,6 +46,8 @@ struct StrHelper { }; struct ChannelDetails { char name[32]; }; struct Mesh { + bool dual_radio_active=false; + bool isDualRadioActive() const { return dual_radio_active; } bool getChannel(int channel,ChannelDetails& details) const { const char* names[]={"Public","","Second","Empty"}; if (channel<0 || channel>=MAX_GROUP_CHANNELS) return false; @@ -341,6 +343,20 @@ int main() { assert(home._page==HomeScreen::Count-1 && home.events==5); gesture(task,3); assert(task.buzzer_changes==1); gesture(task,4); assert(task.buzzer_changes==2); + // A single-profile board skips the two extra radio pages in both directions. + home._page=HomeScreen::RADIO; + gesture(task,1); assert(home._page==HomeScreen::DISCOVERY); + gesture(task,2); assert(home._page==HomeScreen::RADIO); + // With two profiles, the same physical button walks R1, R2 and status. + the_mesh.dual_radio_active=true; + gesture(task,1); assert(home._page==HomeScreen::RADIO2); + gesture(task,1); assert(home._page==HomeScreen::RADIO_STATUS); + home.handleInput(static_cast(KEY_ENTER)); + assert(home._radio_status_page==1); + gesture(task,1); assert(home._page==HomeScreen::DISCOVERY); + gesture(task,2); assert(home._page==HomeScreen::RADIO_STATUS); + gesture(task,2); assert(home._page==HomeScreen::RADIO2); + gesture(task,2); assert(home._page==HomeScreen::RADIO); } ''' @@ -366,16 +382,19 @@ class MessageNavigationTest(unittest.TestCase): home = source[source.index("class HomeScreen :"):] home_navigation = home[home.index(" bool handleInput(char c) override {"):] home_navigation = home_navigation.split("#ifdef COMPANION_EXCLUSIVE_WIFI_BLE", 1)[0] - # This focused navigation harness intentionally omits HomeScreen's - # radio-page timing state. Entering the radio page resets that state - # in production, but it is unrelated to the button routing exercised - # below, so remove only that call from the extracted fragment. - home_navigation = home_navigation.replace( - "if (_page == HomePage::RADIO) resetRadioProfileDisplayPage();\n", "") + # Keep the real radio-page navigation helpers in this focused harness, + # so new home pages cannot silently bypass the button-routing test. home_navigation = home_navigation.replace("{\n", "{\n Screen::handleInput(c);\n", 1) + radio_navigation = "\n".join(extract_braced(source, signature) for signature in ( + "void resetRadioProfileDisplayPage() {", + "bool isPageVisible(uint8_t page) const {", + "void movePage(int direction) {", + "bool isRadioPage() const {")) implementation += ("class HomeScreen : public Screen { public: UITask* _task; " - "enum HomePage {FIRST,MESSAGES,RECENT,RADIO,DISCOVERY,Count}; int _page=0; " - "HomeScreen(UITask* task):_task(task){}\n" + home_navigation + + "enum HomePage {FIRST,MESSAGES,RECENT,RADIO,RADIO2,RADIO_STATUS,DISCOVERY,Count}; " + "int _page=0; uint32_t _radio_profile_page_started_at=0; " + "uint8_t _radio_status_page=0; bool _dual_radio_enabled_seen=false; " + "HomeScreen(UITask* task):_task(task){}\n" + radio_navigation + "\n" + home_navigation + "return false; } };\n") target = (ROOT / "variants/sensecap_indicator-espnow/target.cpp").read_text() button = re.search(r"MomentaryButton user_btn\([^;]+;", target).group(0) diff --git a/test/test_nrf52_variant_contracts.py b/test/test_nrf52_variant_contracts.py index d232ede95..bdc633056 100644 --- a/test/test_nrf52_variant_contracts.py +++ b/test/test_nrf52_variant_contracts.py @@ -119,7 +119,7 @@ class Nrf52VariantContractsTest(unittest.TestCase): def test_rak3401_reduced_profile_names_its_narrow_sensor_trim(self) -> None: recipe = (ROOT / "variants/rak3401/platformio.ini").read_text() shared = (ROOT / "platformio.ini").read_text() - build_script = (ROOT / "build.sh").read_text() + build_script = (ROOT / "build_legacy.sh").read_text() expected_ina = { "ENV_INCLUDE_INA219",