tests: add tests for setting_templates
This commit is contained in:
parent
17bbc9c4ea
commit
5e351399f5
|
@ -16,10 +16,16 @@
|
||||||
|
|
||||||
"""HID++ data and functions common to several logitech_receiver test files"""
|
"""HID++ data and functions common to several logitech_receiver test files"""
|
||||||
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from dataclasses import field
|
||||||
from struct import pack
|
from struct import pack
|
||||||
|
from typing import Any
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from logitech_receiver import device
|
||||||
|
from logitech_receiver import hidpp20
|
||||||
|
|
||||||
|
|
||||||
def open_path(path: Optional[str]) -> Optional[int]:
|
def open_path(path: Optional[str]) -> Optional[int]:
|
||||||
return int(path, 16) if path is not None else None
|
return int(path, 16) if path is not None else None
|
||||||
|
@ -117,3 +123,41 @@ r_mouse_3 = [ # a HID++ 2.0 mouse
|
||||||
Response("414241424142414241424142414241", 0x0510, "00"), # name - first 15 characters
|
Response("414241424142414241424142414241", 0x0510, "00"), # name - first 15 characters
|
||||||
Response("444544000000000000000000000000", 0x0510, "0F"), # name - last 3 characters
|
Response("444544000000000000000000000000", 0x0510, "0F"), # name - last 3 characters
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Device:
|
||||||
|
name: str = "TESTD"
|
||||||
|
online: bool = True
|
||||||
|
protocol: float = 2.0
|
||||||
|
codename: str = "TESTC"
|
||||||
|
responses: Any = field(default_factory=list)
|
||||||
|
feature: Optional[int] = None
|
||||||
|
features: Any = None
|
||||||
|
_backlight: Any = None
|
||||||
|
_keys: Any = None
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
self.features = hidpp20.FeaturesArray(self)
|
||||||
|
self.responses += [Response("010001", 0x0000, "0001"), Response("20", 0x0100)]
|
||||||
|
if self.feature is not None:
|
||||||
|
self.responses.append(Response("040001", 0x0000, f"{self.feature:0>4X}"))
|
||||||
|
|
||||||
|
def request(self, id, *params, no_reply=False):
|
||||||
|
if params is None:
|
||||||
|
params = []
|
||||||
|
params = b"".join(pack("B", p) if isinstance(p, int) else p for p in params)
|
||||||
|
print("REQUEST ", self.name, hex(id), params.hex())
|
||||||
|
for r in self.responses:
|
||||||
|
if id == r.id and params == bytes.fromhex(r.params):
|
||||||
|
print("RESPONSE", self.name, hex(r.id), r.params, r.response)
|
||||||
|
return bytes.fromhex(r.response) if r.response is not None else None
|
||||||
|
|
||||||
|
def feature_request(self, feature, function=0x00, *params, no_reply=False):
|
||||||
|
if self.protocol >= 2.0:
|
||||||
|
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
|
||||||
|
|
|
@ -0,0 +1,442 @@
|
||||||
|
## Copyright (C) 2024 Solaar Contributors https://pwr-solaar.github.io/Solaar/
|
||||||
|
##
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License along
|
||||||
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from struct import pack
|
||||||
|
from typing import Any
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from logitech_receiver import common
|
||||||
|
from logitech_receiver import hidpp20
|
||||||
|
from logitech_receiver import settings_templates
|
||||||
|
from solaar import configuration
|
||||||
|
|
||||||
|
from . import hidpp
|
||||||
|
|
||||||
|
# TODO OnboardProfiles, Report Rate, ExtendedReportRate, DpiSlidingXY, MouseGesturesXY, DivertKeys
|
||||||
|
# TODO SpeedChange and onward
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RegisterTest:
|
||||||
|
sclass: Any
|
||||||
|
initial_value: Any = False
|
||||||
|
write_value: Any = True
|
||||||
|
write_params: str = ""
|
||||||
|
|
||||||
|
|
||||||
|
tests = [
|
||||||
|
[
|
||||||
|
RegisterTest(settings_templates.RegisterHandDetection, False, True, [b"\x00\x00\x00"]),
|
||||||
|
hidpp.Response("000030", 0x8101), # keyboard_hand_detection
|
||||||
|
hidpp.Response("000000", 0x8001, "000000"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
RegisterTest(settings_templates.RegisterHandDetection, True, False, [b"\x00\x00\x30"]),
|
||||||
|
hidpp.Response("000000", 0x8101), # keyboard_hand_detection
|
||||||
|
hidpp.Response("000030", 0x8001, "000030"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
RegisterTest(settings_templates.RegisterSmoothScroll, False, True, [b"\x40"]),
|
||||||
|
hidpp.Response("00", 0x8101), # mouse_button_flags
|
||||||
|
hidpp.Response("40", 0x8001, "40"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
RegisterTest(settings_templates.RegisterSideScroll, True, False, [b"\x00"]),
|
||||||
|
hidpp.Response("02", 0x8101), # mouse_button_flags
|
||||||
|
hidpp.Response("00", 0x8001, "00"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
RegisterTest(settings_templates.RegisterFnSwap, False, True, [b"\x00\x01"]),
|
||||||
|
hidpp.Response("0000", 0x8109), # keyboard_fn_swap
|
||||||
|
hidpp.Response("0001", 0x8009, "0001"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
RegisterTest(
|
||||||
|
settings_templates._PerformanceMXDpi, common.NamedInt(0x88, "800"), common.NamedInt(0x89, "900"), [b"\x89"]
|
||||||
|
),
|
||||||
|
hidpp.Response("88", 0x8163), # mouse_dpi
|
||||||
|
hidpp.Response("89", 0x8063, "89"),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("test", tests)
|
||||||
|
def test_register_template(test, mocker):
|
||||||
|
device = hidpp.Device(responses=test[1:])
|
||||||
|
device.persister = configuration._DeviceEntry()
|
||||||
|
device.protocol = 1.0
|
||||||
|
spy_request = mocker.spy(device, "request")
|
||||||
|
|
||||||
|
setting = test[0].sclass.build(device)
|
||||||
|
value = setting.read(cached=False)
|
||||||
|
cached_value = setting.read(cached=True)
|
||||||
|
write_value = setting.write(test[0].write_value)
|
||||||
|
|
||||||
|
assert setting is not None
|
||||||
|
assert value == test[0].initial_value
|
||||||
|
assert cached_value == test[0].initial_value
|
||||||
|
assert write_value == test[0].write_value
|
||||||
|
spy_request.assert_called_with(test[0].sclass.register + 0x8000, *test[0].write_params)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FeatureTest:
|
||||||
|
sclass: Any
|
||||||
|
initial_value: Any = False
|
||||||
|
write_value: Any = True
|
||||||
|
write_fnid: int = 0x10
|
||||||
|
write_params: str = ""
|
||||||
|
no_reply: Optional[bool] = False
|
||||||
|
|
||||||
|
|
||||||
|
tests = [
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.K375sFnSwap, False, True, 0x10, "FF01"),
|
||||||
|
hidpp.Response("060001", 0x0000, "40A3"), # K375_FN_INVERSION
|
||||||
|
hidpp.Response("FF0001", 0x0600, "FF"),
|
||||||
|
hidpp.Response("FF0101", 0x0610, "FF01"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.FnSwap, True, False, 0x10, "00"),
|
||||||
|
hidpp.Response("040001", 0x0000, "40A0"), # FN_INVERSION
|
||||||
|
hidpp.Response("01", 0x0400),
|
||||||
|
hidpp.Response("00", 0x0410, "00"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.NewFnSwap, True, False, 0x10, "00"),
|
||||||
|
hidpp.Response("040001", 0x0000, "40A2"), # NEW_FN_INVERSION
|
||||||
|
hidpp.Response("01", 0x0400),
|
||||||
|
hidpp.Response("00", 0x0410, "00"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.Backlight, 0, 5, 0x10, "05"),
|
||||||
|
hidpp.Response("060001", 0x0000, "1981"), # BACKLIGHT
|
||||||
|
hidpp.Response("00", 0x0600),
|
||||||
|
hidpp.Response("05", 0x0610, "05"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.Backlight2DurationHandsOut, 0x20, 0x40, 0x10, "0118FF000D0040006000", None),
|
||||||
|
hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2
|
||||||
|
hidpp.Response("011830000000200040006000", 0x0400),
|
||||||
|
hidpp.Response("0118FF000000040004000600", 0x0410, "0118FF000D0040006000"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.Backlight2DurationPowered, 0x60, 0x70, 0x10, "0118FF00200040001700", None),
|
||||||
|
hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2
|
||||||
|
hidpp.Response("011830000000200040006000", 0x0400),
|
||||||
|
hidpp.Response("0118FF00200040001700", 0x0410, "0118FF00200040001700"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.HiResScroll, True, False, 0x10, "00"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2120"), # HI_RES_SCROLLING
|
||||||
|
hidpp.Response("01", 0x0400),
|
||||||
|
hidpp.Response("00", 0x0410, "00"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.LowresMode, False, True, 0x10, "01"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2130"), # LOWRES_WHEEL
|
||||||
|
hidpp.Response("00", 0x0400),
|
||||||
|
hidpp.Response("01", 0x0410, "01"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.HiresSmoothInvert, True, False, 0x20, "02"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2121"), # HIRES_WHEEL
|
||||||
|
hidpp.Response("06", 0x0410),
|
||||||
|
hidpp.Response("02", 0x0420, "02"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.HiresSmoothResolution, True, False, 0x20, "04"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2121"), # HIRES_WHEEL
|
||||||
|
hidpp.Response("06", 0x0410),
|
||||||
|
hidpp.Response("04", 0x0420, "04"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.HiresMode, False, True, 0x20, "07"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2121"), # HIRES_WHEEL
|
||||||
|
hidpp.Response("06", 0x0410),
|
||||||
|
hidpp.Response("07", 0x0420, "07"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.PointerSpeed, 0x0100, 0x0120, 0x10, "0120"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2205"), # POINTER_SPEED
|
||||||
|
hidpp.Response("0100", 0x0400),
|
||||||
|
hidpp.Response("0120", 0x0410, "0120"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.ThumbMode, True, False, 0x20, "0000"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2150"), # THUMB_WHEEL
|
||||||
|
hidpp.Response("0100", 0x0410),
|
||||||
|
hidpp.Response("0000", 0x0420, "0000"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.ThumbInvert, False, True, 0x20, "0101"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2150"), # THUMB_WHEEL
|
||||||
|
hidpp.Response("0100", 0x0410),
|
||||||
|
hidpp.Response("0101", 0x0420, "0101"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.DivertCrown, False, True, 0x20, "02"),
|
||||||
|
hidpp.Response("040001", 0x0000, "4600"), # CROWN
|
||||||
|
hidpp.Response("01", 0x0410),
|
||||||
|
hidpp.Response("02", 0x0420, "02"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.CrownSmooth, True, False, 0x20, "0002"),
|
||||||
|
hidpp.Response("040001", 0x0000, "4600"), # CROWN
|
||||||
|
hidpp.Response("0001", 0x0410),
|
||||||
|
hidpp.Response("0002", 0x0420, "0002"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.DivertGkeys, False, True, 0x20, "01"),
|
||||||
|
hidpp.Response("040001", 0x0000, "8010"), # GKEY
|
||||||
|
hidpp.Response("01", 0x0420, "01"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.ScrollRatchet, 2, 1, 0x10, "01"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2110"), # SMART_SHIFT
|
||||||
|
hidpp.Response("02", 0x0400),
|
||||||
|
hidpp.Response("01", 0x0410, "01"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.SmartShift, 1, 10, 0x10, "000A"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2110"), # SMART_SHIFT
|
||||||
|
hidpp.Response("0100", 0x0400),
|
||||||
|
hidpp.Response("000A", 0x0410, "000A"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.SmartShift, 5, 50, 0x10, "00FF"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2110"), # SMART_SHIFT
|
||||||
|
hidpp.Response("0005", 0x0400),
|
||||||
|
hidpp.Response("00FF", 0x0410, "00FF"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.SmartShiftEnhanced, 5, 50, 0x20, "00FF"),
|
||||||
|
hidpp.Response("040001", 0x0000, "2111"), # SMART_SHIFT_ENHANCED
|
||||||
|
hidpp.Response("0005", 0x0410),
|
||||||
|
hidpp.Response("00FF", 0x0420, "00FF"),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("test", tests)
|
||||||
|
def test_simple_template(test, mocker):
|
||||||
|
setup_responses = [hidpp.Response("010001", 0x0000, "0001"), hidpp.Response("20", 0x0100)]
|
||||||
|
device = hidpp.Device(responses=test[1:] + setup_responses)
|
||||||
|
device.persister = configuration._DeviceEntry()
|
||||||
|
device.features = hidpp20.FeaturesArray(device)
|
||||||
|
spy_feature_request = mocker.spy(device, "feature_request")
|
||||||
|
|
||||||
|
setting = settings_templates.check_feature(device, test[0].sclass)
|
||||||
|
value = setting.read(cached=False)
|
||||||
|
cached_value = setting.read(cached=True)
|
||||||
|
write_value = setting.write(test[0].write_value)
|
||||||
|
|
||||||
|
assert setting is not None
|
||||||
|
assert value == test[0].initial_value
|
||||||
|
assert cached_value == test[0].initial_value
|
||||||
|
assert write_value == test[0].write_value
|
||||||
|
params = bytes.fromhex(test[0].write_params)
|
||||||
|
no_reply = {"no_reply": test[0].no_reply} if test[0].no_reply is not None else {}
|
||||||
|
spy_feature_request.assert_called_with(test[0].sclass.feature, test[0].write_fnid, params, **no_reply)
|
||||||
|
|
||||||
|
|
||||||
|
tests = [
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.Backlight2, 0xFF, 0x00, 0x10, "0102ff00000000000000", None),
|
||||||
|
common.NamedInts(Disabled=0xFF, Enabled=0x00),
|
||||||
|
hidpp.Response("040001", 0x0000, "1982"), # BACKLIGHT2
|
||||||
|
hidpp.Response("000201000000000000000000", 0x0400),
|
||||||
|
hidpp.Response("010201", 0x0410, "0102ff00000000000000"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.Backlight2, 0x03, 0xFF, 0x10, "0018ff00000000000000", None),
|
||||||
|
common.NamedInts(Disabled=0xFF, Manual=0x03),
|
||||||
|
hidpp.Response("040001", 0x0000, "1982"), # BACKLIGHT2
|
||||||
|
hidpp.Response("011830000000000000000000", 0x0400),
|
||||||
|
hidpp.Response("001801", 0x0410, "0018ff00000000000000"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.Backlight2Level, 0, 3, 0x10, "0118ff03000000000000", None),
|
||||||
|
[0, 4],
|
||||||
|
hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2
|
||||||
|
hidpp.Response("011830000000000000000000", 0x0400),
|
||||||
|
hidpp.Response("01180103000000000000", 0x0410, "0118ff03000000000000"),
|
||||||
|
hidpp.Response("05", 0x0420),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.Backlight2Level, 0, 2, 0x10, "0118ff02000000000000", None),
|
||||||
|
[0, 4],
|
||||||
|
hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2
|
||||||
|
hidpp.Response("011830000000000000000000", 0x0400),
|
||||||
|
hidpp.Response("01180102000000000000", 0x0410, "0118ff02000000000000"),
|
||||||
|
hidpp.Response("05", 0x0420),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.AdjustableDpi, 800, 400, 0x30, "000190"),
|
||||||
|
common.NamedInts.list([400, 800, 1600]),
|
||||||
|
hidpp.Response("040003", 0x0000, "2201"), # ADJUSTABLE_DPI
|
||||||
|
hidpp.Response("000190032006400000", 0x0410, "000000"),
|
||||||
|
hidpp.Response("000320", 0x0420),
|
||||||
|
hidpp.Response("000190", 0x0430, "000190"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.AdjustableDpi, 256, 512, 0x30, "000200"),
|
||||||
|
common.NamedInts.list([256, 512]),
|
||||||
|
hidpp.Response("040003", 0x0000, "2201"), # ADJUSTABLE_DPI
|
||||||
|
hidpp.Response("000100e10002000000", 0x0410, "000000"),
|
||||||
|
hidpp.Response("000100", 0x0420),
|
||||||
|
hidpp.Response("000200", 0x0430, "000200"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.ExtendedAdjustableDpi, 256, 512, 0x60, "000200"),
|
||||||
|
common.NamedInts.list([256, 512]),
|
||||||
|
hidpp.Response("090000", 0x0000, "2202"), # EXTENDED_ADJUSTABLE_DPI
|
||||||
|
hidpp.Response("0000000100e10002000000", 0x0920, "000000"),
|
||||||
|
hidpp.Response("000100", 0x0950),
|
||||||
|
hidpp.Response("000200", 0x0960, "000200"),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("test", tests)
|
||||||
|
def test_variable_template(test, mocker):
|
||||||
|
setup_responses = [hidpp.Response("010001", 0x0000, "0001"), hidpp.Response("20", 0x0100)]
|
||||||
|
device = hidpp.Device(responses=test[2:] + setup_responses)
|
||||||
|
device.persister = configuration._DeviceEntry()
|
||||||
|
device.features = hidpp20.FeaturesArray(device)
|
||||||
|
spy_feature_request = mocker.spy(device, "feature_request")
|
||||||
|
|
||||||
|
setting = settings_templates.check_feature(device, test[0].sclass)
|
||||||
|
value = setting.read(cached=False)
|
||||||
|
cached_value = setting.read(cached=True)
|
||||||
|
write_value = setting.write(test[0].write_value)
|
||||||
|
|
||||||
|
assert setting is not None
|
||||||
|
if isinstance(test[1], common.NamedInts):
|
||||||
|
assert len(setting.choices) == len(test[1])
|
||||||
|
for setting_choice, expected_choice in zip(setting.choices, test[1]):
|
||||||
|
assert setting_choice == expected_choice
|
||||||
|
if isinstance(test[1], list):
|
||||||
|
assert setting._validator.min_value == test[1][0]
|
||||||
|
assert setting._validator.max_value == test[1][1]
|
||||||
|
assert value == test[0].initial_value
|
||||||
|
assert cached_value == test[0].initial_value
|
||||||
|
assert write_value == test[0].write_value
|
||||||
|
|
||||||
|
params = bytes.fromhex(test[0].write_params)
|
||||||
|
no_reply = {"no_reply": test[0].no_reply} if test[0].no_reply is not None else {}
|
||||||
|
spy_feature_request.assert_called_with(test[0].sclass.feature, test[0].write_fnid, params, **no_reply)
|
||||||
|
|
||||||
|
|
||||||
|
tests = [
|
||||||
|
[
|
||||||
|
FeatureTest(
|
||||||
|
settings_templates.ReprogrammableKeys, {0x50: 0x50, 0x51: 0x50, 0xC4: 0xC4}, {0x51: 0x51}, 0x30, "0051000051"
|
||||||
|
),
|
||||||
|
{
|
||||||
|
common.NamedInt(0x50, "Left Button"): [0x50, 0x51],
|
||||||
|
common.NamedInt(0x51, "Right Button"): [0x51, 0x50],
|
||||||
|
common.NamedInt(0xC4, "Smart Shift"): [0xC4, 0x50, 0x51],
|
||||||
|
},
|
||||||
|
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
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("test", tests)
|
||||||
|
def test_key_template(test, mocker):
|
||||||
|
setup_responses = [hidpp.Response("010001", 0x0000, "0001"), hidpp.Response("20", 0x0100)]
|
||||||
|
device = hidpp.Device(responses=test[2:] + setup_responses)
|
||||||
|
device.persister = configuration._DeviceEntry()
|
||||||
|
device.features = hidpp20.FeaturesArray(device)
|
||||||
|
spy_feature_request = mocker.spy(device, "feature_request")
|
||||||
|
|
||||||
|
setting = settings_templates.check_feature(device, test[0].sclass)
|
||||||
|
assert setting is not None
|
||||||
|
assert len(setting.choices) == len(test[1])
|
||||||
|
for k, v in setting.choices.items():
|
||||||
|
assert len(v) == len(test[1][k])
|
||||||
|
for setting_key, test_key in zip(v, test[1][k]):
|
||||||
|
assert setting_key == test_key
|
||||||
|
|
||||||
|
value = setting.read(cached=False)
|
||||||
|
for k, v in test[0].initial_value.items():
|
||||||
|
assert value[k] == v
|
||||||
|
|
||||||
|
for key, value in test[0].write_value.items():
|
||||||
|
write_value = setting.write_key_value(key, value)
|
||||||
|
assert write_value == value
|
||||||
|
|
||||||
|
assert spy_feature_request.call_args_list[-1][0][0] == test[0].sclass.feature
|
||||||
|
assert spy_feature_request.call_args_list[-1][0][1] == test[0].write_fnid
|
||||||
|
param = b"".join(pack("B", p) if isinstance(p, int) else p for p in spy_feature_request.call_args_list[-1][0][2:])
|
||||||
|
assert param == bytes.fromhex(test[0].write_params)
|
||||||
|
|
||||||
|
|
||||||
|
tests = [ # needs settings to be set up!!
|
||||||
|
[
|
||||||
|
FeatureTest(settings_templates.SpeedChange, 0, 0xED, 0x60, "000200"),
|
||||||
|
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", tests)
|
||||||
|
def XX_action_template(test, mocker): # needs settings to be set up!!
|
||||||
|
setup_responses = [hidpp.Response("010001", 0x0000, "0001"), hidpp.Response("20", 0x0100)]
|
||||||
|
device = hidpp.Device(responses=test[2:] + setup_responses)
|
||||||
|
device.persister = configuration._DeviceEntry()
|
||||||
|
device.features = hidpp20.FeaturesArray(device)
|
||||||
|
spy_feature_request = mocker.spy(device, "feature_request")
|
||||||
|
|
||||||
|
setting = settings_templates.check_feature(device, test[0].sclass)
|
||||||
|
print("SETTING", setting)
|
||||||
|
value = setting.read(cached=False)
|
||||||
|
cached_value = setting.read(cached=True)
|
||||||
|
write_value = setting.write(test[0].write_value)
|
||||||
|
|
||||||
|
assert setting is not None
|
||||||
|
if isinstance(test[1], common.NamedInts):
|
||||||
|
assert len(setting.choices) == len(test[1])
|
||||||
|
for setting_choice, expected_choice in zip(setting.choices, test[1]):
|
||||||
|
assert setting_choice == expected_choice
|
||||||
|
if isinstance(test[1], list):
|
||||||
|
assert setting._validator.min_value == test[1][0]
|
||||||
|
assert setting._validator.max_value == test[1][1]
|
||||||
|
assert value == test[0].initial_value
|
||||||
|
assert cached_value == test[0].initial_value
|
||||||
|
assert write_value == test[0].write_value
|
||||||
|
|
||||||
|
params = bytes.fromhex(test[0].write_params)
|
||||||
|
no_reply = {"no_reply": test[0].no_reply} if test[0].no_reply is not None else {}
|
||||||
|
spy_feature_request.assert_called_with(test[0].sclass.feature, test[0].write_fnid, params, **no_reply)
|
Loading…
Reference in New Issue