spiegel-keyman/linux/keyman-config/tests/test_install_kmp.py
2023-01-20 08:58:14 +01:00

306 lines
13 KiB
Python

#!/usr/bin/python3
import os
import tempfile
import unittest
from unittest.mock import patch, ANY
from keyman_config import __version__
from keyman_config.get_kmp import InstallLocation
from keyman_config.install_kmp import InstallError, InstallKmp
class InstallKmpTests(unittest.TestCase):
def setUp(self):
patcher1 = patch('keyman_config.install_kmp.install_to_ibus')
self.mockInstallToIbus = patcher1.start()
self.addCleanup(patcher1.stop)
patcher2 = patch('keyman_config.install_kmp.restart_ibus')
self.mockRestartIbus = patcher2.start()
self.addCleanup(patcher2.stop)
patcher3 = patch('keyman_config.install_kmp.get_ibus_bus')
self.mockGetIbusBus = patcher3.start()
self.addCleanup(patcher3.stop)
patcher4 = patch('keyman_config.install_kmp.GnomeKeyboardsUtil')
self.mockGnomeKeyboardsUtilClass = patcher4.start()
self.addCleanup(patcher4.stop)
patcher5 = patch('keyman_config.install_kmp.get_keyboard_dir')
self.mockGetKeyboardDir = patcher5.start()
self.addCleanup(patcher5.stop)
patcher6 = patch('keyman_config.install_kmp.extract_kmp')
self.mockExtractKmp = patcher6.start()
self.addCleanup(patcher6.stop)
patcher7 = patch('keyman_config.install_kmp.extractico')
self.mockExtractIco = patcher7.start()
self.addCleanup(patcher7.stop)
patcher8 = patch('keyman_config.install_kmp.is_gnome_shell')
self.mockIsGnomeShell = patcher8.start()
self.addCleanup(patcher8.stop)
self.mockIsGnomeShell.return_value = False
patcher9 = patch('keyman_config.install_kmp.is_fcitx_running')
self.mockIsFcitxRunning = patcher9.start()
self.addCleanup(patcher9.stop)
self.mockIsFcitxRunning.return_value = False
def test_InstallKeyboardsToIbus_NoIbus(self):
# Setup
self.mockGetIbusBus.return_value = None
# Execute
InstallKmp()._install_keyboards_to_ibus([], None)
# Verify
self.mockRestartIbus.assert_not_called()
def test_InstallKeyboardsToIbus_SingleKbNoLanguages(self):
# Setup
bus = self.mockGetIbusBus.return_value
keyboards = [{'id': 'foo1'}]
# Execute
InstallKmp()._install_keyboards_to_ibus(keyboards, 'fooDir')
# Verify
self.mockInstallToIbus.assert_called_once_with(ANY, 'fooDir/foo1.kmx')
self.mockRestartIbus.assert_called_once()
bus.destroy.assert_called_once()
def test_InstallKeyboardsToIbus_MultipleKbsNoLanguages(self):
# Setup
bus = self.mockGetIbusBus.return_value
keyboards = [{'id': 'foo1'}, {'id': 'foo2'}]
# Execute
InstallKmp()._install_keyboards_to_ibus(keyboards, 'fooDir')
# Verify
self.mockInstallToIbus.assert_any_call(ANY, 'fooDir/foo1.kmx')
self.mockInstallToIbus.assert_any_call(ANY, 'fooDir/foo2.kmx')
self.mockRestartIbus.assert_called_once()
bus.destroy.assert_called_once()
def test_InstallKeyboardsToIbus_SingleKbSingleLanguage(self):
# Setup
bus = self.mockGetIbusBus.return_value
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}]}]
# Execute
InstallKmp()._install_keyboards_to_ibus(keyboards, 'fooDir')
# Verify
self.mockInstallToIbus.assert_called_once_with(ANY, 'en:fooDir/foo1.kmx')
self.mockRestartIbus.assert_called_once()
bus.destroy.assert_called_once()
def test_InstallKeyboardsToIbus_SingleKbMultipleLanguages(self):
# Setup
bus = self.mockGetIbusBus.return_value
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}]
# Execute
InstallKmp()._install_keyboards_to_ibus(keyboards, 'fooDir')
# Verify
self.mockInstallToIbus.assert_called_once()
self.mockInstallToIbus.assert_called_with(ANY, 'en:fooDir/foo1.kmx')
# self.mockInstallToIbus.assert_not_called_with(ANY, 'fr:fooDir/foo1.kmx')
self.mockRestartIbus.assert_called_once()
bus.destroy.assert_called_once()
def test_InstallKeyboardsToIbus_SingleKbMultipleLanguages_GivenLanguage(self):
# Setup
bus = self.mockGetIbusBus.return_value
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}]
# Execute
InstallKmp()._install_keyboards_to_ibus(keyboards, 'fooDir', 'fr')
# Verify
self.mockInstallToIbus.assert_called_once()
self.mockInstallToIbus.assert_called_with(ANY, 'fr:fooDir/foo1.kmx')
# self.mockInstallToIbus.assert_not_called_with(ANY, 'en:fooDir/foo1.kmx')
self.mockRestartIbus.assert_called_once()
bus.destroy.assert_called_once()
def test_InstallKeyboardsToIbus_SingleKbMultipleLanguages_OtherLanguage(self):
# Setup
bus = self.mockGetIbusBus.return_value
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}]
# Execute
InstallKmp()._install_keyboards_to_ibus(keyboards, 'fooDir', 'de')
# Verify
self.mockInstallToIbus.assert_called_once()
self.mockInstallToIbus.assert_called_with(ANY, 'de:fooDir/foo1.kmx')
# self.mockInstallToIbus.assert_not_called_with(ANY, 'en:fooDir/foo1.kmx')
self.mockRestartIbus.assert_called_once()
bus.destroy.assert_called_once()
def test_InstallKeyboardsToGnome_SingleKbNoLanguages(self):
# Setup
mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [('xkb', 'en')]
keyboards = [{'id': 'foo1'}]
# Execute
InstallKmp()._install_keyboards_to_gnome(keyboards, 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx')])
self.mockRestartIbus.assert_not_called()
def test_InstallKeyboardsToGnome_MultipleKbsNoLanguages(self):
# Setup
mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [('xkb', 'en')]
keyboards = [{'id': 'foo1'}, {'id': 'foo2'}]
# Execute
InstallKmp()._install_keyboards_to_gnome(keyboards, 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')])
self.mockRestartIbus.assert_not_called()
def test_InstallKeyboardsToGnome_SingleKbSingleLanguage(self):
# Setup
mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [('xkb', 'en')]
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}]}]
# Execute
InstallKmp()._install_keyboards_to_gnome(keyboards, 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')])
self.mockRestartIbus.assert_not_called()
def test_InstallKeyboardsToGnome_SingleKbMultipleLanguages(self):
# Setup
mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [('xkb', 'en')]
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}]
# Execute
InstallKmp()._install_keyboards_to_gnome(keyboards, 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')])
self.mockRestartIbus.assert_not_called()
def test_InstallKeyboardsToGnome_SingleKbMultipleLanguages_GivenLanguage(self):
# Setup
mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [('xkb', 'en')]
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}]
# Execute
InstallKmp()._install_keyboards_to_gnome(keyboards, 'fooDir', 'fr')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en'), ('ibus', 'fr:fooDir/foo1.kmx')])
self.mockRestartIbus.assert_not_called()
def test_InstallKeyboardsToGnome_SingleKbMultipleLanguages_OtherLanguage(self):
# Setup
mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [('xkb', 'en')]
keyboards = [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}]
# Execute
InstallKmp()._install_keyboards_to_gnome(keyboards, 'fooDir', 'de')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en'), ('ibus', 'de:fooDir/foo1.kmx')])
self.mockRestartIbus.assert_not_called()
def test_normalizeLanguage(self):
# Setup
languages = [
{'id': 'de'},
{'id': 'esi-Latn'},
{'id': 'dyo'}
]
for testcase in [
{'given': 'de', 'expected': 'de'},
{'given': 'esi', 'expected': 'esi-Latn'},
{'given': 'esi-Latn', 'expected': 'esi-Latn'},
{'given': 'es', 'expected': None},
{'given': 'en', 'expected': None},
{'given': None, 'expected': None},
# #3399
{'given': 'dyo-latn', 'expected': 'dyo-Latn'},
{'given': 'dyo', 'expected': 'dyo-Latn'},
]:
with self.subTest(data=testcase):
# Execute
result = InstallKmp()._normalize_language(languages, testcase['given'])
# Verify
self.assertEqual(result, testcase['expected'])
def test_normalizeLanguage_noLanguages(self):
# Setup
languages = []
# Execute
result = InstallKmp()._normalize_language(languages, 'en')
# Verify
self.assertEqual(result, '')
def _createEmptyKmp(self, workdir):
kmpfile = os.path.join(workdir, 'foo.kmp')
with open(kmpfile, 'w') as file:
file.write('')
return kmpfile
def _createKmpJson(self, packagedir, fileVersionString):
with open(os.path.join(packagedir, 'kmp.json'), 'w') as file:
file.write('''{
"system": {
"keymanDeveloperVersion": "15.0"
''' + fileVersionString + '''
},
"files": [ {
"name": "khmer_angkor.kmx",
"description": "Keyboard Khmer Angkor"
}, {
"name": "kmp.json",
"description": "Package information (JSON)"
} ],
"keyboards": [ {
"name": "Khmer Angkor",
"id": "khmer_angkor",
"version": "1.1",
"languages": [ {
"name": "Central Khmer (Khmer, Cambodia)",
"id": "km"
} ]}
]}''')
def test_InstallKmp_FutureKeymanVersion(self):
# Setup
workdir = tempfile.TemporaryDirectory().name
os.makedirs(workdir)
packagedir = tempfile.TemporaryDirectory().name
os.makedirs(packagedir)
self.mockGetKeyboardDir.return_value = packagedir
kmpfile = self._createEmptyKmp(workdir)
self._createKmpJson(packagedir, ', "fileVersion": "99.0"')
# Execute
with self.assertRaises(InstallError) as context:
InstallKmp()._install_kmp(kmpfile, 'km', InstallLocation.User)
# Verify
self.assertTrue('foo.kmp requires Keyman 99.0 or higher' in context.exception.message)
self.mockInstallToIbus.assert_not_called()
def test_InstallKmp(self):
for testcase in [
{'name': 'PreviousKeymanVersion', 'fileVersion': ', "fileVersion": "7.0"'},
{'name': 'SameKeymanVersion', 'fileVersion': ', "fileVersion": "' + __version__ + '"'},
{'name': 'NoFileVersion', 'fileVersion': ''}
]:
with self.subTest(msg=testcase['name'], data=testcase['fileVersion']):
# Setup
self.mockInstallToIbus.reset_mock()
workdir = tempfile.TemporaryDirectory().name
os.makedirs(workdir)
packagedir = tempfile.TemporaryDirectory().name
os.makedirs(packagedir)
self.mockGetKeyboardDir.return_value = packagedir
kmpfile = self._createEmptyKmp(workdir)
self._createKmpJson(packagedir, testcase['fileVersion'])
# Execute
InstallKmp()._install_kmp(kmpfile, 'km', InstallLocation.User)
# Verify
self.mockInstallToIbus.assert_called_once()
if __name__ == '__main__':
unittest.main()