integration test for rows

This commit is contained in:
sezanzeb 2020-11-15 01:35:35 +01:00
parent 14267283f3
commit 1cda8bd943
4 changed files with 91 additions and 5 deletions

View File

@ -39,7 +39,7 @@ sudo python3 setup.py install && python3 tests/test.py
- [x] generate a file for /usr/share/X11/xkb/symbols/ for each preset - [x] generate a file for /usr/share/X11/xkb/symbols/ for each preset
- [x] load that file with `setxkbmap` - [x] load that file with `setxkbmap`
- [x] keep the system defaults for unmapped buttons - [x] keep the system defaults for unmapped buttons
- [ ] highlight changes and alert before discarding unsaved changes - [x] highlight changes and alert before discarding unsaved changes
- [ ] automatically load the preset (on startup?, udev on mouse connect?) - [ ] automatically load the preset (on startup?, udev on mouse connect?)
- [ ] make it work on wayland - [ ] make it work on wayland
- [ ] add to the AUR, provide .deb and .appimage files - [ ] add to the AUR, provide .deb and .appimage files

View File

@ -26,7 +26,6 @@ import gi
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
gi.require_version('GLib', '2.0') gi.require_version('GLib', '2.0')
from gi.repository import Gtk, GLib from gi.repository import Gtk, GLib
import cairo as Cairo
from keymapper.mapping import custom_mapping from keymapper.mapping import custom_mapping
from keymapper.logger import logger from keymapper.logger import logger

View File

@ -118,12 +118,16 @@ class Window:
def check_add_row(self): def check_add_row(self):
"""Ensure that one empty row is available at all times.""" """Ensure that one empty row is available at all times."""
rows = len(self.get('key_list').get_children()) num_rows = len(self.get('key_list').get_children())
# verify that all mappings are displayed # verify that all mappings are displayed
assert rows >= len(custom_mapping) if num_rows < len(custom_mapping):
raise AssertionError(
f'custom_mapping contains {len(custom_mapping)} rows, '
f'but only {num_rows} are displayed'
)
if rows == len(custom_mapping): if num_rows == len(custom_mapping):
self.add_empty() self.add_empty()
return True return True

View File

@ -34,6 +34,7 @@ from gi.repository import Gtk
from keymapper.mapping import custom_mapping from keymapper.mapping import custom_mapping
from keymapper.paths import USERS_SYMBOLS, HOME_PATH, KEYCODES_PATH from keymapper.paths import USERS_SYMBOLS, HOME_PATH, KEYCODES_PATH
from keymapper.linux import keycode_reader
from test import tmp from test import tmp
@ -82,11 +83,17 @@ class Integration(unittest.TestCase):
self.window = launch() self.window = launch()
def tearDown(self): def tearDown(self):
# before calling destroy to break everything (happened with
# check_add_row), make an iteration to clear all pending events.
gtk_iteration()
self.window.on_close() self.window.on_close()
self.window.window.destroy() self.window.window.destroy()
gtk_iteration() gtk_iteration()
shutil.rmtree('/tmp/key-mapper-test') shutil.rmtree('/tmp/key-mapper-test')
def get_rows(self):
return self.window.get('key_list').get_children()
def test_can_start(self): def test_can_start(self):
self.assertIsNotNone(self.window) self.assertIsNotNone(self.window)
self.assertTrue(self.window.window.get_visible()) self.assertTrue(self.window.window.get_visible())
@ -102,6 +109,82 @@ class Integration(unittest.TestCase):
rows = len(self.window.get('key_list').get_children()) rows = len(self.window.get('key_list').get_children())
self.assertEqual(rows, 2) self.assertEqual(rows, 2)
def test_rows(self):
"""Comprehensive test for rows."""
def read():
"""Always return a different keycode for each row."""
# + 7 because keycodes usually start at 8
return len(self.window.get('key_list').get_children()) + 7
def change_empty_row(character):
"""Modify the one empty row that always exists."""
# wait for the window to create a new empty row if needed
time.sleep(0.2)
gtk_iteration()
# find the empty row
rows = self.get_rows()
row = rows[-1]
self.assertNotIn('changed', row.get_style_context().list_classes())
self.assertIsNone(row.keycode.get_label())
self.assertEqual(row.character_input.get_text(), '')
# focus the keycode to trigger reading the fake keycode
self.window.window.set_focus(row.keycode)
time.sleep(0.2)
gtk_iteration()
# it should be filled using the `read` patch
self.assertEqual(int(row.keycode.get_label()), len(rows) + 7)
self.window.window.set_focus(None)
# set the character to make the new row complete
row.character_input.set_text(character)
self.assertIn('changed', row.get_style_context().list_classes())
return row
with patch.object(keycode_reader, 'read', read):
# add two rows by modifiying the one empty row that exists
change_empty_row('a')
change_empty_row('b')
# one empty row added automatically again
time.sleep(0.2)
gtk_iteration()
# sleep one more time because it's funny to watch the ui
# during the test, how rows turn blue and stuff
time.sleep(0.2)
self.assertEqual(len(self.get_rows()), 3)
self.assertEqual(custom_mapping.get(8), 'a')
self.assertEqual(custom_mapping.get(9), 'b')
self.assertTrue(custom_mapping.changed)
self.window.on_save_preset_clicked(None)
for row in self.get_rows():
self.assertNotIn(
'changed',
row.get_style_context().list_classes()
)
self.assertFalse(custom_mapping.changed)
# now change the first row and it should turn blue,
# but the other should remain unhighlighted
row = self.get_rows()[0]
row.character_input.set_text('c')
self.assertIn('changed', row.get_style_context().list_classes())
for row in self.get_rows()[1:]:
self.assertNotIn(
'changed',
row.get_style_context().list_classes()
)
self.assertEqual(custom_mapping.get(8), 'c')
self.assertEqual(custom_mapping.get(9), 'b')
self.assertTrue(custom_mapping.changed)
def test_rename_and_save(self): def test_rename_and_save(self):
custom_mapping.change(None, 14, 'a') custom_mapping.change(None, 14, 'a')
self.assertEqual(self.window.selected_preset, 'new preset') self.assertEqual(self.window.selected_preset, 'new preset')