import time from unittest.mock import Mock import pytest from fenrirscreenreader.core.tabCompletionManager import TabCompletionManager def _build_env(old_text="", cursor=None, screen="pty"): if cursor is None: cursor = {"x": 0, "y": 0} input_manager = Mock() input_manager.get_last_event.return_value = { "event_name": "KEY_TAB", "event_state": 1, } env = { "runtime": { "InputManager": input_manager, }, "screen": { "new_cursor": cursor.copy(), "new_content_text": old_text, "new_delta": "", "new_delta_is_typing": False, "newTTY": screen, }, "commandBuffer": {}, } manager = TabCompletionManager() manager.initialize(env) return manager, env, input_manager def _set_screen_update(env, text, cursor, delta="", typing=False): env["screen"]["new_content_text"] = text env["screen"]["new_cursor"] = cursor.copy() env["screen"]["new_delta"] = delta env["screen"]["new_delta_is_typing"] = typing @pytest.mark.unit def test_unique_completion_speaks_inserted_suffix(): manager, env, _input_manager = _build_env( "cd Do".ljust(20), {"x": 5, "y": 0} ) manager.capture_if_tab() _set_screen_update( env, "cd Documents/".ljust(20), {"x": 13, "y": 0}, delta="cuments/", typing=True, ) assert manager.process_update() == "cuments/" state = env["commandBuffer"]["tabCompletion"] assert state["pending"] is None assert state["lastProcessedDelta"] == "cuments/" @pytest.mark.unit def test_candidate_list_speaks_visible_list_without_cursor_advance(): old_text = "\n".join(["$ cd Do".ljust(20), "".ljust(20), "".ljust(20)]) manager, env, _input_manager = _build_env(old_text, {"x": 7, "y": 0}) manager.capture_if_tab() _set_screen_update( env, "\n".join( [ "$ cd Do".ljust(20), "Documents/ Downloads/".ljust(20), "$ cd Do".ljust(20), ] ), {"x": 7, "y": 2}, delta="Documents/ Downloads/", ) assert manager.process_update() == "Documents/ Downloads/" @pytest.mark.unit def test_no_screen_change_stays_silent_and_keeps_pending_briefly(): manager, env, _input_manager = _build_env( "cd Do".ljust(20), {"x": 5, "y": 0} ) manager.capture_if_tab() assert manager.process_update() == "" assert env["commandBuffer"]["tabCompletion"]["pending"] is not None @pytest.mark.unit def test_timeout_clears_pending_without_speech(): manager, env, _input_manager = _build_env( "cd Do".ljust(20), {"x": 5, "y": 0} ) manager.capture_if_tab() env["commandBuffer"]["tabCompletion"]["pending"]["timestamp"] = ( time.time() - 1 ) _set_screen_update( env, "unrelated output".ljust(20), {"x": 0, "y": 0}, delta="unrelated output", ) assert manager.process_update() == "" assert env["commandBuffer"]["tabCompletion"]["pending"] is None @pytest.mark.unit def test_non_tab_key_does_not_capture(): manager, env, input_manager = _build_env( "cd Do".ljust(20), {"x": 5, "y": 0} ) input_manager.get_last_event.return_value = { "event_name": "KEY_A", "event_state": 1, } manager.capture_if_tab() assert env["commandBuffer"]["tabCompletion"]["pending"] is None