mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-09 02:15:32 +00:00
306 lines
13 KiB
Python
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()
|