Fixed some half-completed work in generic drivers. Minor -x bug fixes.

This commit is contained in:
Storm Dragon
2026-06-18 10:35:48 -04:00
parent fd5fe5b328
commit 2b7d205f06
13 changed files with 425 additions and 119 deletions
+114
View File
@@ -0,0 +1,114 @@
from configparser import ConfigParser
from pathlib import Path
from unittest.mock import Mock
import pytest
from fenrirscreenreader.core.settingsData import settings_data
from fenrirscreenreader.soundDriver import genericDriver
class SettingsManager:
def __init__(self, settings):
self.settings = settings
def get_setting(self, section, setting):
return self.settings[setting]
def _sound_driver(settings):
sound_driver = genericDriver.driver()
sound_driver.initialize(
{"runtime": {"SettingsManager": SettingsManager(settings)}}
)
sound_driver.set_volume(0.75)
return sound_driver
def _configured_sound_settings():
config = ConfigParser(interpolation=None)
config.read(Path(__file__).parents[2] / "config/settings/settings.conf")
return {
"generic_play_file_command": config.get(
"sound", "generic_play_file_command"
),
"generic_frequency_command": config.get(
"sound", "generic_frequency_command"
),
}
def test_play_frequency_replaces_snake_case_placeholders(monkeypatch):
popen = Mock()
monkeypatch.setattr(genericDriver.subprocess, "Popen", popen)
sound_driver = _sound_driver(
{
"generic_play_file_command": "player fenrir_sound_file",
"generic_frequency_command": (
"tone --volume fenrir_volume --duration fenrir_duration "
"--frequency fenrir_frequency"
),
}
)
sound_driver.play_frequence(
440, 0.25, adjust_volume=0.5, interrupt=False
)
assert popen.call_args.args[0] == [
"tone",
"--volume",
"0.375",
"--duration",
"0.25",
"--frequency",
"440",
]
def test_play_sound_file_replaces_snake_case_placeholders(
monkeypatch, tmp_path
):
popen = Mock()
monkeypatch.setattr(genericDriver.subprocess, "Popen", popen)
sound_file = tmp_path / "sound file.ogg"
sound_file.write_bytes(b"")
sound_driver = _sound_driver(
{
"generic_play_file_command": (
"player --volume fenrir_volume fenrir_sound_file"
),
"generic_frequency_command": "tone fenrir_frequency",
}
)
sound_driver.play_sound_file(str(sound_file), interrupt=False)
assert popen.call_args.args[0] == [
"player",
"--volume",
"0.75",
str(sound_file),
]
@pytest.mark.parametrize(
"settings",
[settings_data["sound"], _configured_sound_settings()],
)
def test_default_sound_commands_use_supported_placeholders(
monkeypatch, tmp_path, settings
):
popen = Mock()
monkeypatch.setattr(genericDriver.subprocess, "Popen", popen)
sound_file = tmp_path / "sound.ogg"
sound_file.write_bytes(b"")
sound_driver = _sound_driver(settings)
sound_driver.play_frequence(
440, 0.25, adjust_volume=0.5, interrupt=False
)
sound_driver.play_sound_file(str(sound_file), interrupt=False)
for call in popen.call_args_list:
assert not any("fenrir_" in argument for argument in call.args[0])
+73
View File
@@ -0,0 +1,73 @@
from configparser import ConfigParser
from pathlib import Path
import pytest
from fenrirscreenreader.core.settingsData import settings_data
from fenrirscreenreader.speechDriver import genericDriver
def test_build_speech_command_replaces_snake_case_placeholders():
speech_driver = genericDriver.driver()
speech_driver.speech_command = (
"synth --volume fenrir_volume --module fenrir_module "
"--language fenrir_language --voice fenrir_voice "
"--pitch fenrir_pitch --rate fenrir_rate fenrir_text"
)
utterance = {
"volume": "150",
"module": "module-name",
"language": "en-US",
"voice": "voice-name",
"pitch": "50",
"rate": "240",
"text": "hello",
}
assert speech_driver._build_speech_command(utterance) == [
"synth",
"--volume",
"150",
"--module",
"module-name",
"--language",
"en-US",
"--voice",
"voice-name",
"--pitch",
"50",
"--rate",
"240",
"hello",
]
def _configured_speech_command():
config = ConfigParser(interpolation=None)
config.read(Path(__file__).parents[2] / "config/settings/settings.conf")
return config.get("speech", "generic_speech_command")
@pytest.mark.parametrize(
"speech_command",
[
settings_data["speech"]["generic_speech_command"],
_configured_speech_command(),
],
)
def test_default_speech_commands_use_supported_placeholders(speech_command):
speech_driver = genericDriver.driver()
speech_driver.speech_command = speech_command
utterance = {
"volume": "150",
"module": "",
"language": "en-US",
"voice": "voice-name",
"pitch": "50",
"rate": "240",
"text": "hello",
}
built_command = speech_driver._build_speech_command(utterance)
assert not any("fenrir_" in argument for argument in built_command)
+57
View File
@@ -70,6 +70,7 @@ def test_pty_stdin_input_interrupts_output_when_all_keys_interrupt_enabled():
"runtime": {
"SettingsManager": settings_manager,
"OutputManager": output_manager,
"DebugManager": Mock(write_debug_out=Mock()),
}
}
@@ -254,6 +255,7 @@ def test_pty_stdin_input_honors_interrupt_disabled():
"runtime": {
"SettingsManager": settings_manager,
"OutputManager": output_manager,
"DebugManager": Mock(write_debug_out=Mock()),
}
}
@@ -273,6 +275,7 @@ def test_pty_stdin_input_leaves_filtered_interrupts_to_key_events():
"runtime": {
"SettingsManager": settings_manager,
"OutputManager": output_manager,
"DebugManager": Mock(write_debug_out=Mock()),
}
}
@@ -281,6 +284,60 @@ def test_pty_stdin_input_leaves_filtered_interrupts_to_key_events():
output_manager.interrupt_output.assert_not_called()
@pytest.mark.unit
def test_pty_recent_review_escape_tail_is_consumed_without_interrupt_or_injection():
pty_driver = PtyDriver()
event_queue = Mock()
settings_manager = Mock()
settings_manager.get_setting_as_bool.return_value = True
settings_manager.get_setting.return_value = ""
output_manager = Mock()
pty_driver.env = {
"commandInfo": {
"lastCommand": "REVIEW_PREV_LINE",
"lastCommandSection": "commands",
"lastCommandRunTime": time.time(),
},
"input": {"curr_input": []},
"runtime": {
"DebugManager": Mock(write_debug_out=Mock()),
"OutputManager": output_manager,
"SettingsManager": settings_manager,
},
}
pty_driver.inject_text_to_screen = Mock()
pty_driver.handle_stdin_input(b"\x1b[7~", event_queue)
output_manager.interrupt_output.assert_not_called()
pty_driver.inject_text_to_screen.assert_not_called()
@pytest.mark.unit
def test_pty_recent_review_does_not_consume_plain_text_input():
pty_driver = PtyDriver()
event_queue = Mock()
settings_manager = Mock()
settings_manager.get_setting_as_bool.return_value = False
pty_driver.env = {
"commandInfo": {
"lastCommand": "REVIEW_PREV_LINE",
"lastCommandSection": "commands",
"lastCommandRunTime": time.time(),
},
"input": {"curr_input": []},
"runtime": {
"DebugManager": Mock(write_debug_out=Mock()),
"SettingsManager": settings_manager,
},
}
pty_driver.inject_text_to_screen = Mock()
pty_driver.handle_stdin_input(b"a", event_queue)
pty_driver.inject_text_to_screen.assert_called_once_with(b"a")
@pytest.mark.unit
def test_pty_backspace_with_fenrir_key_synthesizes_shortcut_events():
pty_driver = PtyDriver()