fix and refactor keyboard unittest

This commit is contained in:
xs5871 2022-07-03 15:31:39 +00:00 committed by Kyle Brown
parent 64d9147615
commit 258e622bb4
2 changed files with 58 additions and 39 deletions

View File

@ -60,6 +60,9 @@ def maybe_make_consumer_key(candidate, code, names):
class KeyAttrDict: class KeyAttrDict:
__cache = {} __cache = {}
def __iter__(self):
return self.__cache.__iter__()
def __setitem__(self, key, value): def __setitem__(self, key, value):
if DEBUG_OUTPUT: if DEBUG_OUTPUT:
print(f'__setitem__ {key}, {value}') print(f'__setitem__ {key}, {value}')

View File

@ -4,7 +4,7 @@ from functools import reduce
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
from kmk.hid import HIDModes from kmk.hid import HIDModes
from kmk.keys import ModifierKey from kmk.keys import KC, ModifierKey
from kmk.kmk_keyboard import KMKKeyboard from kmk.kmk_keyboard import KMKKeyboard
from kmk.scanners import DiodeOrientation from kmk.scanners import DiodeOrientation
from kmk.scanners.digitalio import MatrixScanner from kmk.scanners.digitalio import MatrixScanner
@ -14,6 +14,16 @@ class DigitalInOut(Mock):
value = False value = False
def code2name(code):
for name in KC:
try:
if KC[name].code == code:
return name
except AttributeError:
pass
return code
class KeyboardTest: class KeyboardTest:
def __init__( def __init__(
self, self,
@ -46,15 +56,15 @@ class KeyboardTest:
self.keyboard._init(hid_type=HIDModes.NOOP) self.keyboard._init(hid_type=HIDModes.NOOP)
@patch('kmk.hid.AbstractHID.hid_send') @patch('kmk.hid.AbstractHID.hid_send')
def test(self, testname, key_events, assert_hid_reports, hid_send): def test(self, testname, key_events, assert_reports, hid_send):
if self.debug_enabled: if self.debug_enabled:
print(testname, key_events, assert_hid_reports) print(testname)
hid_send_call_arg_list = [] # setup report recording
hid_send.side_effect = lambda hid_report: hid_send_call_arg_list.append( hid_reports = []
hid_report[1:] hid_send.side_effect = lambda report: hid_reports.append(report[1:])
)
# inject key switch events
for e in key_events: for e in key_events:
if isinstance(e, int): if isinstance(e, int):
starttime_ms = time.time_ns() // 1_000_000 starttime_ms = time.time_ns() // 1_000_000
@ -66,43 +76,49 @@ class KeyboardTest:
self.pins[key_pos].value = is_pressed self.pins[key_pos].value = is_pressed
self.do_main_loop() self.do_main_loop()
if self.debug_enabled: matching = True
for hid_report in hid_send_call_arg_list: for i in range(max(len(hid_reports), len(assert_reports))):
print(hid_report) # prepare the generated report codes
try:
hid_report = hid_reports[i]
except IndexError:
report_mods = None
report_keys = [None]
else:
report_mods = hid_report[0]
report_keys = {code for code in hid_report[2:] if code != 0}
assert len(hid_send_call_arg_list) >= len(assert_hid_reports) # prepare the desired report codes
try:
hid_assert = assert_reports[i]
except IndexError:
assert_mods = None
assert_keys = [None]
else:
assert_mods = 0
assert_keys = set()
for k in hid_assert:
if isinstance(k, ModifierKey):
assert_mods |= k.code
else:
assert_keys.add(k.code)
# accumulate assertion for late evalution, -- makes for a more
# helpfull debug output.
matching = matching and report_mods == assert_mods
matching = matching and report_keys == assert_keys
for i, hid_report in enumerate(
hid_send_call_arg_list[-len(assert_hid_reports) :]
):
hid_report_keys = {code for code in hid_report[2:] if code != 0}
assert_keys = {
k.code for k in assert_hid_reports[i] if not isinstance(k, ModifierKey)
}
if self.debug_enabled: if self.debug_enabled:
report_keys_names = {code2name(c) for c in report_keys}
assert_keys_names = {code2name(c) for c in assert_keys}
print( print(
'assert keys:', f'assert '
hid_report_keys == assert_keys, f'mods: {report_mods} == {assert_mods} '
hid_report_keys, f'keys: {report_keys_names} == {assert_keys_names} '
assert_keys,
) )
assert hid_report_keys == assert_keys
hid_report_modifiers = hid_report[0] assert matching, "reports don't match up"
assert_modifiers = reduce(
lambda mod, all_mods: all_mods | mod,
{k.code for k in assert_hid_reports[i] if isinstance(k, ModifierKey)},
0,
)
if self.debug_enabled:
print(
'assert mods:',
hid_report_modifiers == assert_modifiers,
hid_report_modifiers,
assert_modifiers,
)
assert hid_report_modifiers == assert_modifiers
def do_main_loop(self): def do_main_loop(self):
for i in range(random.randint(5, 50)): self.keyboard._main_loop()
self.keyboard._main_loop() time.sleep(0.002)