95 lines
3.8 KiB
Python
95 lines
3.8 KiB
Python
import sys
|
|
import time
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
|
|
from cthulhu import speechdispatcherfactory
|
|
import speechd
|
|
|
|
|
|
class SpeechDispatcherInterruptRegressionTests(unittest.TestCase):
|
|
def _make_server(self):
|
|
server = speechdispatcherfactory.SpeechServer.__new__(speechdispatcherfactory.SpeechServer)
|
|
server._lastKeyEchoTime = None
|
|
server._cancel = mock.Mock()
|
|
server._apply_acss = mock.Mock()
|
|
server._send_command = mock.Mock()
|
|
server._speak = mock.Mock()
|
|
server._client = mock.Mock()
|
|
server._client.char = mock.Mock()
|
|
return server
|
|
|
|
def test_interrupting_string_speech_cancels_active_output_first(self):
|
|
server = self._make_server()
|
|
|
|
server.speak("long utterance", interrupt=True)
|
|
|
|
server._cancel.assert_called_once_with()
|
|
server._speak.assert_called_once_with("long utterance", None)
|
|
|
|
def test_recent_key_echo_suppresses_backend_cancel(self):
|
|
server = self._make_server()
|
|
server._lastKeyEchoTime = time.time()
|
|
|
|
server.speak("next", interrupt=True)
|
|
|
|
server._cancel.assert_not_called()
|
|
server._speak.assert_called_once_with("next", None)
|
|
|
|
def test_send_command_logs_and_recovers_from_command_errors(self):
|
|
server = self._make_server()
|
|
server.reset = mock.Mock()
|
|
command = mock.Mock(
|
|
side_effect=[
|
|
speechd.SSIPCommandError(500, "bad ssml", "bad ssml"),
|
|
"recovered",
|
|
]
|
|
)
|
|
|
|
with mock.patch.object(speechdispatcherfactory.debug, "printMessage") as print_message:
|
|
result = speechdispatcherfactory.SpeechServer._send_command(server, command, "payload")
|
|
|
|
self.assertEqual("recovered", result)
|
|
server.reset.assert_called_once_with()
|
|
self.assertEqual(2, command.call_count)
|
|
logged_messages = [call.args[1] for call in print_message.call_args_list]
|
|
self.assertTrue(any("SSIPCommandError" in message for message in logged_messages))
|
|
|
|
def test_debug_sd_values_logs_when_backend_state_queries_return_none(self):
|
|
server = self._make_server()
|
|
server._current_voice_properties = {}
|
|
server._id = "default"
|
|
server.reset = mock.Mock()
|
|
server._send_command = speechdispatcherfactory.SpeechServer._send_command.__get__(
|
|
server, speechdispatcherfactory.SpeechServer
|
|
)
|
|
|
|
fake_app = mock.Mock()
|
|
fake_app.settingsManager.getSetting.return_value = speechdispatcherfactory.settings.PUNCTUATION_STYLE_MOST
|
|
fake_script = mock.Mock()
|
|
fake_script.utilities.adjustForDigits.side_effect = lambda text: text
|
|
fake_state = mock.Mock(activeScript=fake_script)
|
|
|
|
server._client.get_rate.return_value = None
|
|
server._client.get_pitch.return_value = None
|
|
server._client.get_volume.return_value = None
|
|
server._client.get_language.return_value = None
|
|
|
|
with mock.patch.object(speechdispatcherfactory, "cthulhu") as fake_cthulhu, \
|
|
mock.patch.object(speechdispatcherfactory, "cthulhu_state", fake_state), \
|
|
mock.patch.object(speechdispatcherfactory.debug, "debugLevel", speechdispatcherfactory.debug.LEVEL_INFO), \
|
|
mock.patch.object(speechdispatcherfactory.debug, "printMessage") as print_message:
|
|
fake_cthulhu.cthulhuApp = fake_app
|
|
speechdispatcherfactory.SpeechServer._debug_sd_values(server, "prefix")
|
|
|
|
logged_messages = [str(call.args[1]) for call in print_message.call_args_list]
|
|
self.assertTrue(any("returned None" in message for message in logged_messages))
|
|
self.assertEqual(4, server.reset.call_count)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|