import sys import unittest from pathlib import Path from unittest import mock sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from cthulhu import guilabels from cthulhu import settings from cthulhu import settings_manager from cthulhu import speech_and_verbosity_manager from cthulhu import speechdispatcherfactory from cthulhu import speechserver class SpeechDispatcherVoiceSelectionRegressionTests(unittest.TestCase): def test_session_speech_settings_override_profile_reload(self): manager = settings_manager.SettingsManager.__new__( settings_manager.SettingsManager ) manager._session_settings = { "speechServerInfo": ["doubletalk", "doubletalk"], "voices": { settings.DEFAULT_VOICE: { "family": { speechserver.VoiceFamily.NAME: "Perfect Paul", speechserver.VoiceFamily.LANG: "en", speechserver.VoiceFamily.DIALECT: "US", speechserver.VoiceFamily.VARIANT: "none", } } }, } manager.customizedSettings = {} manager._getCustomizedSettings = mock.Mock(return_value={}) manager._logRoleSoundPresentationChange = mock.Mock() saved_settings = { "speechServerInfo": ["rhvoice", "rhvoice"], "voices": { settings.DEFAULT_VOICE: { "family": { speechserver.VoiceFamily.NAME: "Previous Voice", } } }, } with mock.patch.object( settings, "speechServerInfo", saved_settings["speechServerInfo"], ), mock.patch.object(settings, "voices", saved_settings["voices"]): manager._setSettingsRuntime(saved_settings) self.assertEqual( ["doubletalk", "doubletalk"], settings.speechServerInfo, ) self.assertEqual( "Perfect Paul", settings.voices[settings.DEFAULT_VOICE]["family"][ speechserver.VoiceFamily.NAME ], ) def test_quick_module_switch_preserves_module_and_voice_for_session(self): current_module = {"name": "rhvoice"} perfect_paul = speechserver.VoiceFamily( { speechserver.VoiceFamily.NAME: "Perfect Paul", speechserver.VoiceFamily.LANG: "en", speechserver.VoiceFamily.DIALECT: "US", speechserver.VoiceFamily.VARIANT: "none", } ) server = mock.Mock() server.list_output_modules.return_value = ["rhvoice", "doubletalk"] server.getOutputModule.side_effect = lambda: current_module["name"] server.setOutputModule.side_effect = ( lambda module: current_module.update(name=module) ) server.getVoiceFamilies.return_value = [perfect_paul] session_settings = mock.Mock() app = mock.Mock() app.getSettingsManager.return_value = session_settings manager = speech_and_verbosity_manager.SpeechAndVerbosityManager.__new__( speech_and_verbosity_manager.SpeechAndVerbosityManager ) manager.app = app manager._get_server = mock.Mock(return_value=server) manager._present_message = mock.Mock() runtime_voices = { settings.DEFAULT_VOICE: { "family": { speechserver.VoiceFamily.NAME: "Previous Voice", } } } with mock.patch.object(settings, "voices", runtime_voices), \ mock.patch.object( settings, "speechServerInfo", ["rhvoice", "rhvoice"], ): manager._adjust_module(script=None, decrease=False) session_values = { call.args[0]: call.args[1] for call in session_settings.set_session_setting.call_args_list } self.assertEqual( ["doubletalk", "doubletalk"], session_values["speechServerInfo"], ) self.assertEqual( "Perfect Paul", session_values["voices"][settings.DEFAULT_VOICE]["family"][ speechserver.VoiceFamily.NAME ], ) def test_output_module_updates_the_synthetic_default_voice_name(self): server = speechdispatcherfactory.SpeechServer.__new__( speechdispatcherfactory.SpeechServer ) server._client = mock.Mock() server._default_voice_name = guilabels.SPEECH_DEFAULT_VOICE % "default" server._current_voice_properties = { speechdispatcherfactory.ACSS.FAMILY: {"name": "Previous Voice"} } server.setOutputModule("doubletalk") server._client.set_output_module.assert_called_once_with("doubletalk") self.assertEqual( guilabels.SPEECH_DEFAULT_VOICE % "doubletalk", server._default_voice_name, ) self.assertNotIn( speechdispatcherfactory.ACSS.FAMILY, server._current_voice_properties, ) def test_quick_voice_list_prefers_real_doubletalk_voices(self): default_name = guilabels.SPEECH_DEFAULT_VOICE % "doubletalk" voice_names = [ "Perfect Paul", "Vader", "Big Bob", "Precise Pete", "Ricochet", "Biff", "Skip", "Robo Robert", ] voices = [ speechserver.VoiceFamily( { speechserver.VoiceFamily.NAME: default_name, speechserver.VoiceFamily.LANG: "en", speechserver.VoiceFamily.DIALECT: "US", speechserver.VoiceFamily.VARIANT: None, } ), ] voices.extend( speechserver.VoiceFamily( { speechserver.VoiceFamily.NAME: voice_name, speechserver.VoiceFamily.LANG: "en", speechserver.VoiceFamily.DIALECT: "US", speechserver.VoiceFamily.VARIANT: "none", } ) for voice_name in voice_names ) server = mock.Mock() server.getOutputModule.return_value = "doubletalk" server.getVoiceFamilies.return_value = voices manager = speech_and_verbosity_manager.SpeechAndVerbosityManager.__new__( speech_and_verbosity_manager.SpeechAndVerbosityManager ) available = manager._get_available_voices(server) self.assertEqual( voice_names, [voice[speechserver.VoiceFamily.NAME] for voice in available], ) def test_quick_voice_list_keeps_default_when_no_real_voice_exists(self): default_name = guilabels.SPEECH_DEFAULT_VOICE % "generic" default_voice = speechserver.VoiceFamily( { speechserver.VoiceFamily.NAME: default_name, speechserver.VoiceFamily.LANG: "en", } ) server = mock.Mock() server.getOutputModule.return_value = "generic" server.getVoiceFamilies.return_value = [default_voice] manager = speech_and_verbosity_manager.SpeechAndVerbosityManager.__new__( speech_and_verbosity_manager.SpeechAndVerbosityManager ) self.assertEqual([default_voice], manager._get_available_voices(server)) if __name__ == "__main__": unittest.main()