Fixed autocompletion tests; Group devices using their `uniq` property (#818)

* using uniq in the group key, fixed autocompletion tests
pull/841/head
Tobi 5 months ago committed by GitHub
parent d55c6d4eeb
commit 8f79c25bd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -221,8 +221,6 @@ def get_unique_key(device: InputDevice):
# - device.phys is empty sometimes and varies across virtual
# subdevices
# - device.version varies across subdevices
# - device.uniq is empty most of the time, I don't know what this is
# supposed to be
return (
# device.info bustype, vendor and product are unique for
# a product, but multiple similar device models would be grouped
@ -230,6 +228,9 @@ def get_unique_key(device: InputDevice):
f"{device.info.bustype}_"
f"{device.info.vendor}_"
f"{device.info.product}_"
# device.uniq is empty most of the time. It seems to be the only way to
# distinguish multiple connected bluetooth gamepads
f"{device.uniq}_"
# deivce.phys if "/input..." is removed from it, because the first
# chunk seems to be unique per hardware (if it's not completely empty)
f'{device.phys.split("/")[0] or "-"}'

@ -75,6 +75,7 @@ def get_incomplete_function_name(iter_: Gtk.TextIter) -> str:
# bar(KEY_A,\nfoo
# foo
match = re.match(rf"(?:{FUNCTION_CHAIN}|{PARAMETER}|^)(\w+)$", left_text)
logger.debug('get_incomplete_function_name text: "%s" match: %s', left_text, match)
if match is None:
return ""

@ -420,14 +420,15 @@ class CodeEditor:
# actually looking at the snapshot preview! In glades editor this didn't have an
# effect.
self.gui.set_resize_mode(Gtk.ResizeMode.IMMEDIATE)
# Syntax Highlighting
# TODO there are some similarities with python, but overall it's quite useless.
# commented out until there is proper highlighting for input-remappers syntax.
# Thanks to https://github.com/wolfthefallen/py-GtkSourceCompletion-example
# language_manager = GtkSource.LanguageManager()
# fun fact: without saving LanguageManager into its own variable it doesn't work
# python = language_manager.get_language("python")
# source_view.get_buffer().set_language(python)
# TODO there are some similarities with python, but overall it's quite useless.
# commented out until there is proper highlighting for input-remappers syntax.
self._update_placeholder()

@ -27,7 +27,8 @@ Automated tests
---------------
```bash
pip install coverage --user # https://github.com/nedbat/coveragepy
pip install coverage psutil --user # https://github.com/nedbat/coveragepy, https://github.com/giampaolo/psutil
export PATH="$PATH:$HOME/.local/bin"
sudo pkill -f input-remapper
sudo pip install . && coverage run tests/test.py
coverage combine && coverage report -m

@ -21,15 +21,18 @@
import asyncio
# the tests file needs to be imported first to make sure patches are loaded
from tests.test import get_project_root
from contextlib import contextmanager
from typing import Tuple, List, Optional, Iterable
from inputremapper.gui.autocompletion import get_incomplete_parameter, _get_left_text
from inputremapper.gui.autocompletion import (
get_incomplete_parameter,
get_incomplete_function_name,
)
from inputremapper.injection.global_uinputs import global_uinputs
from tests.lib.global_uinputs import reset_global_uinputs_for_service
from tests.test import get_project_root
from tests.lib.cleanup import cleanup, quick_cleanup
from tests.lib.cleanup import cleanup
from tests.lib.stuff import spy
from tests.lib.constants import EVENT_READ_TIMEOUT
from tests.lib.fixtures import prepare_presets
@ -78,7 +81,11 @@ from inputremapper.gui.messages.message_broker import (
MessageType,
)
from inputremapper.gui.messages.message_data import StatusData, CombinationRecorded
from inputremapper.gui.components.editor import MappingSelectionLabel, SET_KEY_FIRST
from inputremapper.gui.components.editor import (
MappingSelectionLabel,
SET_KEY_FIRST,
CodeEditor,
)
from inputremapper.gui.components.device_groups import DeviceGroupEntry
from inputremapper.gui.controller import Controller
from inputremapper.gui.reader_service import ReaderService
@ -162,6 +169,7 @@ def patch_launch():
def clean_up_integration(test):
logger.info("clean_up_integration")
test.controller.stop_injecting()
gtk_iteration()
test.user_interface.on_gtk_close()
@ -400,6 +408,17 @@ class GuiTestBase(unittest.TestCase):
self.throttle(20)
def focus_source_view(self):
# despite the focus and gtk_iterations, gtk never runs the event handlers for
# the focus-in-event (_update_placeholder), which would clear the placeholder
# text. Remove it manually, it can't be helped. Fun fact: when the
# window gets destroyed, gtk runs the handler 10 times for good measure.
# Lost one hour of my life on GTK again. It's gone! Forever! Use qt next time.
source_view = self.code_editor
self.set_focus(source_view)
self.code_editor.get_buffer().set_text("")
return source_view
def get_selection_labels(self) -> List[MappingSelectionLabel]:
return self.selection_label_listbox.get_children()
@ -2003,7 +2022,9 @@ class TestGui(GuiTestBase):
)
self.throttle(100) # give time for the input to arrive
self.assertEqual(self.get_unfiltered_symbol_input_text(), "")
self.assertEqual(
self.get_unfiltered_symbol_input_text(), CodeEditor.placeholder
)
self.assertTrue(self.output_box.get_sensitive())
# disable it by deleting the mapping
@ -2041,11 +2062,28 @@ class TestAutocompletion(GuiTestBase):
test("foo", "foo")
test("bar + foo", "foo")
def test_get_incomplete_function_name(self):
def test(text, expected):
text_view = Gtk.TextView()
Gtk.TextView.do_insert_at_cursor(text_view, text)
text_iter = text_view.get_iter_at_location(0, 0)[1]
text_iter.set_offset(len(text))
self.assertEqual(get_incomplete_function_name(text_iter), expected)
test("bar().foo", "foo")
test("bar()\n.foo", "foo")
test("bar().\nfoo", "foo")
test("bar(\nfoo", "foo")
test("bar(\nqux=foo", "foo")
test("bar(KEY_A,\nfoo", "foo")
test("foo", "foo")
def test_autocomplete_names(self):
autocompletion = self.user_interface.autocompletion
def setup(text):
self.set_focus(self.code_editor)
self.code_editor.get_buffer().set_text("")
Gtk.TextView.do_insert_at_cursor(self.code_editor, text)
self.throttle(200)
text_iter = self.code_editor.get_iter_at_location(0, 0)[1]
@ -2064,6 +2102,7 @@ class TestAutocompletion(GuiTestBase):
gtk_iteration()
self.set_focus(self.code_editor)
self.code_editor.get_buffer().set_text("")
complete_key_name = "Test_Foo_Bar"
@ -2111,8 +2150,7 @@ class TestAutocompletion(GuiTestBase):
self.controller.update_mapping(output_symbol="")
gtk_iteration()
source_view = self.code_editor
self.set_focus(source_view)
source_view = self.focus_source_view()
incomplete = "key(KEY_A).\nepea"
Gtk.TextView.do_insert_at_cursor(source_view, incomplete)
@ -2134,8 +2172,7 @@ class TestAutocompletion(GuiTestBase):
self.controller.update_mapping(output_symbol="")
gtk_iteration()
source_view = self.code_editor
self.set_focus(source_view)
source_view = self.focus_source_view()
Gtk.TextView.do_insert_at_cursor(source_view, "KEY_")
@ -2156,8 +2193,7 @@ class TestAutocompletion(GuiTestBase):
def test_writing_still_works(self):
self.controller.update_mapping(output_symbol="")
gtk_iteration()
source_view = self.code_editor
self.set_focus(source_view)
source_view = self.focus_source_view()
Gtk.TextView.do_insert_at_cursor(source_view, "KEY_")
@ -2186,8 +2222,7 @@ class TestAutocompletion(GuiTestBase):
def test_cycling(self):
self.controller.update_mapping(output_symbol="")
gtk_iteration()
source_view = self.code_editor
self.set_focus(source_view)
source_view = self.focus_source_view()
Gtk.TextView.do_insert_at_cursor(source_view, "KEY_")

@ -47,6 +47,9 @@ class Fixture:
phys: str = "unset"
group_key: Optional[str] = None
# uniq is typically empty
uniq: str = ""
def __hash__(self):
return hash(self.path)

@ -74,6 +74,7 @@ class InputDevice:
self.phys = self._fixture.phys
self.info = self._fixture.info
self.name = self._fixture.name
self.uniq = self._fixture.uniq
# this property exists only for test purposes and is not part of
# the original evdev.InputDevice class

Loading…
Cancel
Save