mirror of
https://github.com/sezanzeb/input-remapper
synced 2024-11-04 12:00:16 +00:00
more tests
This commit is contained in:
parent
070150e49c
commit
bf482cc2bb
@ -44,7 +44,6 @@ window = None
|
||||
|
||||
# TODO check for sudo rights
|
||||
# TODO NUM1 doesnt work anymore
|
||||
# TODO write some tests?
|
||||
|
||||
|
||||
def gtk_iteration():
|
||||
|
@ -39,8 +39,7 @@ from keymapper.paths import get_home_path, get_usr_path, KEYCODES_PATH, \
|
||||
CONFIG_PATH, SYMBOLS_PATH
|
||||
from keymapper.logger import logger
|
||||
from keymapper.data import get_data_path
|
||||
from keymapper.presets import get_presets
|
||||
from keymapper.linux import get_devices, can_grab
|
||||
from keymapper.linux import get_devices
|
||||
|
||||
|
||||
class Mapping:
|
||||
@ -96,7 +95,7 @@ class Mapping:
|
||||
character : string
|
||||
"""
|
||||
if new_keycode and character:
|
||||
self._mapping[new_keycode] = character
|
||||
self._mapping[new_keycode] = str(character)
|
||||
if new_keycode != previous_keycode:
|
||||
# clear previous mapping of that code, because the line
|
||||
# representing that one will now represent a different one.
|
||||
@ -194,7 +193,7 @@ def create_setxkbmap_config(device, preset, mapping):
|
||||
|
||||
logger.info('Writing key mappings')
|
||||
with open(home_preset_path, 'w') as f:
|
||||
contents = generate_symbols_file_content(device, preset, mapping)
|
||||
contents = generate_symbols_content(device, preset, mapping)
|
||||
if contents is not None:
|
||||
f.write(contents)
|
||||
|
||||
@ -260,13 +259,17 @@ def create_identity_mapping():
|
||||
|
||||
if not os.path.exists(KEYCODES_PATH):
|
||||
logger.info('Creating "%s"', KEYCODES_PATH)
|
||||
os.makedirs(os.path.dirname(KEYCODES_PATH), exist_ok=True)
|
||||
os.mknod(KEYCODES_PATH)
|
||||
with open(KEYCODES_PATH, 'w') as keycodes:
|
||||
keycodes.write(result)
|
||||
|
||||
|
||||
def generate_symbols_file_content(device, preset, mapping):
|
||||
def generate_symbols_content(device, preset, mapping):
|
||||
"""Create config contents to be placed in /usr/share/X11/xkb/symbols.
|
||||
|
||||
This file contains the mapping of the preset as expected by X.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
device : string
|
||||
@ -276,15 +279,21 @@ def generate_symbols_file_content(device, preset, mapping):
|
||||
# TODO test this function
|
||||
system_default = 'us' # TODO get the system default
|
||||
|
||||
if len(mapping) == 0:
|
||||
raise ValueError('Mapping is empty')
|
||||
|
||||
# If the symbols file contains key codes that are not present in
|
||||
# the keycodes file, THE WHOLE X SESSION WILL CRASH!
|
||||
if not os.path.exists(KEYCODES_PATH):
|
||||
raise ValueError('Expected the keycodes file to exist.')
|
||||
raise FileNotFoundError('Expected the keycodes file to exist')
|
||||
with open(KEYCODES_PATH, 'r') as f:
|
||||
keycodes = re.findall(r'<.+?>', f.read())
|
||||
|
||||
xkb_symbols = []
|
||||
for keycode, character in mapping:
|
||||
# since the side effect of a broken config is so severe, make
|
||||
# sure to check the presence of the keycode once again even though
|
||||
# their content is always the same (unless modified by a user).
|
||||
if f'<{keycode}>' not in keycodes:
|
||||
logger.error(f'Unknown keycode <{keycode}> for "{character}"')
|
||||
# continue, otherwise X would crash when loading
|
||||
|
@ -28,10 +28,12 @@ Is a module so that tests can modify them.
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
# since this needs to run as sudo,
|
||||
# get the home dir of the user who called sudo.
|
||||
who = subprocess.check_output('who').decode().split()[0]
|
||||
|
||||
# the path in home, is symlinked with SYMBOLS_PATH
|
||||
CONFIG_PATH = os.path.join('/home', who, '.config/key-mapper')
|
||||
|
||||
# should not contain spaces
|
||||
@ -57,6 +59,8 @@ def get_home_path(device, preset=None):
|
||||
def get_usr_path(device, preset=None):
|
||||
"""Get the path to the config file in /usr.
|
||||
|
||||
This folder is a symlink and the files are in ~/.config/key-mapper
|
||||
|
||||
If preset is omitted, returns the folder for the device.
|
||||
"""
|
||||
device = device.strip()
|
||||
|
@ -26,7 +26,8 @@ import os
|
||||
import time
|
||||
import glob
|
||||
|
||||
from keymapper.paths import CONFIG_PATH, get_home_path
|
||||
from keymapper.paths import get_home_path, SYMBOLS_PATH, CONFIG_PATH, \
|
||||
KEYCODES_PATH
|
||||
from keymapper.logger import logger
|
||||
from keymapper.linux import get_devices
|
||||
|
||||
@ -53,17 +54,6 @@ def get_presets(device):
|
||||
return [preset.replace('_', ' ') for preset in presets]
|
||||
|
||||
|
||||
def get_mappings(device, preset):
|
||||
"""Get all configured buttons of the preset.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
device : string
|
||||
preset : string
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def get_any_preset():
|
||||
"""Return the first found tuple of (device, preset)."""
|
||||
devices = get_devices().keys()
|
||||
@ -99,7 +89,7 @@ def find_newest_preset(device=None):
|
||||
)
|
||||
|
||||
if len(paths) == 0:
|
||||
logger.debug('No presets found.')
|
||||
logger.debug('No presets found')
|
||||
return get_any_preset()
|
||||
|
||||
online_devices = [
|
||||
@ -118,7 +108,7 @@ def find_newest_preset(device=None):
|
||||
break
|
||||
|
||||
if newest_path is None:
|
||||
logger.debug('None of the configured devices is currently online.')
|
||||
logger.debug('None of the configured devices is currently online')
|
||||
return get_any_preset()
|
||||
|
||||
# ui: no underscores, filesystem: no whitespaces
|
||||
|
@ -30,6 +30,8 @@ import unittest
|
||||
from keymapper import paths
|
||||
paths.SYMBOLS_PATH = '/tmp/key-mapper-test/symbols'
|
||||
paths.CONFIG_PATH = '/tmp/key-mapper-test/.config'
|
||||
paths.KEYCODES_PATH = '/tmp/key-mapper-test/keycodes'
|
||||
|
||||
|
||||
from keymapper import linux
|
||||
linux._devices = {
|
||||
|
88
tests/testcases/config.py
Normal file
88
tests/testcases/config.py
Normal file
@ -0,0 +1,88 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# key-mapper - GUI for device specific keyboard mappings
|
||||
# Copyright (C) 2020 sezanzeb <proxima@hip70890b.de>
|
||||
#
|
||||
# This file is part of key-mapper.
|
||||
#
|
||||
# key-mapper is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# key-mapper is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with key-mapper. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import shutil
|
||||
|
||||
from keymapper.X import Mapping, generate_symbols_content, \
|
||||
create_identity_mapping, create_setxkbmap_config, get_home_path
|
||||
from keymapper.paths import KEYCODES_PATH, SYMBOLS_PATH, CONFIG_PATH
|
||||
|
||||
from test import tmp
|
||||
|
||||
|
||||
class TestConfig(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.mapping = Mapping()
|
||||
self.mapping.change(None, 10, 'a')
|
||||
self.mapping.change(None, 11, 'NUM1')
|
||||
self.mapping.change(None, 12, 3)
|
||||
if os.path.exists(tmp):
|
||||
shutil.rmtree(tmp)
|
||||
|
||||
def test_create_setxkbmap_config(self):
|
||||
create_setxkbmap_config('device a', 'preset b', self.mapping)
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(
|
||||
CONFIG_PATH,
|
||||
'device_a',
|
||||
'preset_b'
|
||||
)))
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(
|
||||
SYMBOLS_PATH,
|
||||
'device_a',
|
||||
'preset_b'
|
||||
)))
|
||||
|
||||
self.assertTrue(os.path.exists(KEYCODES_PATH))
|
||||
|
||||
with open(get_home_path('device_a', 'preset_b'), 'r') as f:
|
||||
content = f.read()
|
||||
self.assertIn('key <10> { [ a ] };', content)
|
||||
self.assertIn('key <11> { [ NUM1 ] };', content)
|
||||
self.assertIn('key <12> { [ 3 ] };', content)
|
||||
|
||||
def test_generate_content(self):
|
||||
self.assertRaises(
|
||||
FileNotFoundError,
|
||||
generate_symbols_content,
|
||||
'device', 'preset', self.mapping
|
||||
)
|
||||
|
||||
# create the identity mapping, because it is required for
|
||||
# generate_symbols_content
|
||||
create_identity_mapping()
|
||||
self.assertTrue(os.path.exists(KEYCODES_PATH))
|
||||
with open(KEYCODES_PATH, 'r') as f:
|
||||
keycodes = f.read()
|
||||
self.assertIn('<8> = 8;', keycodes)
|
||||
self.assertIn('<255> = 255;', keycodes)
|
||||
|
||||
content = generate_symbols_content('device', 'preset', self.mapping)
|
||||
self.assertIn('key <10> { [ a ] };', content)
|
||||
self.assertIn('key <11> { [ NUM1 ] };', content)
|
||||
self.assertIn('key <12> { [ 3 ] };', content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@ -29,7 +29,7 @@ class TestMapping(unittest.TestCase):
|
||||
self.mapping = Mapping()
|
||||
|
||||
def test_change(self):
|
||||
# 1 is not assigned yet, just add it
|
||||
# 1 is not assigned yet, ignore it
|
||||
self.mapping.change(1, 2, 'a')
|
||||
self.assertIsNone(self.mapping.get(1))
|
||||
self.assertEqual(self.mapping.get(2), 'a')
|
||||
@ -66,6 +66,15 @@ class TestMapping(unittest.TestCase):
|
||||
self.assertIsNone(self.mapping.get(20))
|
||||
self.assertEqual(self.mapping.get(30), 'NUM3')
|
||||
|
||||
def test_iterate_and_convert(self):
|
||||
self.mapping.change(None, 10, 1)
|
||||
self.mapping.change(None, 20, 2)
|
||||
self.mapping.change(None, 30, 3)
|
||||
self.assertListEqual(
|
||||
list(self.mapping),
|
||||
[(10, '1'), (20, '2'), (30, '3')]
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user