New hardware synth support added. Untested, so consider this experimental.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
import os
|
||||
import select
|
||||
import time
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from fenrirscreenreader.speechDriver import dectalkDriver
|
||||
from fenrirscreenreader.speechDriver import doubletalkDriver
|
||||
from fenrirscreenreader.speechDriver import litetalkDriver
|
||||
from fenrirscreenreader.speechDriver import tripletalkDriver
|
||||
|
||||
|
||||
def build_environment(device):
|
||||
settings_manager = Mock()
|
||||
settings_manager.get_setting.side_effect = (
|
||||
lambda section, setting: device
|
||||
if (section, setting) == ("speech", "hardware_device")
|
||||
else ""
|
||||
)
|
||||
settings_manager.get_setting_as_int.side_effect = (
|
||||
lambda section, setting: 9600
|
||||
if (section, setting) == ("speech", "hardware_baud_rate")
|
||||
else 0
|
||||
)
|
||||
return {
|
||||
"runtime": {
|
||||
"SettingsManager": settings_manager,
|
||||
"DebugManager": Mock(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def read_available(fd, expected_length, timeout=1.0):
|
||||
deadline = time.monotonic() + timeout
|
||||
data = b""
|
||||
while len(data) < expected_length and time.monotonic() < deadline:
|
||||
readable, _, _ = select.select([fd], [], [], 0.05)
|
||||
if readable:
|
||||
data += os.read(fd, 1024)
|
||||
return data
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def serial_pair():
|
||||
master_fd, slave_fd = os.openpty()
|
||||
try:
|
||||
yield master_fd, os.ttyname(slave_fd)
|
||||
finally:
|
||||
os.close(master_fd)
|
||||
os.close(slave_fd)
|
||||
|
||||
|
||||
def initialized_driver(driver_class, serial_pair):
|
||||
master_fd, slave_name = serial_pair
|
||||
speech_driver = driver_class.driver()
|
||||
speech_driver.initialize(build_environment(slave_name))
|
||||
assert speech_driver._is_initialized
|
||||
return speech_driver, master_fd
|
||||
|
||||
|
||||
def test_dectalk_driver_speaks_printable_text(serial_pair):
|
||||
speech_driver, master_fd = initialized_driver(dectalkDriver, serial_pair)
|
||||
try:
|
||||
speech_driver.speak("Hello\nworld ☃")
|
||||
assert read_available(master_fd, 13) == b"Hello world \x01"
|
||||
finally:
|
||||
speech_driver.shutdown()
|
||||
|
||||
|
||||
def test_dectalk_driver_writes_settings_and_cancel(serial_pair):
|
||||
speech_driver, master_fd = initialized_driver(dectalkDriver, serial_pair)
|
||||
try:
|
||||
speech_driver.set_rate(1.0)
|
||||
speech_driver.set_pitch(0.0)
|
||||
speech_driver.set_volume(0.5)
|
||||
speech_driver.cancel()
|
||||
assert read_available(master_fd, 33) == (
|
||||
b"[:ra 650][:dv ap 50][:vo 50]\x18"
|
||||
)
|
||||
finally:
|
||||
speech_driver.shutdown()
|
||||
|
||||
|
||||
def test_litetalk_driver_speaks_printable_text(serial_pair):
|
||||
speech_driver, master_fd = initialized_driver(litetalkDriver, serial_pair)
|
||||
try:
|
||||
speech_driver.speak("Ready")
|
||||
assert read_available(master_fd, 6) == b"Ready\r"
|
||||
finally:
|
||||
speech_driver.shutdown()
|
||||
|
||||
|
||||
def test_litetalk_driver_writes_settings_and_cancel(serial_pair):
|
||||
speech_driver, master_fd = initialized_driver(litetalkDriver, serial_pair)
|
||||
try:
|
||||
speech_driver.set_rate(1.0)
|
||||
speech_driver.set_pitch(0.0)
|
||||
speech_driver.set_volume(0.5)
|
||||
speech_driver.cancel()
|
||||
assert read_available(master_fd, 9) == b"\x019S\x010P\x014V\x18"
|
||||
finally:
|
||||
speech_driver.shutdown()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("driver_class", [doubletalkDriver, tripletalkDriver])
|
||||
def test_litetalk_compatible_alias_drivers(driver_class, serial_pair):
|
||||
speech_driver, master_fd = initialized_driver(driver_class, serial_pair)
|
||||
try:
|
||||
speech_driver.speak("Alias")
|
||||
speech_driver.set_rate(1.0)
|
||||
assert read_available(master_fd, 10) == b"\x019SAlias\r"
|
||||
finally:
|
||||
speech_driver.shutdown()
|
||||
|
||||
|
||||
def test_hardware_driver_ignores_empty_and_non_string_text(serial_pair):
|
||||
speech_driver, master_fd = initialized_driver(dectalkDriver, serial_pair)
|
||||
try:
|
||||
speech_driver.speak("")
|
||||
speech_driver.speak(None)
|
||||
assert read_available(master_fd, 1, timeout=0.2) == b""
|
||||
finally:
|
||||
speech_driver.shutdown()
|
||||
@@ -71,6 +71,10 @@ class TestSpeechSettingsValidation:
|
||||
# Valid drivers
|
||||
self.manager._validate_setting_value("speech", "driver", "speechdDriver")
|
||||
self.manager._validate_setting_value("speech", "driver", "genericDriver")
|
||||
self.manager._validate_setting_value("speech", "driver", "dectalkDriver")
|
||||
self.manager._validate_setting_value("speech", "driver", "doubletalkDriver")
|
||||
self.manager._validate_setting_value("speech", "driver", "litetalkDriver")
|
||||
self.manager._validate_setting_value("speech", "driver", "tripletalkDriver")
|
||||
self.manager._validate_setting_value("speech", "driver", "dummyDriver")
|
||||
|
||||
# Invalid driver
|
||||
|
||||
Reference in New Issue
Block a user