"""Source-level contract for the Live Captions external Tactility app. The app is ELF-loaded firmware code, so this test guards the device protocol and persistence requirements before an ESP32-S3 build/install test is available. """ from pathlib import Path import unittest ROOT = Path(__file__).resolve().parents[1] APP = ROOT / "Apps" / "LiveCaptions" class LiveCaptionsContractTests(unittest.TestCase): def test_manifest_identifies_the_captions_app(self): manifest = (APP / "manifest.properties").read_text() self.assertIn("app.id=one.tactility.livecaptions", manifest) self.assertIn("app.name=Live Captions", manifest) self.assertIn("target.platforms=esp32s3", manifest) def test_app_streams_audio_and_logs_final_caption_to_daily_text_file(self): source = (APP / "main" / "Source" / "main.c").read_text() self.assertIn("audio_stream_open_input", source) self.assertIn("/sdcard/captions", source) self.assertIn('"%Y-%m-%d.txt"', source) self.assertIn("append_final_caption", source) self.assertIn('"draft"', source) self.assertIn('"interim_transcript"', source) self.assertIn('"transcript"', source) self.assertIn('"final"', source) self.assertIn("const char* stop", source) self.assertNotIn("i2s_controller_", source) def test_ui_autostarts_and_keeps_only_the_latest_thirty_words(self): source = (APP / "main" / "Source" / "main.c").read_text() self.assertIn("#define DISPLAY_WORD_LIMIT 50", source) self.assertIn("copy_recent_words", source) self.assertIn("tt_lvgl_toolbar_create_for_app", source) self.assertNotIn("lv_btn_create", source) self.assertNotIn("start_button", source) self.assertIn("xTaskCreate(worker_task", source) def test_connection_failure_stays_failed_until_user_starts_again(self): source = (APP / "main" / "Source" / "main.c").read_text() self.assertIn("CAPTION_FAILED", source) self.assertIn("Fail to connect", source) self.assertNotIn("retry_attempt", source) self.assertNotIn("retry scheduled", source) if __name__ == "__main__": unittest.main()