From 4d0f93b35cd00b3c5db23d13278278ff68863985 Mon Sep 17 00:00:00 2001 From: "Peter F. Patel-Schneider" Date: Mon, 25 Mar 2024 07:35:52 -0400 Subject: [PATCH] tests: improve infrastructure for testing setting_templates --- lib/logitech_receiver/common.py | 3 + tests/logitech_receiver/hidpp.py | 9 +- .../test_setting_templates.py | 751 ++++++++---------- 3 files changed, 343 insertions(+), 420 deletions(-) diff --git a/lib/logitech_receiver/common.py b/lib/logitech_receiver/common.py index 31a451c0..83d76c44 100644 --- a/lib/logitech_receiver/common.py +++ b/lib/logitech_receiver/common.py @@ -505,6 +505,9 @@ class NamedInts: def __or__(self, other): return NamedInts(**self.__dict__, **other.__dict__) + def __eq__(self, other): + return type(self) == type(other) and self._values == other._values + class UnsortedNamedInts(NamedInts): def _sort_values(self): diff --git a/tests/logitech_receiver/hidpp.py b/tests/logitech_receiver/hidpp.py index 35beb518..7bad8732 100644 --- a/tests/logitech_receiver/hidpp.py +++ b/tests/logitech_receiver/hidpp.py @@ -136,7 +136,8 @@ class Device: codename: str = "TESTC" responses: Any = field(default_factory=list) feature: Optional[int] = None - features: Any = None + offset: Optional[int] = 4 + version: Optional[int] = 0 setting_callback: Any = None _backlight = _keys = _remap_keys = _led_effects = None @@ -150,15 +151,15 @@ class Device: def __post_init__(self): self.persister = configuration._DeviceEntry() self.features = hidpp20.FeaturesArray(self) - self.responses += [Response("010001", 0x0000, "0001"), Response("20", 0x0100)] + self.responses = [Response("010001", 0x0000, "0001"), Response("20", 0x0100)] + self.responses if self.feature is not None: - self.responses.append(Response("040001", 0x0000, f"{self.feature:0>4X}")) + self.responses.append(Response(f"{self.offset:0>2X}00{self.version:0>2X}", 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()) + print("REQUEST ", self.name, hex(id), params.hex().upper()) 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) diff --git a/tests/logitech_receiver/test_setting_templates.py b/tests/logitech_receiver/test_setting_templates.py index 468a5b6e..52123cf7 100644 --- a/tests/logitech_receiver/test_setting_templates.py +++ b/tests/logitech_receiver/test_setting_templates.py @@ -21,7 +21,6 @@ The device uses some methods from the real device to set up data structures that from dataclasses import dataclass from struct import pack from typing import Any -from typing import Optional import pytest @@ -34,7 +33,13 @@ from . import hidpp # TODO DpiSlidingXY, MouseGesturesXY, SpeedChange # TODO Gesture2Gestures, Gesture2Divert, Gesture2Params, MKeyLEDs, Equalizer -# future per-key lighting + + +class Setup: + def __init__(self, test, *params): + self.test = test + self.responses = [r for r in params if isinstance(r, hidpp.Response)] + self.choices = None if isinstance(params[0], hidpp.Response) else params[0] @dataclass @@ -42,60 +47,60 @@ class RegisterTest: sclass: Any initial_value: Any = False write_value: Any = True - write_params: str = "" + write_params: str = "01" -tests = [ - [ +register_tests = [ + Setup( RegisterTest(settings_templates.RegisterHandDetection, False, True, [b"\x00\x00\x00"]), hidpp.Response("000030", 0x8101), # keyboard_hand_detection hidpp.Response("000000", 0x8001, "000000"), - ], - [ + ), + Setup( RegisterTest(settings_templates.RegisterHandDetection, True, False, [b"\x00\x00\x30"]), hidpp.Response("000000", 0x8101), # keyboard_hand_detection hidpp.Response("000030", 0x8001, "000030"), - ], - [ + ), + Setup( RegisterTest(settings_templates.RegisterSmoothScroll, False, True, [b"\x40"]), hidpp.Response("00", 0x8101), # mouse_button_flags hidpp.Response("40", 0x8001, "40"), - ], - [ + ), + Setup( RegisterTest(settings_templates.RegisterSideScroll, True, False, [b"\x00"]), hidpp.Response("02", 0x8101), # mouse_button_flags hidpp.Response("00", 0x8001, "00"), - ], - [ + ), + Setup( RegisterTest(settings_templates.RegisterFnSwap, False, True, [b"\x00\x01"]), hidpp.Response("0000", 0x8109), # keyboard_fn_swap hidpp.Response("0001", 0x8009, "0001"), - ], - [ + ), + Setup( 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) +@pytest.mark.parametrize("test", register_tests) def test_register_template(test, mocker): - device = hidpp.Device(protocol=1.0, responses=test[1:]) + device = hidpp.Device(protocol=1.0, responses=test.responses) spy_request = mocker.spy(device, "request") - setting = test[0].sclass.build(device) + setting = test.test.sclass.build(device) value = setting.read(cached=False) cached_value = setting.read(cached=True) - write_value = setting.write(test[0].write_value) + write_value = setting.write(test.test.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) + assert value == test.test.initial_value + assert cached_value == test.test.initial_value + assert write_value == test.test.write_value + spy_request.assert_called_with(test.test.sclass.register + 0x8000, *test.test.write_params) @dataclass @@ -103,413 +108,318 @@ class FeatureTest: sclass: Any initial_value: Any = False write_value: Any = True - write_fnid: int = 0x10 - write_params: str = "" - no_reply: Optional[bool] = False + matched_calls: int = 1 + offset: int = 0x04 + version: int = 0x00 -tests = [ - [ - FeatureTest(settings_templates.K375sFnSwap, False, True, 0x10, "FF01"), - hidpp.Response("060001", 0x0000, "40A3"), # K375_FN_INVERSION +simple_tests = [ + Setup( + FeatureTest(settings_templates.K375sFnSwap, False, True, offset=0x06), 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 + ), + Setup( + FeatureTest(settings_templates.FnSwap, True, False), 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 + ), + Setup( + FeatureTest(settings_templates.NewFnSwap, True, False), 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, 80, 160, 0x10, "0118FF00200040006000", None), - hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2 + ), + # Setup( # Backlight has caused problems + # FeatureTest(settings_templates.Backlight, 0, 5, offset=0x06), + # hidpp.Response("00", 0x0600), + # hidpp.Response("05", 0x0610, "05"), + # ), + Setup( + FeatureTest(settings_templates.Backlight2DurationHandsOut, 80, 160, version=0x03), hidpp.Response("011830000000100040006000", 0x0400), hidpp.Response("0118FF00200040006000", 0x0410, "0118FF00200040006000"), - ], - [ - FeatureTest(settings_templates.Backlight2DurationHandsIn, 320, 160, 0x10, "0118FF00200020006000", None), - hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2 + ), + Setup( + FeatureTest(settings_templates.Backlight2DurationHandsIn, 320, 160, version=0x03), hidpp.Response("011830000000200040006000", 0x0400), hidpp.Response("0118FF00200020006000", 0x0410, "0118FF00200020006000"), - ], - [ - FeatureTest(settings_templates.Backlight2DurationPowered, 480, 80, 0x10, "0118FF00200040001000", None), - hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2 + ), + Setup( + FeatureTest(settings_templates.Backlight2DurationPowered, 480, 80, version=0x03), hidpp.Response("011830000000200040006000", 0x0400), hidpp.Response("0118FF00200040001000", 0x0410, "0118FF00200040001000"), - ], - [ - FeatureTest(settings_templates.Backlight3, 0x50, 0x70, 0x20, "007009"), - hidpp.Response("040001", 0x0000, "1983"), # BACKLIGHT3 + ), + Setup( + FeatureTest(settings_templates.Backlight3, 0x50, 0x70), hidpp.Response("50", 0x0410), hidpp.Response("70", 0x0420, "007009"), - ], - [ - FeatureTest(settings_templates.HiResScroll, True, False, 0x10, "00"), - hidpp.Response("040001", 0x0000, "2120"), # HI_RES_SCROLLING + ), + Setup( + FeatureTest(settings_templates.HiResScroll, True, False), hidpp.Response("01", 0x0400), hidpp.Response("00", 0x0410, "00"), - ], - [ - FeatureTest(settings_templates.LowresMode, False, True, 0x10, "01"), - hidpp.Response("040001", 0x0000, "2130"), # LOWRES_WHEEL + ), + Setup( + FeatureTest(settings_templates.LowresMode, False, True), hidpp.Response("00", 0x0400), hidpp.Response("01", 0x0410, "01"), - ], - [ - FeatureTest(settings_templates.HiresSmoothInvert, True, False, 0x20, "02"), - hidpp.Response("040001", 0x0000, "2121"), # HIRES_WHEEL + ), + Setup( + FeatureTest(settings_templates.HiresSmoothInvert, True, False), hidpp.Response("06", 0x0410), hidpp.Response("02", 0x0420, "02"), - ], - [ - FeatureTest(settings_templates.HiresSmoothResolution, True, False, 0x20, "04"), - hidpp.Response("040001", 0x0000, "2121"), # HIRES_WHEEL + ), + Setup( + FeatureTest(settings_templates.HiresSmoothResolution, True, False), hidpp.Response("06", 0x0410), hidpp.Response("04", 0x0420, "04"), - ], - [ - FeatureTest(settings_templates.HiresMode, False, True, 0x20, "07"), - hidpp.Response("040001", 0x0000, "2121"), # HIRES_WHEEL + ), + Setup( + FeatureTest(settings_templates.HiresMode, False, True), hidpp.Response("06", 0x0410), hidpp.Response("07", 0x0420, "07"), - ], - [ - FeatureTest(settings_templates.PointerSpeed, 0x0100, 0x0120, 0x10, "0120"), - hidpp.Response("040001", 0x0000, "2205"), # POINTER_SPEED + ), + Setup( + FeatureTest(settings_templates.PointerSpeed, 0x0100, 0x0120), hidpp.Response("0100", 0x0400), hidpp.Response("0120", 0x0410, "0120"), - ], - [ - FeatureTest(settings_templates.ThumbMode, True, False, 0x20, "0000"), - hidpp.Response("040001", 0x0000, "2150"), # THUMB_WHEEL + ), + Setup( + FeatureTest(settings_templates.ThumbMode, True, False), hidpp.Response("0100", 0x0410), hidpp.Response("0000", 0x0420, "0000"), - ], - [ - FeatureTest(settings_templates.ThumbInvert, False, True, 0x20, "0101"), - hidpp.Response("040001", 0x0000, "2150"), # THUMB_WHEEL + ), + Setup( + FeatureTest(settings_templates.ThumbInvert, False, True), hidpp.Response("0100", 0x0410), hidpp.Response("0101", 0x0420, "0101"), - ], - [ - FeatureTest(settings_templates.DivertCrown, False, True, 0x20, "02"), - hidpp.Response("040001", 0x0000, "4600"), # CROWN + ), + Setup( + FeatureTest(settings_templates.DivertCrown, False, True), hidpp.Response("01", 0x0410), hidpp.Response("02", 0x0420, "02"), - ], - [ - FeatureTest(settings_templates.CrownSmooth, True, False, 0x20, "0002"), - hidpp.Response("040001", 0x0000, "4600"), # CROWN + ), + Setup( + FeatureTest(settings_templates.CrownSmooth, True, False), hidpp.Response("0001", 0x0410), hidpp.Response("0002", 0x0420, "0002"), - ], - [ - FeatureTest(settings_templates.DivertGkeys, False, True, 0x20, "01"), - hidpp.Response("040001", 0x0000, "8010"), # GKEY + ), + Setup( + FeatureTest(settings_templates.DivertGkeys, False, True), hidpp.Response("01", 0x0420, "01"), - ], - [ - FeatureTest(settings_templates.ScrollRatchet, 2, 1, 0x10, "01"), - hidpp.Response("040001", 0x0000, "2110"), # SMART_SHIFT + ), + Setup( + FeatureTest(settings_templates.ScrollRatchet, 2, 1), hidpp.Response("02", 0x0400), hidpp.Response("01", 0x0410, "01"), - ], - [ - FeatureTest(settings_templates.SmartShift, 1, 10, 0x10, "000A"), - hidpp.Response("040001", 0x0000, "2110"), # SMART_SHIFT + ), + Setup( + FeatureTest(settings_templates.SmartShift, 1, 10), hidpp.Response("0100", 0x0400), hidpp.Response("000A", 0x0410, "000A"), - ], - [ - FeatureTest(settings_templates.SmartShift, 5, 50, 0x10, "00FF"), - hidpp.Response("040001", 0x0000, "2110"), # SMART_SHIFT + ), + Setup( + FeatureTest(settings_templates.SmartShift, 5, 50), 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 + ), + Setup( + FeatureTest(settings_templates.SmartShiftEnhanced, 5, 50), hidpp.Response("0005", 0x0410), 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 + ), + Setup( + FeatureTest(settings_templates.DisableKeyboardKeys, {1: True, 8: True}, {1: False, 8: True}), 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 + ), + Setup( + FeatureTest(settings_templates.DualPlatform, 0, 1), hidpp.Response("00", 0x0400), hidpp.Response("01", 0x0420, "01"), - ], - [ - FeatureTest(settings_templates.MRKeyLED, False, True, 0x00, "01"), - hidpp.Response("040003", 0x0000, "8030"), # MR + ), + Setup( + FeatureTest(settings_templates.MRKeyLED, False, True), hidpp.Response("01", 0x0400, "01"), - ], - [ - FeatureTest(settings_templates.Sidetone, 5, 0xA, 0x10, "0A"), - hidpp.Response("040003", 0x0000, "8300"), # SIDETONE + ), + Setup( + FeatureTest(settings_templates.Sidetone, 5, 0xA), hidpp.Response("05", 0x0400), hidpp.Response("0A", 0x0410, "0A"), - ], - [ - FeatureTest(settings_templates.ADCPower, 5, 0xA, 0x20, "0A"), - hidpp.Response("040003", 0x0000, "1F20"), # ADC_MEASUREMENT + ), + Setup( + FeatureTest(settings_templates.ADCPower, 5, 0xA), 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 + ), + Setup( + FeatureTest(settings_templates.LEDControl, 0, 1), hidpp.Response("00", 0x0470), hidpp.Response("01", 0x0480, "01"), - ], - [ + ), + Setup( FeatureTest( settings_templates.LEDZoneSetting, hidpp20.LEDEffectSetting(ID=3, intensity=0x50, period=0x100), hidpp20.LEDEffectSetting(ID=3, intensity=0x50, period=0x101), - 0x30, - "000000000000000101500000", ), - hidpp.Response("040001", 0x0000, "8070"), # COLOR_LED_EFFECTS hidpp.Response("0100000001", 0x0400), hidpp.Response("00000102", 0x0410, "00FF00"), hidpp.Response("0000000300040005", 0x0420, "000000"), hidpp.Response("0001000B00080009", 0x0420, "000100"), hidpp.Response("000000000000010050", 0x04E0, "00"), hidpp.Response("000000000000000101500000", 0x0430, "000000000000000101500000"), - ], - [ - FeatureTest(settings_templates.RGBControl, 0, 1, 0x50, "0101"), - hidpp.Response("040003", 0x0000, "8071"), # RGB_EFFECTS + ), + Setup( + FeatureTest(settings_templates.RGBControl, 0, 1), hidpp.Response("0000", 0x0450), hidpp.Response("010100", 0x0450, "0101"), - ], - [ + ), + Setup( FeatureTest( settings_templates.RGBEffectSetting, hidpp20.LEDEffectSetting(ID=3, intensity=0x50, period=0x100), hidpp20.LEDEffectSetting(ID=2, color=0x505050, speed=0x50), - 0x10, - "00015050505000000000000001", ), - hidpp.Response("040003", 0x0000, "8071"), # RGB_EFFECTS hidpp.Response("FFFF0100000001", 0x0400, "FFFF00"), hidpp.Response("0000000102", 0x0400, "00FF00"), hidpp.Response("0000000300040005", 0x0400, "000000"), hidpp.Response("0001000200080009", 0x0400, "000100"), hidpp.Response("000000000000010050", 0x04E0, "00"), hidpp.Response("00015050505000000000000001", 0x0410, "00015050505000000000000001"), - ], - [ - FeatureTest( - settings_templates.RGBEffectSetting, - None, - hidpp20.LEDEffectSetting(ID=3, intensity=0x60, period=0x101), - 0x10, - "00000000000000010160000001", - ), - hidpp.Response("040003", 0x0000, "8071"), # RGB_EFFECTS + ), + Setup( + FeatureTest(settings_templates.RGBEffectSetting, None, hidpp20.LEDEffectSetting(ID=3, intensity=0x60, period=0x101)), hidpp.Response("FFFF0100000001", 0x0400, "FFFF00"), hidpp.Response("0000000102", 0x0400, "00FF00"), hidpp.Response("0000000300040005", 0x0400, "000000"), hidpp.Response("0001000200080009", 0x0400, "000100"), hidpp.Response("00000000000000010160000001", 0x0410, "00000000000000010160000001"), - ], - [ - FeatureTest( - settings_templates.RGBEffectSetting, - None, - hidpp20.LEDEffectSetting(ID=3, intensity=0x60, period=0x101), - 0x10, - "00020000000000010160000001", - ), - hidpp.Response("0A0000", 0x0000, "8071"), # RGB_EFFECTS - hidpp.Response("FF000200020004000000000000000000", 0x0A00, "FFFF00"), - hidpp.Response("00000002040000000000000000000000", 0x0A00, "00FF00"), - hidpp.Response("00000000000000000000000000000000", 0x0A00, "000000"), - hidpp.Response("00010001000000000000000000000000", 0x0A00, "000100"), - hidpp.Response("00020003C00503E00000000000000000", 0x0A00, "000200"), - hidpp.Response("0003000AC0011E0B0000000000000000", 0x0A00, "000300"), - hidpp.Response("01000001070000000000000000000000", 0x0A00, "01FF00"), - hidpp.Response("01000000000000000000000000000000", 0x0A00, "010000"), - hidpp.Response("01010001000000000000000000000000", 0x0A00, "010100"), - hidpp.Response("0102000AC0011E0B0000000000000000", 0x0A00, "010200"), - hidpp.Response("01030003C00503E00000000000000000", 0x0A00, "010300"), - hidpp.Response("01040004DCE1001E0000000000000000", 0x0A00, "010400"), - hidpp.Response("0105000B000000320000000000000000", 0x0A00, "010500"), - hidpp.Response("0106000C001B02340000000000000000", 0x0A00, "010600"), - hidpp.Response("00020000000000010160000001", 0x0A10, "00020000000000010160000001"), - ], -] - - -@pytest.mark.parametrize("test", tests) -def test_simple_template(test, mocker): - device = hidpp.Device(responses=test[1:]) - spy_feature_request = mocker.spy(device, "feature_request") - - setting = settings_templates.check_feature(device, test[0].sclass) - if isinstance(setting, list): - setting = setting[0] - 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) - - -@pytest.fixture -def mock_gethostname(mocker): - mocker.patch("socket.gethostname", return_value="ABCDEF.foo.org") - - -tests = [ - [ - FeatureTest(settings_templates.Backlight2, 0xFF, 0x00, 0x10, "0102ff00000000000000", None), + ), + Setup( + FeatureTest(settings_templates.RGBEffectSetting, None, hidpp20.LEDEffectSetting(ID=3, intensity=0x60, period=0x101)), + hidpp.Response("FF000200020004000000000000000000", 0x0400, "FFFF00"), + hidpp.Response("00000002040000000000000000000000", 0x0400, "00FF00"), + hidpp.Response("00000000000000000000000000000000", 0x0400, "000000"), + hidpp.Response("00010001000000000000000000000000", 0x0400, "000100"), + hidpp.Response("00020003C00503E00000000000000000", 0x0400, "000200"), + hidpp.Response("0003000AC0011E0B0000000000000000", 0x0400, "000300"), + hidpp.Response("01000001070000000000000000000000", 0x0400, "01FF00"), + hidpp.Response("01000000000000000000000000000000", 0x0400, "010000"), + hidpp.Response("01010001000000000000000000000000", 0x0400, "010100"), + hidpp.Response("0102000AC0011E0B0000000000000000", 0x0400, "010200"), + hidpp.Response("01030003C00503E00000000000000000", 0x0400, "010300"), + hidpp.Response("01040004DCE1001E0000000000000000", 0x0400, "010400"), + hidpp.Response("0105000B000000320000000000000000", 0x0400, "010500"), + hidpp.Response("0106000C001B02340000000000000000", 0x0400, "010600"), + hidpp.Response("00020000000000010160000001", 0x0410, "00020000000000010160000001"), + ), + Setup( + FeatureTest(settings_templates.Backlight2, 0xFF, 0x00), 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), + hidpp.Response("010201", 0x0410, "0102FF00000000000000"), + ), + Setup( + FeatureTest(settings_templates.Backlight2, 0x03, 0xFF), common.NamedInts(Disabled=0xFF, Automatic=0x01, Manual=0x03), - hidpp.Response("040001", 0x0000, "1982"), # BACKLIGHT2 hidpp.Response("011838000000000000000000", 0x0400), - hidpp.Response("001801", 0x0410, "0018ff00000000000000"), - ], - [ - FeatureTest(settings_templates.Backlight2Level, 0, 3, 0x10, "0118ff03000000000000", None), + hidpp.Response("001801", 0x0410, "0018FF00000000000000"), + ), + Setup( + FeatureTest(settings_templates.Backlight2Level, 0, 3, version=0x03), [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), + hidpp.Response("01180103000000000000", 0x0410, "0118FF03000000000000"), + ), + Setup( + FeatureTest(settings_templates.Backlight2Level, 0, 2, version=0x03), [0, 4], - hidpp.Response("040003", 0x0000, "1982"), # BACKLIGHT2 hidpp.Response("011830000000000000000000", 0x0400), - hidpp.Response("01180102000000000000", 0x0410, "0118ff02000000000000"), hidpp.Response("05", 0x0420), - ], - [ - FeatureTest(settings_templates.OnboardProfiles, 2, 1, 0x30, "0001", None), + hidpp.Response("01180102000000000000", 0x0410, "0118FF02000000000000"), + ), + Setup( + FeatureTest(settings_templates.OnboardProfiles, 0, 1, offset=0x0C), common.NamedInts(**{"Disabled": 0, "Profile 1": 1, "Profile 2": 2}), - hidpp.Response("0C0003", 0x0000, "8100"), # ONBOARD_PROFILES hidpp.Response("00010100000201FFFFFFFFFFFFFFFFFF", 0x0C50, "00000000"), hidpp.Response("000201FFFFFFFFFFFFFFFFFFFFFFFFFF", 0x0C50, "00000004"), hidpp.Response("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 0x0C50, "00000008"), - hidpp.Response("01", 0x0C20), - hidpp.Response("0002", 0x0C40), + hidpp.Response("02", 0x0C20), hidpp.Response("01", 0x0C10, "01"), hidpp.Response("0001", 0x0C30, "0001"), - ], - [ - FeatureTest(settings_templates.OnboardProfiles, 1, 0, 0x10, "02", None), + ), + Setup( + FeatureTest(settings_templates.OnboardProfiles, 1, 0, offset=0x0C), common.NamedInts(**{"Disabled": 0, "Profile 1": 1, "Profile 2": 2}), - hidpp.Response("0C0003", 0x0000, "8100"), # ONBOARD_PROFILES hidpp.Response("00010100000201FFFFFFFFFFFFFFFFFF", 0x0C50, "00000000"), hidpp.Response("000201FFFFFFFFFFFFFFFFFFFFFFFFFF", 0x0C50, "00000004"), hidpp.Response("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 0x0C50, "00000008"), hidpp.Response("01", 0x0C20), hidpp.Response("0001", 0x0C40), hidpp.Response("02", 0x0C10, "02"), - ], - [ - FeatureTest(settings_templates.ReportRate, 1, 5, 0x20, "05"), + ), + Setup( + FeatureTest(settings_templates.ReportRate, 1, 5, offset=0x0C), common.NamedInts(**{"1ms": 1, "2ms": 2, "5ms": 5, "6ms": 6}), - hidpp.Response("0C0003", 0x0000, "8060"), # REPORT_RATE hidpp.Response("33", 0x0C00), hidpp.Response("01", 0x0C10), hidpp.Response("05", 0x0C20, "05"), - ], - [ - FeatureTest(settings_templates.ExtendedReportRate, 1, 5, 0x30, "05"), + ), + Setup( + FeatureTest(settings_templates.ExtendedReportRate, 1, 5, offset=0x0C), common.NamedInts(**{"8ms": 0, "4ms": 1, "500us": 4, "250us": 5}), - hidpp.Response("0C0003", 0x0000, "8061"), # EXTENDED_REPORT_RATE hidpp.Response("33", 0x0C10), hidpp.Response("01", 0x0C20), hidpp.Response("05", 0x0C30, "05"), - ], - # [ - # FeatureTest(settings_templates.AdjustableDpi, 800, 400, 0x30, "000190"), + ), + # Setup( + # FeatureTest(settings_templates.AdjustableDpi, 800, 400, version=0x03), # 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"), + # ), + # Setup( + # FeatureTest(settings_templates.AdjustableDpi, 256, 512, version=0x03), # 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"), + # ), + # Setup( + # FeatureTest(settings_templates.ExtendedAdjustableDpi, 256, 512, version=0x09), # common.NamedInts.list([256, 512]), - # hidpp.Response("090000", 0x0000, "2202"), # EXTENDED_ADJUSTABLE_DPI # hidpp.Response("000000", 0x0910, "00"), # no y direction # hidpp.Response("0000000100e10002000000", 0x0920, "000000"), # hidpp.Response("000100", 0x0950), # hidpp.Response("000200", 0x0960, "000200"), - # ], - # [ - # FeatureTest(settings_templates.ExtendedAdjustableDpi, 0x64, 0x164, 0x60, "0001640164"), + # ), + # Setup( + # FeatureTest(settings_templates.ExtendedAdjustableDpi, 0x64, 0x164, version=0x09), # common.NamedInts.list([0x064, 0x074, 0x084, 0x0A4, 0x0C4, 0x0E4, 0x0124, 0x0164, 0x01C4]), - # hidpp.Response("090000", 0x0000, "2202"), # EXTENDED_ADJUSTABLE_DPI # hidpp.Response("000001", 0x0910, "00"), # supports y direction # hidpp.Response("0000000064E0100084E02000C4E02000", 0x0920, "000000"), # hidpp.Response("000001E4E0400124E0400164E06001C4", 0x0920, "000001"), # hidpp.Response("00000000000000000000000000000000", 0x0920, "000002"), # hidpp.Response("000064", 0x0950), # hidpp.Response("0001640164", 0x0960, "0001640164"), - # ], - [ - FeatureTest(settings_templates.Multiplatform, 0, 1, 0x30, "FF01"), + # ), + Setup( + FeatureTest(settings_templates.Multiplatform, 0, 1), 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), + ), + Setup( + FeatureTest(settings_templates.ChangeHost, 1, 0), 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"), @@ -518,76 +428,81 @@ tests = [ hidpp.Response("00004748494A4B4C00", 0x0530, "0100"), hidpp.Response("0201", 0x0400), hidpp.Response(True, 0x0410, "00"), - ], - [ - FeatureTest(settings_templates.BrightnessControl, 0x10, 0x20, 0x20, "0020", False), + ), + Setup( + FeatureTest(settings_templates.BrightnessControl, 0x10, 0x20), [0, 80], - hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL hidpp.Response("00505100000000", 0x0400), # 0 to 80, all acceptable, no separate on/off hidpp.Response("10", 0x0410), # brightness 16 hidpp.Response("0020", 0x0420, "0020"), # set brightness 32 - ], - [ - FeatureTest(settings_templates.BrightnessControl, 0x10, 0x00, 0x20, "0000", False), + ), + Setup( + FeatureTest(settings_templates.BrightnessControl, 0x10, 0x00), [0, 80], - hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL hidpp.Response("00505104000000", 0x0400), # 0 to 80, all acceptable, separate on/off hidpp.Response("10", 0x0410), # brightness 16 hidpp.Response("01", 0x0430), # on hidpp.Response("00", 0x0440), # set off hidpp.Response("0000", 0x0420, "0000"), # set brightness 0 - ], - [ - FeatureTest(settings_templates.BrightnessControl, 0x00, 0x20, 0x20, "0020", False), + ), + Setup( + FeatureTest(settings_templates.BrightnessControl, 0x00, 0x20), [0, 80], - hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL hidpp.Response("00505104000000", 0x0400), # 0 to 80, all acceptable, separate on/off hidpp.Response("10", 0x0410), # brightness 16 hidpp.Response("00", 0x0430), # off hidpp.Response("01", 0x0440), # set on hidpp.Response("0020", 0x0420, "0020"), # set brightness 32 - ], - [ - FeatureTest(settings_templates.BrightnessControl, 0x20, 0x08, 0x40, "00", False), + ), + Setup( + FeatureTest(settings_templates.BrightnessControl, 0x20, 0x08), [0, 80], - hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL hidpp.Response("00504104001000", 0x0400), # 16 to 80, all acceptable, separate on/off hidpp.Response("20", 0x0410), # brightness 32 hidpp.Response("01", 0x0430), # on hidpp.Response("00", 0x0440, "00"), # set off - ], + ), ] -@pytest.mark.parametrize("test", tests) -def test_variable_template(test, mocker, mock_gethostname): - device = hidpp.Device(responses=test[2:]) - spy_feature_request = mocker.spy(device, "feature_request") +@pytest.fixture +def mock_gethostname(mocker): + mocker.patch("socket.gethostname", return_value="ABCDEF.foo.org") - setting = settings_templates.check_feature(device, test[0].sclass) + +@pytest.mark.parametrize("test", simple_tests) +def test_simple_template(test, mocker, mock_gethostname): + tst = test.test + device = hidpp.Device(responses=test.responses, feature=tst.sclass.feature, offset=tst.offset, version=tst.version) + spy_request = mocker.spy(device, "request") + + setting = settings_templates.check_feature(device, tst.sclass) + + assert setting + + if isinstance(setting, list): + setting = setting[0] value = setting.read(cached=False) cached_value = setting.read(cached=True) - write_value = setting.write(test[0].write_value) + write_value = setting.write(tst.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 + 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] + assert value == tst.initial_value + assert cached_value == tst.initial_value + assert write_value == tst.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) + for i in range(0 - tst.matched_calls, 0): + param = b"".join(pack("B", p) if isinstance(p, int) else p for p in spy_request.call_args_list[i][0][1:]).hex().upper() + print("MATCH", i, hex(spy_request.call_args_list[i][0][0]), param, hex(test.responses[i].id), test.responses[i].params) + assert spy_request.call_args_list[i][0][0] == test.responses[i].id + assert param == test.responses[i].params 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 @@ -595,56 +510,55 @@ responses_reprog_controls = [ 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 + hidpp.Response("00500005000000000000000000000000", 0x0530, "0050000050"), # left button write + hidpp.Response("00510005000000000000000000000000", 0x0530, "0051000050"), # right button write + hidpp.Response("00C4000C400000000000000000000000", 0x0530, "00C40000C4"), # smart shift write ] -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 = [ - [ - FeatureTest( - settings_templates.ReprogrammableKeys, {0x50: 0x50, 0x51: 0x50, 0xC4: 0xC4}, {0x51: 0x51}, 0x30, "0051000051" - ), +key_tests = [ + Setup( + FeatureTest(settings_templates.ReprogrammableKeys, {0x50: 0x50, 0x51: 0x50, 0xC4: 0xC4}, {0x51: 0x51}, 4, offset=0x05), { - common.NamedInt(0x50, "Left Button"): [0x50, 0x51], - common.NamedInt(0x51, "Right Button"): [0x51, 0x50], - common.NamedInt(0xC4, "Smart Shift"): [0xC4, 0x50, 0x51], + common.NamedInt(0x50, "Left Button"): common.UnsortedNamedInts(Left_Click=0x50, Right_Click=0x51), + common.NamedInt(0x51, "Right Button"): common.UnsortedNamedInts(Right_Click=0x51, Left_Click=0x50), + common.NamedInt(0xC4, "Smart Shift"): common.UnsortedNamedInts(Smart_Shift=0xC4, Left_Click=80, Right_Click=81), }, - ] - + responses_reprog_controls, - [ - FeatureTest(settings_templates.DivertKeys, {0xC4: 0}, {0xC4: 1}, 0x30, "00C4030000"), - {common.NamedInt(0xC4, "Smart Shift"): [0, 1, 2]}, - ] - + responses_reprog_controls - + [hidpp.Response("00C4030000", 0x0530, "00C4030000")], - [ - FeatureTest( - settings_templates.PersistentRemappableAction, - {80: 16797696, 81: 16797696}, - {0x51: 16797952}, - 0x40, - "0051FF01005100", - ), + *responses_reprog_controls, + hidpp.Response("0051000051", 0x0530, "0051000051"), # right button set write + ), + Setup( + FeatureTest(settings_templates.DivertKeys, {0xC4: 0}, {0xC4: 1}, 2, offset=0x05), + {common.NamedInt(0xC4, "Smart Shift"): common.NamedInts(Regular=0, Diverted=1, Mouse_Gestures=2)}, + *responses_reprog_controls, + hidpp.Response("00C4020000", 0x0530, "00C4020000"), # Smart Shift write + hidpp.Response("00C4030000", 0x0530, "00C4030000"), # Smart Shift divert write + ), + Setup( + FeatureTest(settings_templates.PersistentRemappableAction, {80: 16797696, 81: 16797696}, {0x51: 16797952}, 3), { common.NamedInt(80, "Left Button"): special_keys.KEYS_KEYS_CONSUMER, common.NamedInt(81, "Right Button"): special_keys.KEYS_KEYS_CONSUMER, }, - ] - + responses_remappable_action, - [ - FeatureTest(settings_templates.PerKeyLighting, {0x01: 0xFFFFFF, 0x02: 0xFFFFFF}, {0x02: 0xFF0000}, 0x70, "00"), + hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4 + *responses_reprog_controls, + 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("0050FF01005000", 0x0440, "0050FF01005000"), # left button write + hidpp.Response("0051FF01005000", 0x0440, "0051FF01005000"), # right button write + hidpp.Response("0051FF01005100", 0x0440, "0051FF01005100"), # right button set write + ), + Setup( + FeatureTest( + settings_templates.PerKeyLighting, + {1: 0xFFFFFF, 2: 0xFFFFFF, 9: 0xFFFFFF, 10: 0xFFFFFF, 113: 0xFFFFFF, 114: 0xFFFFFF}, + {2: 0xFF0000}, + 5, + ), { common.NamedInt(1, "1"): special_keys.COLORS, common.NamedInt(2, "2"): special_keys.COLORS, @@ -653,49 +567,50 @@ tests = [ common.NamedInt(113, "113"): special_keys.COLORS, common.NamedInt(114, "114"): special_keys.COLORS, }, - hidpp.Response("040001", 0x0000, "8081"), # PER_KEY_LIGHTING_V2 - hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), - hidpp.Response("00000600000000000000000000000000", 0x0400, "0001"), - hidpp.Response("00000000000000000000000000000000", 0x0400, "0002"), - hidpp.Response("02FF0000", 0x0410, "02FF0000"), - hidpp.Response("00", 0x0470, "00"), - ], + hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys + hidpp.Response("00000600000000000000000000000000", 0x0400, "0001"), # second group of keys + hidpp.Response("00000000000000000000000000000000", 0x0400, "0002"), # last group of keys + hidpp.Response("01FFFFFF02FFFFFF09FFFFFF0AFFFFFF", 0x0410, "01FFFFFF02FFFFFF09FFFFFF0AFFFFFF"), # write first 4 values + hidpp.Response("71FFFFFF72FFFFFF", 0x0410, "71FFFFFF72FFFFFF"), # write last two values + hidpp.Response("00", 0x0470, "00"), # finish + hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value + hidpp.Response("00", 0x0470, "00"), # finish + ), ] -@pytest.mark.parametrize("test", tests) +@pytest.mark.parametrize("test", key_tests) def test_key_template(test, mocker): - device = hidpp.Device(responses=test[2:]) - spy_feature_request = mocker.spy(device, "feature_request") + tst = test.test + device = hidpp.Device(responses=test.responses, feature=tst.sclass.feature, offset=tst.offset, version=tst.version) + spy_request = mocker.spy(device, "request") - setting = settings_templates.check_feature(device, test[0].sclass) + setting = settings_templates.check_feature(device, tst.sclass) assert setting is not None if isinstance(setting, list): setting = setting[0] - 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 + assert setting.choices == test.choices value = setting.read(cached=False) - for k, v in test[0].initial_value.items(): - assert value[k] == v - setting.write(setting._value) + assert value == tst.initial_value - for key, value in test[0].write_value.items(): + wvalue = setting.write(value) + assert wvalue == tst.initial_value + + for key, value in tst.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) + for i in range(0 - tst.matched_calls, 0): + param = b"".join(pack("B", p) if isinstance(p, int) else p for p in spy_request.call_args_list[i][0][1:]).hex().upper() + print("MATCH", i, hex(spy_request.call_args_list[i][0][0]), param, hex(test.responses[i].id), test.responses[i].params) + assert spy_request.call_args_list[i][0][0] == test.responses[i].id + assert param == test.responses[i].params -tests = [ # needs settings to be set up!! - [ - FeatureTest(settings_templates.SpeedChange, 0, 0xED, 0x60, "000200"), +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), @@ -704,32 +619,36 @@ tests = [ # needs settings to be set up!! 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!! - device = hidpp.Device(responses=test[2:]) - spy_feature_request = mocker.spy(device, "feature_request") +@pytest.mark.parametrize("test", simple_tests + key_tests) +def test_check_feature_settings(test, mocker): + tst = test.test + device = hidpp.Device(responses=test.responses, feature=tst.sclass.feature, offset=tst.offset, version=tst.version) - 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) + already_known = [] + setting = settings_templates.check_feature_settings(device, already_known) - 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 + assert setting is True + assert already_known - 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) + +@pytest.mark.parametrize( + "test", + [ + Setup( + FeatureTest(settings_templates.K375sFnSwap, False, True, offset=0x06), + hidpp.Response("FF0001", 0x0600, "FF"), + hidpp.Response("FF0101", 0x0610, "FF01"), + ) + ], +) +def test_check_feature_setting(test, mocker): + tst = test.test + device = hidpp.Device(responses=test.responses, feature=tst.sclass.feature, offset=tst.offset, version=tst.version) + + setting = settings_templates.check_feature_setting(device, tst.sclass.name) + + assert setting