tests: expand tests for settings_templates

This commit is contained in:
Peter F. Patel-Schneider 2024-03-24 06:56:21 -04:00
parent 4fd75a64ff
commit a5f1dd09a2
2 changed files with 140 additions and 33 deletions

View File

@ -125,6 +125,8 @@ r_mouse_3 = [ # a HID++ 2.0 mouse
] ]
# 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
@dataclass @dataclass
class Device: class Device:
name: str = "TESTD" name: str = "TESTD"
@ -134,9 +136,16 @@ class Device:
responses: Any = field(default_factory=list) responses: Any = field(default_factory=list)
feature: Optional[int] = None feature: Optional[int] = None
features: Any = None features: Any = None
_backlight: Any = None setting_callback: Any = None
_keys: Any = None _backlight = None
setting_callback = None _keys = None
_remap_keys = None
read_register = device.Device.read_register
write_register = device.Device.write_register
backlight = device.Device.backlight
keys = device.Device.keys
remap_keys = device.Device.remap_keys
def __post_init__(self): def __post_init__(self):
self.features = hidpp20.FeaturesArray(self) self.features = hidpp20.FeaturesArray(self)
@ -152,13 +161,8 @@ class Device:
for r in self.responses: for r in self.responses:
if id == r.id and params == bytes.fromhex(r.params): if id == r.id and params == bytes.fromhex(r.params):
print("RESPONSE", self.name, hex(r.id), r.params, r.response) print("RESPONSE", self.name, hex(r.id), r.params, r.response)
return bytes.fromhex(r.response) if r.response is not None else None return bytes.fromhex(r.response) if isinstance(r.response, str) else r.response
def feature_request(self, feature, function=0x00, *params, no_reply=False): def feature_request(self, feature, function=0x00, *params, no_reply=False):
if self.protocol >= 2.0: if self.protocol >= 2.0:
return hidpp20.feature_request(self, feature, function, *params, no_reply=no_reply) return hidpp20.feature_request(self, feature, function, *params, no_reply=no_reply)
read_register = device.Device.read_register
write_register = device.Device.write_register
backlight = device.Device.backlight
keys = device.Device.keys

View File

@ -14,6 +14,10 @@
## with this program; if not, write to the Free Software Foundation, Inc., ## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""The tests work by creating a faked device (from the hidpp module) that uses provided data as responses to HID++ commands.
The device uses some methods from the real device to set up data structures that are needed for some tests.
"""
from dataclasses import dataclass from dataclasses import dataclass
from struct import pack from struct import pack
from typing import Any from typing import Any
@ -24,13 +28,14 @@ import pytest
from logitech_receiver import common from logitech_receiver import common
from logitech_receiver import hidpp20 from logitech_receiver import hidpp20
from logitech_receiver import settings_templates from logitech_receiver import settings_templates
from logitech_receiver import special_keys
from solaar import configuration from solaar import configuration
from . import hidpp from . import hidpp
# TODO hard MouseGesturesXY, SpeedChange, Gesture2Gestures, Gesture2Divert, Gesture2Params, # TODO DpiSlidingXY, MouseGesturesXY, SpeedChange
# TODO hard PersistentRemappableAction, LEDControl, LEDZoneSetting, # TODO Gesture2Gestures, Gesture2Divert, Gesture2Params, MKeyLEDs, Equalizer, LEDZoneSetting
# TODO DisableKeyboardKeys, Multiplatform, DualPlatform, ChangeHost, MKeyLEDs, MRKeyLED, SideTone, Equalized, ADCPower # TODO future RGB..., RGB..., BrightnessControl
@dataclass @dataclass
@ -149,6 +154,12 @@ tests = [
hidpp.Response("011830000000200040006000", 0x0400), hidpp.Response("011830000000200040006000", 0x0400),
hidpp.Response("0118FF00200040001000", 0x0410, "0118FF00200040001000"), hidpp.Response("0118FF00200040001000", 0x0410, "0118FF00200040001000"),
], ],
[
FeatureTest(settings_templates.Backlight3, 0x50, 0x70, 0x20, "007009"),
hidpp.Response("040001", 0x0000, "1983"), # BACKLIGHT3
hidpp.Response("50", 0x0410),
hidpp.Response("70", 0x0420, "007009"),
],
[ [
FeatureTest(settings_templates.HiResScroll, True, False, 0x10, "00"), FeatureTest(settings_templates.HiResScroll, True, False, 0x10, "00"),
hidpp.Response("040001", 0x0000, "2120"), # HI_RES_SCROLLING hidpp.Response("040001", 0x0000, "2120"), # HI_RES_SCROLLING
@ -238,6 +249,42 @@ tests = [
hidpp.Response("0005", 0x0410), hidpp.Response("0005", 0x0410),
hidpp.Response("00FF", 0x0420, "00FF"), hidpp.Response("00FF", 0x0420, "00FF"),
], ],
[
FeatureTest(settings_templates.DisableKeyboardKeys, {1: True, 8: True}, {1: False, 8: True}, 0x20, "08"),
hidpp.Response("040003", 0x0000, "4521"), # KEYBOARD_DISABLE_KEYS
hidpp.Response("09", 0x0400),
hidpp.Response("09", 0x0410),
hidpp.Response("08", 0x0420, "08"),
],
[
FeatureTest(settings_templates.DualPlatform, 0, 1, 0x20, "01"),
hidpp.Response("040003", 0x0000, "4530"), # DUALPLATFORM
hidpp.Response("00", 0x0400),
hidpp.Response("01", 0x0420, "01"),
],
[
FeatureTest(settings_templates.MRKeyLED, False, True, 0x00, "01"),
hidpp.Response("040003", 0x0000, "8030"), # MR
hidpp.Response("01", 0x0400, "01"),
],
[
FeatureTest(settings_templates.Sidetone, 5, 0xA, 0x10, "0A"),
hidpp.Response("040003", 0x0000, "8300"), # SIDETONE
hidpp.Response("05", 0x0400),
hidpp.Response("0A", 0x0410, "0A"),
],
[
FeatureTest(settings_templates.ADCPower, 5, 0xA, 0x20, "0A"),
hidpp.Response("040003", 0x0000, "1F20"), # ADC_MEASUREMENT
hidpp.Response("05", 0x0410),
hidpp.Response("0A", 0x0420, "0A"),
],
[
FeatureTest(settings_templates.LEDControl, 0, 1, 0x80, "01"),
hidpp.Response("040003", 0x0000, "8070"), # COLOR_LED_EFFECTS
hidpp.Response("00", 0x0470),
hidpp.Response("01", 0x0480, "01"),
],
] ]
@ -263,6 +310,11 @@ def test_simple_template(test, mocker):
spy_feature_request.assert_called_with(test[0].sclass.feature, test[0].write_fnid, params, **no_reply) spy_feature_request.assert_called_with(test[0].sclass.feature, test[0].write_fnid, params, **no_reply)
@pytest.fixture
def mock_gethostname(mocker):
mocker.patch("socket.gethostname", return_value="ABCDEF.foo.org")
tests = [ tests = [
[ [
FeatureTest(settings_templates.Backlight2, 0xFF, 0x00, 0x10, "0102ff00000000000000", None), FeatureTest(settings_templates.Backlight2, 0xFF, 0x00, 0x10, "0102ff00000000000000", None),
@ -369,11 +421,35 @@ tests = [
# hidpp.Response("000064", 0x0950), # hidpp.Response("000064", 0x0950),
# hidpp.Response("0001640164", 0x0960, "0001640164"), # hidpp.Response("0001640164", 0x0960, "0001640164"),
# ], # ],
[
FeatureTest(settings_templates.Multiplatform, 0, 1, 0x30, "FF01"),
common.NamedInts(**{"MacOS 0.1-0.5": 0, "iOS 0.1-0.7": 1, "Linux 0.2-0.9": 2, "Windows 0.3-0.9": 3}),
hidpp.Response("040003", 0x0000, "4531"), # MULTIPLATFORM
hidpp.Response("020004000001", 0x0400),
hidpp.Response("00FF200000010005", 0x0410, "00"),
hidpp.Response("01FF400000010007", 0x0410, "01"),
hidpp.Response("02FF040000020009", 0x0410, "02"),
hidpp.Response("03FF010000030009", 0x0410, "03"),
hidpp.Response("FF01", 0x0430, "FF01"),
],
[
FeatureTest(settings_templates.ChangeHost, 1, 0, 0x10, "00", True),
common.NamedInts(**{"1:ABCDEF": 0, "2:GHIJKL": 1}),
hidpp.Response("040003", 0x0000, "1814"), # CHANGE_HOST
hidpp.Response("050003", 0x0000, "1815"), # HOSTS_INFO
hidpp.Response("01000200", 0x0500),
hidpp.Response("000100000600", 0x0510, "00"),
hidpp.Response("000041424344454600", 0x0530, "0000"),
hidpp.Response("000100000600", 0x0510, "01"),
hidpp.Response("00004748494A4B4C00", 0x0530, "0100"),
hidpp.Response("0201", 0x0400),
hidpp.Response(True, 0x0410, "00"),
],
] ]
@pytest.mark.parametrize("test", tests) @pytest.mark.parametrize("test", tests)
def test_variable_template(test, mocker): def test_variable_template(test, mocker, mock_gethostname):
setup_responses = [hidpp.Response("010001", 0x0000, "0001"), hidpp.Response("20", 0x0100)] setup_responses = [hidpp.Response("010001", 0x0000, "0001"), hidpp.Response("20", 0x0100)]
device = hidpp.Device(responses=test[2:] + setup_responses) device = hidpp.Device(responses=test[2:] + setup_responses)
device.persister = configuration._DeviceEntry() device.persister = configuration._DeviceEntry()
@ -381,7 +457,10 @@ def test_variable_template(test, mocker):
spy_feature_request = mocker.spy(device, "feature_request") spy_feature_request = mocker.spy(device, "feature_request")
setting = settings_templates.check_feature(device, test[0].sclass) setting = settings_templates.check_feature(device, test[0].sclass)
print("CH", setting)
print("CH", setting.choices)
value = setting.read(cached=False) value = setting.read(cached=False)
print("CV", value)
cached_value = setting.read(cached=True) cached_value = setting.read(cached=True)
write_value = setting.write(test[0].write_value) write_value = setting.write(test[0].write_value)
@ -393,6 +472,7 @@ def test_variable_template(test, mocker):
if isinstance(test[1], list): if isinstance(test[1], list):
assert setting._validator.min_value == test[1][0] assert setting._validator.min_value == test[1][0]
assert setting._validator.max_value == test[1][1] assert setting._validator.max_value == test[1][1]
print("VALYE", value, test[0].initial_value)
assert value == test[0].initial_value assert value == test[0].initial_value
assert cached_value == test[0].initial_value assert cached_value == test[0].initial_value
assert write_value == test[0].write_value assert write_value == test[0].write_value
@ -402,6 +482,30 @@ def test_variable_template(test, mocker):
spy_feature_request.assert_called_with(test[0].sclass.feature, test[0].write_fnid, params, **no_reply) spy_feature_request.assert_called_with(test[0].sclass.feature, test[0].write_fnid, params, **no_reply)
responses_reprog_controls = [
hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4
hidpp.Response("03", 0x0500),
hidpp.Response("00500038010001010400000000000000", 0x0510, "00"), # left button
hidpp.Response("00510039010001010400000000000000", 0x0510, "01"), # right button
hidpp.Response("00C4009D310003070500000000000000", 0x0510, "02"), # smart shift
hidpp.Response("00500000000000000000000000000000", 0x0520, "0050"), # left button current
hidpp.Response("00510000500000000000000000000000", 0x0520, "0051"), # right button current
hidpp.Response("00C40000000000000000000000000000", 0x0520, "00C4"), # smart shift current
hidpp.Response("0051000051", 0x0530, "0051000051"), # right button set
]
responses_remappable_action = responses_reprog_controls + [
hidpp.Response("040001", 0x0000, "1C00"), # PERSISTENT_REMAPPABLE_ACTION
hidpp.Response("0041", 0x0400),
hidpp.Response("0201", 0x0410),
hidpp.Response("02", 0x0400),
hidpp.Response("0050", 0x0420, "00FF"), # left button
hidpp.Response("0051", 0x0420, "01FF"), # right button
hidpp.Response("0050000100500000", 0x0430, "0050FF"), # left button current
hidpp.Response("0051000100500001", 0x0430, "0051FF"), # right button current
hidpp.Response("0051FF01005100", 0x0440, "0051FF01005100"), # right button set
]
tests = [ tests = [
[ [
FeatureTest( FeatureTest(
@ -412,29 +516,28 @@ tests = [
common.NamedInt(0x51, "Right Button"): [0x51, 0x50], common.NamedInt(0x51, "Right Button"): [0x51, 0x50],
common.NamedInt(0xC4, "Smart Shift"): [0xC4, 0x50, 0x51], common.NamedInt(0xC4, "Smart Shift"): [0xC4, 0x50, 0x51],
}, },
hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4 ]
hidpp.Response("03", 0x0500), + responses_reprog_controls,
hidpp.Response("00500038010001010400000000000000", 0x0510, "00"), # left button
hidpp.Response("00510039010001010400000000000000", 0x0510, "01"), # right button
hidpp.Response("00C4009D310003070500000000000000", 0x0510, "02"), # smart shift
hidpp.Response("00500000000000000000000000000000", 0x0520, "0050"), # left button current
hidpp.Response("00510000500000000000000000000000", 0x0520, "0051"), # right button current
hidpp.Response("00C40000000000000000000000000000", 0x0520, "00C4"), # smart shift current
hidpp.Response("0051000051", 0x0530, "0051000051"),
],
[ [
FeatureTest(settings_templates.DivertKeys, {0xC4: 0}, {0xC4: 1}, 0x30, "00C4030000"), FeatureTest(settings_templates.DivertKeys, {0xC4: 0}, {0xC4: 1}, 0x30, "00C4030000"),
{common.NamedInt(0xC4, "Smart Shift"): [0, 1, 2]}, {common.NamedInt(0xC4, "Smart Shift"): [0, 1, 2]},
hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4 ]
hidpp.Response("03", 0x0500), + responses_reprog_controls
hidpp.Response("00500038010001010400000000000000", 0x0510, "00"), # left button + [hidpp.Response("00C4030000", 0x0530, "00C4030000")],
hidpp.Response("00510039010001010400000000000000", 0x0510, "01"), # right button [
hidpp.Response("00C4009D310003070500000000000000", 0x0510, "02"), # smart shift FeatureTest(
hidpp.Response("00500000000000000000000000000000", 0x0520, "0050"), # left button current settings_templates.PersistentRemappableAction,
hidpp.Response("00510000500000000000000000000000", 0x0520, "0051"), # right button current {80: 16797696, 81: 16797696},
hidpp.Response("00C40000000000000000000000000000", 0x0520, "00C4"), # smart shift current {0x51: 16797952},
hidpp.Response("00C4030000", 0x0530, "00C4030000"), 0x40,
], "0051FF01005100",
),
{
common.NamedInt(80, "Left Button"): special_keys.KEYS_KEYS_CONSUMER,
common.NamedInt(81, "Right Button"): special_keys.KEYS_KEYS_CONSUMER,
},
]
+ responses_remappable_action,
] ]