tests: test GESTURES settings

This commit is contained in:
Peter F. Patel-Schneider 2024-03-28 15:18:25 -04:00
parent e64eec18e9
commit d12575b47d
5 changed files with 122 additions and 86 deletions

View File

@ -343,7 +343,6 @@ class ReprogrammableKeyV4(ReprogrammableKey):
class PersistentRemappableAction:
def __init__(self, device, index, cid, actionId, remapped, modifierMask, cidStatus):
print("PRA", index, cid, actionId, remapped, modifierMask, cidStatus)
self._device = device
self.index = index
self._cid = cid
@ -544,7 +543,6 @@ class KeysArrayPersistent(KeysArray):
return self._capabilities
def _query_key(self, index: int):
print("QK", index)
if index < 0 or index >= len(self.keys):
raise IndexError(index)
keydata = self.device.feature_request(FEATURE.PERSISTENT_REMAPPABLE_ACTION, 0x20, index, 0xFF)

View File

@ -1471,7 +1471,7 @@ class ActionSettingRW:
if logger.isEnabledFor(logging.WARNING):
logger.warning("cannot disable %s on %s", self.name, device)
self.deactivate_action()
return True
return data_bytes
class RawXYProcessing:

View File

@ -18,6 +18,7 @@
import errno
import threading
from dataclasses import dataclass
from dataclasses import field
@ -129,6 +130,46 @@ r_mouse_3 = [ # a HID++ 2.0 mouse
Response("444544000000000000000000000000", 0x0510, "0F"), # name - last 3 characters
]
responses_gestures = [ # the commented-out messages are not used by either the setting or other testing
Response("4203410141020400320480148C21A301", 0x0400, "0000"), # items
Response("A302A11EA30A4105822C852DAD2AAD2B", 0x0400, "0008"),
Response("8F408F418F434204AF54912282558264", 0x0400, "0010"),
Response("01000000000000000000000000000000", 0x0400, "0018"),
Response("01000000000000000000000000000000", 0x0410, "000101"), # enable
# Response("02000000000000000000000000000000", 0x0410, "000102"),
# Response("04000000000000000000000000000000", 0x0410, "000104"),
# Response("08000000000000000000000000000000", 0x0410, "000108"),
Response("00000000000000000000000000000000", 0x0410, "000110"),
# Response("20000000000000000000000000000000", 0x0410, "000120"),
# Response("40000000000000000000000000000000", 0x0410, "000140"),
# Response("00000000000000000000000000000000", 0x0410, "000180"),
# Response("00000000000000000000000000000000", 0x0410, "010101"),
# Response("00000000000000000000000000000000", 0x0410, "010102"),
# Response("04000000000000000000000000000000", 0x0410, "010104"),
# Response("00000000000000000000000000000000", 0x0410, "010108"),
Response("6F000000000000000000000000000000", 0x0410, "0001FF"),
Response("04000000000000000000000000000000", 0x0410, "01010F"),
Response("00000000000000000000000000000000", 0x0430, "000101"), # divert
# Response("00000000000000000000000000000000", 0x0430, "000102"),
# Response("00000000000000000000000000000000", 0x0430, "000104"),
# Response("00000000000000000000000000000000", 0x0430, "000108"),
Response("00000000000000000000000000000000", 0x0430, "000110"),
# Response("00000000000000000000000000000000", 0x0430, "000120"),
# Response("00000000000000000000000000000000", 0x0430, "000140"),
# Response("00000000000000000000000000000000", 0x0430, "000180"),
# Response("00000000000000000000000000000000", 0x0430, "010101"),
# Response("00000000000000000000000000000000", 0x0430, "010102"),
Response("00000000000000000000000000000000", 0x0430, "0001FF"),
Response("00000000000000000000000000000000", 0x0430, "010103"),
Response("08000000000000000000000000000000", 0x0450, "01FF"),
Response("08000000000000000000000000000000", 0x0450, "02FF"),
Response("08000000000000000000000000000000", 0x0450, "03FF"),
Response("00040000000000000000000000000000", 0x0450, "04FF"),
Response("5C020000000000000000000000000000", 0x0450, "05FF"),
Response("01000000000000000000000000000000", 0x0460, "00FF"),
Response("01000000000000000000000000000000", 0x0470, "00FF"),
]
# A fake device that uses provided data (responses) to respond to HID++ commands.
# Some methods from the real device are used to set up data structures needed for settings
@ -145,7 +186,8 @@ class Device:
wpid: Optional[str] = "0000"
setting_callback: Any = None
settings = []
sliding = profiles = _backlight = _keys = _remap_keys = _led_effects = None
sliding = profiles = _backlight = _keys = _remap_keys = _led_effects = _gestures = None
_gestures_lock = threading.Lock()
read_register = device.Device.read_register
write_register = device.Device.write_register
@ -153,6 +195,7 @@ class Device:
keys = device.Device.keys
remap_keys = device.Device.remap_keys
led_effects = device.Device.led_effects
gestures = device.Device.gestures
__hash__ = device.Device.__hash__
def __post_init__(self):

View File

@ -340,47 +340,7 @@ def test_KeysArrayPersistent_key(key, expected_index, expected_mapped_to):
assert mapped_to == expected_mapped_to
# TODO SubParam, Gesture, Param, Gestures
responses_gestures = [
hidpp.Response("4203410141020400320480148C21A301", 0x0400, "0000"), # items
hidpp.Response("A302A11EA30A4105822C852DAD2AAD2B", 0x0400, "0008"),
hidpp.Response("8F408F418F434204AF54912282558264", 0x0400, "0010"),
hidpp.Response("01000000000000000000000000000000", 0x0400, "0018"),
hidpp.Response("6F000000000000000000000000000000", 0x0410, "0001FF"), # item 0 enable
hidpp.Response("01000000000000000000000000000000", 0x0410, "000101"),
hidpp.Response("02000000000000000000000000000000", 0x0410, "000102"),
hidpp.Response("04000000000000000000000000000000", 0x0410, "000104"),
hidpp.Response("08000000000000000000000000000000", 0x0410, "000108"),
hidpp.Response("00000000000000000000000000000000", 0x0410, "000110"),
hidpp.Response("20000000000000000000000000000000", 0x0410, "000120"),
hidpp.Response("40000000000000000000000000000000", 0x0410, "000140"),
hidpp.Response("00000000000000000000000000000000", 0x0410, "000180"),
hidpp.Response("00000000000000000000000000000000", 0x0410, "010101"),
hidpp.Response("00000000000000000000000000000000", 0x0410, "010102"),
hidpp.Response("04000000000000000000000000000000", 0x0410, "010104"),
hidpp.Response("00000000000000000000000000000000", 0x0410, "010108"),
hidpp.Response("04000000000000000000000000000000", 0x0410, "01010F"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "000101"), # item 1 divert
hidpp.Response("00000000000000000000000000000000", 0x0430, "000102"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "000104"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "000108"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "000110"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "000120"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "000140"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "000180"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "010101"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "010102"),
hidpp.Response("00000000000000000000000000000000", 0x0430, "0001FF"),
hidpp.Response("08000000000000000000000000000000", 0x0450, "03FF"),
hidpp.Response("08000000000000000000000000000000", 0x0450, "01FF"),
hidpp.Response("08000000000000000000000000000000", 0x0450, "02FF"),
hidpp.Response("5C020000000000000000000000000000", 0x0450, "05FF"),
hidpp.Response("00040000000000000000000000000000", 0x0450, "04FF"),
hidpp.Response("01000000000000000000000000000000", 0x0460, "00FF"),
hidpp.Response("01000000000000000000000000000000", 0x0470, "00FF"),
]
device_gestures = hidpp.Device("GESTURES", responses=responses_gestures, feature=hidpp20_constants.FEATURE.GESTURE_2)
device_gestures = hidpp.Device("GESTURES", responses=hidpp.responses_gestures, feature=hidpp20_constants.FEATURE.GESTURE_2)
def test_Gestures():
@ -397,8 +357,6 @@ def test_Gestures():
assert len(gestures.params) == 1
assert gestures.params[4].value == 256
assert gestures.params[4].default_value == 256
print("SPEC", gestures.specs)
assert len(gestures.specs) == 5
assert gestures.specs[2].value == 8
assert gestures.specs[4].value == 4

View File

@ -31,8 +31,7 @@ from logitech_receiver import special_keys
from . import hidpp
# TODO DpiSlidingXY, MouseGesturesXY, SpeedChange
# TODO Gesture2Gestures, Gesture2Divert, Gesture2Params
# TODO action part of DpiSlidingXY, MouseGesturesXY, SpeedChange
class Setup:
@ -456,6 +455,17 @@ simple_tests = [
hidpp.Response("01", 0x0430), # on
hidpp.Response("00", 0x0440, "00"), # set off
),
Setup(
FeatureTest(settings_templates.SpeedChange, 0, None, 0), # need to set up all settings to successfully write
common.NamedInts(**{"Off": 0, "DPI Change": 0xED}),
hidpp.Response("040001", 0x0000, "2205"), # POINTER_SPEED
hidpp.Response("0100", 0x0400),
hidpp.Response("0120", 0x0410, "0120"),
hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4
hidpp.Response("01", 0x0500),
hidpp.Response("00ED009D310003070500000000000000", 0x0510, "00"), # DPI Change
hidpp.Response("00ED0000000000000000000000000000", 0x0520, "00ED"), # DPI Change current
),
]
@ -471,22 +481,22 @@ def test_simple_template(test, mocker, mock_gethostname):
spy_request = mocker.spy(device, "request")
setting = settings_templates.check_feature(device, tst.sclass)
assert setting
assert setting is not None
if isinstance(setting, list):
setting = setting[0]
value = setting.read(cached=False)
cached_value = setting.read(cached=True)
write_value = setting.write(tst.write_value)
if isinstance(test.choices, common.NamedInts):
assert setting.choices == test.choices
if isinstance(test.choices, list):
assert setting._validator.min_value == test.choices[0]
assert setting._validator.max_value == test.choices[1]
elif test.choices is not None:
assert setting.choices == test.choices
value = setting.read(cached=False)
assert value == tst.initial_value
cached_value = setting.read(cached=True)
assert cached_value == tst.initial_value
write_value = setting.write(tst.write_value) if tst.write_value is not None else None
assert write_value == tst.write_value
for i in range(0 - tst.matched_calls, 0):
@ -529,8 +539,9 @@ key_tests = [
),
Setup(
FeatureTest(settings_templates.DivertKeys, {0xC4: 0}, {0xC4: 2}, 2, offset=0x05),
{common.NamedInt(0xC4, "Smart Shift"): common.NamedInts(Regular=0, Diverted=1, Mouse_Gestures=2)},
{common.NamedInt(0xC4, "Smart Shift"): common.NamedInts(Regular=0, Diverted=1, Mouse_Gestures=2, Sliding_DPI=3)},
*responses_reprog_controls,
hidpp.Response("0A0001", 0x0000, "2201"), # ADJUSTABLE_DPI
hidpp.Response("00C4300000", 0x0530, "00C4300000"), # Smart Shift write
hidpp.Response("00C4030000", 0x0530, "00C4030000"), # Smart Shift divert write
),
@ -554,13 +565,54 @@ key_tests = [
hidpp.Response("0051FF01005100", 0x0440, "0051FF01005100"), # right button set write
),
Setup(
FeatureTest(settings_templates.Equalizer, {0: 0x10, 1: 0x14}, {1: 0x20}, 2),
[16, 32],
hidpp.Response("0220001020", 0x0400),
hidpp.Response("0001000200000000000000", 0x0410, "00"),
hidpp.Response("1014", 0x0420, "00"),
hidpp.Response("1014", 0x0430, "021014"),
hidpp.Response("1020", 0x0430, "021020"),
FeatureTest(
settings_templates.Gesture2Gestures,
{
1: True,
2: True,
30: True,
10: True,
45: False,
42: True,
43: True,
64: False,
65: False,
67: False,
84: True,
34: False,
},
{45: True},
4,
),
*hidpp.responses_gestures,
hidpp.Response("0001FF6F", 0x0420, "0001FF6F"), # write
hidpp.Response("01010F04", 0x0420, "01010F04"),
hidpp.Response("0001FF7F", 0x0420, "0001FF7F"), # write 45
hidpp.Response("01010F04", 0x0420, "01010F04"),
),
Setup(
FeatureTest(
settings_templates.Gesture2Divert,
{1: False, 2: False, 10: False, 44: False, 64: False, 65: False, 67: False, 84: False, 85: False, 100: False},
{44: True},
4,
),
*hidpp.responses_gestures,
hidpp.Response("0001FF00", 0x0440, "0001FF00"), # write
hidpp.Response("01010300", 0x0440, "01010300"),
hidpp.Response("0001FF08", 0x0440, "0001FF08"), # write 44
hidpp.Response("01010300", 0x0440, "01010300"),
),
Setup(
FeatureTest(
settings_templates.Gesture2Params,
{4: {"scale": 256}},
{4: {"scale": 128}},
2,
),
*hidpp.responses_gestures,
hidpp.Response("000100FF000000000000000000000000", 0x0480, "000100FF"),
hidpp.Response("000080FF000000000000000000000000", 0x0480, "000080FF"),
),
Setup(
FeatureTest(settings_templates.Equalizer, {0: -0x20, 1: 0x10}, {1: 0x18}, 2),
@ -650,17 +702,17 @@ def test_key_template(test, mocker):
assert setting is not None
if isinstance(setting, list):
setting = setting[0]
if isinstance(test.choices, dict):
assert setting.choices == test.choices
elif isinstance(test.choices, list):
if isinstance(test.choices, list):
assert setting._validator.min_value == test.choices[0]
assert setting._validator.max_value == test.choices[1]
elif test.choices is not None:
assert setting.choices == test.choices
value = setting.read(cached=False)
assert value == tst.initial_value
wvalue = setting.write(value)
assert wvalue == tst.initial_value
write_value = setting.write(value)
assert write_value == tst.initial_value
for key, value in tst.write_value.items():
write_value = setting.write_key_value(key, value)
@ -673,21 +725,6 @@ def test_key_template(test, mocker):
assert param == test.responses[i].params
failing_tests = [ # needs settings to be set up!!
Setup(
FeatureTest(settings_templates.SpeedChange, 0, 0xED),
common.NamedInts(**{"Off": 0, "DPI Change": 0xED}),
hidpp.Response("040001", 0x0000, "2205"), # POINTER_SPEED
hidpp.Response("0100", 0x0400),
hidpp.Response("0120", 0x0410, "0120"),
hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4
hidpp.Response("01", 0x0500),
hidpp.Response("00ED009D310003070500000000000000", 0x0510, "00"), # DPI Change
hidpp.Response("00ED0000000000000000000000000000", 0x0520, "00ED"), # DPI Change current
),
]
@pytest.mark.parametrize("test", simple_tests + key_tests)
def test_check_feature_settings(test, mocker):
tst = test.test