156 lines
4.6 KiB
Python
156 lines
4.6 KiB
Python
import importlib.util
|
|
from pathlib import Path
|
|
from unittest.mock import Mock
|
|
|
|
import pytest
|
|
|
|
from fenrirscreenreader.core.inputManager import InputManager
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
COMMANDS_DIR = (
|
|
PROJECT_ROOT / "src" / "fenrirscreenreader" / "commands" / "commands"
|
|
)
|
|
KEYBOARD_DIR = PROJECT_ROOT / "config" / "keyboard"
|
|
|
|
|
|
def load_command(name):
|
|
spec = importlib.util.spec_from_file_location(
|
|
f"fenrir_{name}", COMMANDS_DIR / f"{name}.py"
|
|
)
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return module.command()
|
|
|
|
|
|
def run_command(name, content, cursor_x=0, cursor_y=0):
|
|
output_manager = Mock()
|
|
settings_manager = Mock()
|
|
settings_manager.get_setting_as_bool.return_value = True
|
|
env = {
|
|
"punctuation": {"PUNCTDICT": {" ": "space"}},
|
|
"screen": {
|
|
"newCursorReview": {"x": cursor_x, "y": cursor_y},
|
|
"new_content_text": content,
|
|
},
|
|
"runtime": {
|
|
"CursorManager": Mock(),
|
|
"OutputManager": output_manager,
|
|
"SettingsManager": settings_manager,
|
|
},
|
|
}
|
|
command = load_command(name)
|
|
command.initialize(env)
|
|
command.run()
|
|
return output_manager
|
|
|
|
|
|
def load_bindings(layout):
|
|
manager = InputManager()
|
|
manager.env = {
|
|
"bindings": {},
|
|
"rawBindings": {},
|
|
"runtime": {"DebugManager": Mock()},
|
|
}
|
|
manager.load_shortcuts(KEYBOARD_DIR / f"{layout}.conf")
|
|
return manager.env["bindings"]
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_current_word_is_spelled_one_character_at_a_time():
|
|
output_manager = run_command(
|
|
"review_curr_word_spell", "hello world", cursor_x=2
|
|
)
|
|
|
|
calls = output_manager.present_text.call_args_list
|
|
assert [call.args[0] for call in calls] == list("hello")
|
|
assert calls[0].kwargs == {
|
|
"interrupt": True,
|
|
"ignore_punctuation": True,
|
|
"announce_capital": True,
|
|
"flush": False,
|
|
}
|
|
assert all(call.kwargs["interrupt"] is False for call in calls[1:])
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_current_word_spelling_preserves_capitals_and_punctuation():
|
|
output_manager = run_command("review_curr_word_spell", "Hi!", cursor_x=1)
|
|
|
|
assert [
|
|
call.args[0] for call in output_manager.present_text.call_args_list
|
|
] == ["H", "i", "!"]
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.parametrize(
|
|
"command_name",
|
|
["review_curr_word_spell", "review_curr_word_phonetic"],
|
|
)
|
|
def test_current_word_spelling_announces_blank_when_no_word_exists(
|
|
command_name,
|
|
):
|
|
output_manager = run_command(command_name, " ")
|
|
|
|
output_manager.present_text.assert_called_once_with(
|
|
"blank", interrupt=True, flush=False
|
|
)
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_current_word_phonetic_spelling_uses_phonetic_names():
|
|
output_manager = run_command(
|
|
"review_curr_word_phonetic", "Az!", cursor_x=1
|
|
)
|
|
|
|
calls = output_manager.present_text.call_args_list
|
|
assert [call.args[0] for call in calls] == ["Alpha", "zulu", "!"]
|
|
assert calls[0].kwargs["interrupt"] is True
|
|
assert all(call.kwargs["interrupt"] is False for call in calls[1:])
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.parametrize(
|
|
("layout", "character_keys", "word_keys"),
|
|
[
|
|
("desktop", ["KEY_KP2"], ["KEY_KP5"]),
|
|
("laptop", ["KEY_COMMA", "KEY_FENRIR"], ["KEY_FENRIR", "KEY_K"]),
|
|
],
|
|
)
|
|
def test_progressive_review_bindings(layout, character_keys, word_keys):
|
|
bindings = load_bindings(layout)
|
|
|
|
assert bindings[str([1, character_keys])] == "REVIEW_CURR_CHAR"
|
|
assert bindings[str([2, character_keys])] == "REVIEW_CURR_CHAR_PHONETIC"
|
|
assert bindings[str([1, word_keys])] == "REVIEW_CURR_WORD"
|
|
assert bindings[str([2, word_keys])] == "REVIEW_CURR_WORD_SPELL"
|
|
assert bindings[str([3, word_keys])] == "REVIEW_CURR_WORD_PHONETIC"
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.parametrize("layout", ["desktop", "laptop"])
|
|
def test_layouts_do_not_bind_removed_keyboard_layout_cycle(layout):
|
|
bindings = load_bindings(layout)
|
|
|
|
assert "CYCLE_KEYBOARD_LAYOUT" not in bindings.values()
|
|
|
|
removed_commands = {
|
|
"REVIEW_PREV_CHAR_PHONETIC",
|
|
"REVIEW_NEXT_CHAR_PHONETIC",
|
|
"REVIEW_PREV_WORD_PHONETIC",
|
|
"REVIEW_NEXT_WORD_PHONETIC",
|
|
}
|
|
assert removed_commands.isdisjoint(bindings.values())
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_obsolete_phonetic_navigation_commands_are_removed():
|
|
removed_commands = [
|
|
"review_prev_char_phonetic.py",
|
|
"review_next_char_phonetic.py",
|
|
"review_prev_word_phonetic.py",
|
|
"review_next_word_phonetic.py",
|
|
]
|
|
|
|
assert all(not (COMMANDS_DIR / name).exists() for name in removed_commands)
|