input-remapper/tests/unit/test_groups.py

313 lines
9.3 KiB
Python
Raw Normal View History

2020-11-16 14:39:15 +00:00
#!/usr/bin/python3
# -*- coding: utf-8 -*-
2022-01-01 12:00:49 +00:00
# input-remapper - GUI for device specific keyboard mappings
2022-01-01 12:52:33 +00:00
# Copyright (C) 2022 sezanzeb <proxima@sezanzeb.de>
2020-11-16 14:39:15 +00:00
#
2022-01-01 12:00:49 +00:00
# This file is part of input-remapper.
2020-11-16 14:39:15 +00:00
#
2022-01-01 12:00:49 +00:00
# input-remapper is free software: you can redistribute it and/or modify
2020-11-16 14:39:15 +00:00
# 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.
#
2022-01-01 12:00:49 +00:00
# input-remapper is distributed in the hope that it will be useful,
2020-11-16 14:39:15 +00:00
# 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
2022-01-01 12:00:49 +00:00
# along with input-remapper. If not, see <https://www.gnu.org/licenses/>.
2020-11-16 14:39:15 +00:00
import os
2020-11-16 14:39:15 +00:00
import unittest
import json
2020-11-16 14:39:15 +00:00
import evdev
from evdev.ecodes import EV_KEY, KEY_A
2022-01-01 12:00:49 +00:00
from inputremapper.paths import CONFIG_PATH
from inputremapper.groups import (
2021-09-26 10:44:56 +00:00
_FindGroups,
groups,
classify,
GAMEPAD,
MOUSE,
UNKNOWN,
GRAPHICS_TABLET,
TOUCHPAD,
KEYBOARD,
_Group,
)
2021-02-03 18:42:26 +00:00
from tests.test import quick_cleanup, fixtures
2020-11-16 14:39:15 +00:00
class FakePipe:
groups = None
def send(self, groups):
self.groups = groups
2020-11-16 15:30:27 +00:00
2020-11-16 14:39:15 +00:00
class TestGroups(unittest.TestCase):
2021-02-03 18:42:26 +00:00
def tearDown(self):
quick_cleanup()
def test_group(self):
group = _Group(
2021-09-26 10:44:56 +00:00
paths=["/dev/a", "/dev/b", "/dev/c"],
names=["name_bar", "name_a", "name_foo"],
types=[MOUSE, KEYBOARD, UNKNOWN],
2021-09-26 10:44:56 +00:00
key="key",
)
2021-09-26 10:44:56 +00:00
self.assertEqual(group.name, "name_a")
self.assertEqual(group.key, "key")
self.assertEqual(
2021-09-26 10:44:56 +00:00
group.get_preset_path("preset1234"),
os.path.join(CONFIG_PATH, "presets", group.name, "preset1234.json"),
)
def test_find_groups(self):
2020-11-16 15:30:27 +00:00
pipe = FakePipe()
_FindGroups(pipe).run()
self.assertIsInstance(pipe.groups, str)
groups.loads(pipe.groups)
self.maxDiff = None
2021-09-26 10:44:56 +00:00
self.assertEqual(
groups.dumps(),
json.dumps(
[
json.dumps(
{
"paths": [
"/dev/input/event1",
],
"names": ["Foo Device"],
"types": [KEYBOARD],
"key": "Foo Device",
}
),
json.dumps(
{
"paths": [
"/dev/input/event11",
"/dev/input/event10",
"/dev/input/event13",
],
2021-09-29 18:17:45 +00:00
"names": ["Foo Device foo", "Foo Device", "Foo Device"],
2021-09-26 10:44:56 +00:00
"types": [KEYBOARD, MOUSE],
"key": "Foo Device 2",
}
),
json.dumps(
{
"paths": ["/dev/input/event20"],
"names": ["Bar Device"],
"types": [KEYBOARD],
"key": "Bar Device",
}
),
json.dumps(
{
"paths": ["/dev/input/event30"],
"names": ["gamepad"],
"types": [GAMEPAD],
"key": "gamepad",
}
),
json.dumps(
{
"paths": ["/dev/input/event40"],
2022-01-01 12:00:49 +00:00
"names": ["input-remapper Bar Device"],
2021-09-26 10:44:56 +00:00
"types": [KEYBOARD],
2022-01-01 12:00:49 +00:00
"key": "input-remapper Bar Device",
2021-09-26 10:44:56 +00:00
}
),
]
),
)
groups2 = json.dumps(
2022-01-01 12:00:49 +00:00
[group.dumps() for group in groups.filter(include_inputremapper=True)]
2021-09-26 10:44:56 +00:00
)
self.assertEqual(pipe.groups, groups2)
def test_list_group_names(self):
2021-09-26 10:44:56 +00:00
self.assertListEqual(
groups.list_group_names(),
[
"Foo Device",
"Foo Device",
"Bar Device",
"gamepad",
],
)
def test_filter(self):
2022-01-01 12:00:49 +00:00
# by default no input-remapper devices are present
filtered = groups.filter()
keys = [group.key for group in filtered]
2021-09-26 10:44:56 +00:00
self.assertIn("Foo Device 2", keys)
2022-01-01 12:00:49 +00:00
self.assertNotIn("input-remapper Bar Device", keys)
2021-02-03 18:42:26 +00:00
def test_skip_camera(self):
2021-09-26 10:44:56 +00:00
fixtures["/foo/bar"] = {
"name": "camera",
"phys": "abcd1",
"info": evdev.DeviceInfo(1, 2, 3, 4),
"capabilities": {evdev.ecodes.EV_KEY: [evdev.ecodes.KEY_CAMERA]},
2021-02-03 18:42:26 +00:00
}
groups.refresh()
2021-09-26 10:44:56 +00:00
self.assertIsNone(groups.find(name="camera"))
self.assertIsNotNone(groups.find(name="gamepad"))
2021-02-03 18:42:26 +00:00
2021-02-15 22:11:59 +00:00
def test_device_with_only_ev_abs(self):
# could be anything, a lot of devices have ABS_X capabilities,
# so it is not treated as gamepad joystick and since it also
# doesn't have key capabilities, there is nothing to map.
2021-09-26 10:44:56 +00:00
fixtures["/foo/bar"] = {
"name": "qux",
"phys": "abcd2",
"info": evdev.DeviceInfo(1, 2, 3, 4),
"capabilities": {evdev.ecodes.EV_ABS: [evdev.ecodes.ABS_X]},
2021-02-03 18:42:26 +00:00
}
groups.refresh()
2021-09-26 10:44:56 +00:00
self.assertIsNotNone(groups.find(name="gamepad"))
self.assertIsNone(groups.find(name="qux"))
# verify this test even works at all
2021-09-26 10:44:56 +00:00
fixtures["/foo/bar"]["capabilities"][EV_KEY] = [KEY_A]
groups.refresh()
2021-09-26 10:44:56 +00:00
self.assertIsNotNone(groups.find(name="qux"))
def test_duplicate_device(self):
2021-09-26 10:44:56 +00:00
fixtures["/dev/input/event20"]["name"] = "Foo Device"
groups.refresh()
2021-09-26 10:44:56 +00:00
group1 = groups.find(key="Foo Device")
group2 = groups.find(key="Foo Device 2")
group3 = groups.find(key="Foo Device 3")
2021-09-26 10:44:56 +00:00
self.assertIn("/dev/input/event1", group1.paths)
self.assertIn("/dev/input/event10", group2.paths)
self.assertIn("/dev/input/event20", group3.paths)
2021-09-26 10:44:56 +00:00
self.assertEqual(group1.key, "Foo Device")
self.assertEqual(group2.key, "Foo Device 2")
self.assertEqual(group3.key, "Foo Device 3")
2021-09-26 10:44:56 +00:00
self.assertEqual(group1.name, "Foo Device")
self.assertEqual(group2.name, "Foo Device")
self.assertEqual(group3.name, "Foo Device")
2021-02-03 18:42:26 +00:00
2021-03-27 12:21:35 +00:00
def test_classify(self):
# properly detects if the device is a gamepad
EV_ABS = evdev.ecodes.EV_ABS
EV_KEY = evdev.ecodes.EV_KEY
2021-02-15 17:18:36 +00:00
EV_REL = evdev.ecodes.EV_REL
2021-01-17 14:09:47 +00:00
class FakeDevice:
def __init__(self, capabilities):
self.c = capabilities
def capabilities(self, absinfo):
assert not absinfo
return self.c
2021-03-27 12:21:35 +00:00
"""gamepads"""
2021-02-15 22:11:59 +00:00
2021-09-26 10:44:56 +00:00
self.assertEqual(
classify(
FakeDevice(
{
EV_ABS: [evdev.ecodes.ABS_X, evdev.ecodes.ABS_Y],
EV_KEY: [evdev.ecodes.BTN_A],
}
)
),
GAMEPAD,
)
2021-02-15 22:11:59 +00:00
2021-03-27 12:21:35 +00:00
"""mice"""
2021-02-15 22:11:59 +00:00
2021-09-26 10:44:56 +00:00
self.assertEqual(
classify(
FakeDevice(
{
EV_REL: [
evdev.ecodes.REL_X,
evdev.ecodes.REL_Y,
evdev.ecodes.REL_WHEEL,
],
EV_KEY: [evdev.ecodes.BTN_LEFT],
}
)
),
MOUSE,
)
2021-03-27 12:21:35 +00:00
"""keyboard"""
2021-09-26 10:44:56 +00:00
self.assertEqual(classify(FakeDevice({EV_KEY: [evdev.ecodes.KEY_A]})), KEYBOARD)
2021-03-27 12:21:35 +00:00
"""touchpads"""
2021-09-26 10:44:56 +00:00
self.assertEqual(
classify(
FakeDevice(
{
EV_KEY: [evdev.ecodes.KEY_A],
EV_ABS: [evdev.ecodes.ABS_MT_POSITION_X],
}
)
),
TOUCHPAD,
)
2021-03-27 12:21:35 +00:00
2021-04-02 10:16:34 +00:00
"""graphics tablets"""
2021-03-27 12:21:35 +00:00
2021-09-26 10:44:56 +00:00
self.assertEqual(
classify(
FakeDevice(
{
EV_ABS: [evdev.ecodes.ABS_X, evdev.ecodes.ABS_Y],
EV_KEY: [evdev.ecodes.BTN_STYLUS],
}
)
),
GRAPHICS_TABLET,
)
2021-04-02 10:16:34 +00:00
"""weird combos"""
2021-02-15 22:11:59 +00:00
2021-09-26 10:44:56 +00:00
self.assertEqual(
classify(
FakeDevice(
{
EV_ABS: [evdev.ecodes.ABS_X, evdev.ecodes.ABS_Y],
EV_KEY: [evdev.ecodes.KEY_1],
}
)
),
UNKNOWN,
)
2021-02-15 22:11:59 +00:00
2021-09-26 10:44:56 +00:00
self.assertEqual(
classify(
2021-09-29 18:17:45 +00:00
FakeDevice({EV_ABS: [evdev.ecodes.ABS_X], EV_KEY: [evdev.ecodes.BTN_A]})
2021-09-26 10:44:56 +00:00
),
UNKNOWN,
)
2021-02-15 22:11:59 +00:00
2021-09-26 10:44:56 +00:00
self.assertEqual(classify(FakeDevice({EV_KEY: [evdev.ecodes.BTN_A]})), UNKNOWN)
2021-02-15 22:11:59 +00:00
2021-09-26 10:44:56 +00:00
self.assertEqual(classify(FakeDevice({EV_ABS: [evdev.ecodes.ABS_X]})), UNKNOWN)
2020-11-16 14:39:15 +00:00
2021-01-01 21:20:33 +00:00
2020-11-16 14:39:15 +00:00
if __name__ == "__main__":
unittest.main()