Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test diversion rules #23

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions lib/solaar/ui/diversion_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from __future__ import annotations

import dataclasses
import logging
import string
Expand Down Expand Up @@ -994,21 +996,21 @@ def __post_init__(self):
self.unitId = ""

@property
def id(self):
def id(self) -> str:
return self.serial or self.unitId or ""

@property
def identifiers(self):
def identifiers(self) -> list[str]:
return [id for id in (self.serial, self.unitId) if id]

@property
def display_name(self):
def display_name(self) -> str:
return f"{self.codename} ({self.id})"

def matches(self, search):
def matches(self, search: str) -> bool:
return search and search in (self.serial, self.unitId, self.display_name)

def update(self, device):
def update(self, device: DeviceInfo) -> None:
for k in ("serial", "unitId", "codename", "settings"):
if not getattr(self, k, None):
v = getattr(device, k, None)
Expand Down Expand Up @@ -1854,7 +1856,7 @@ def update_devices():
_diversion_dialog.update_devices()


def show_window(model):
def show_window(model: Gtk.TreeStore):
GObject.type_register(RuleComponentWrapper)
global _diversion_dialog
global _dev_model
Expand Down
6 changes: 3 additions & 3 deletions lib/solaar/ui/rule_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def __parse(cls, v):
except (TypeError, ValueError):
return 0

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.field_x.set_value(self.__parse(component.amounts[0] if len(component.amounts) >= 1 else 0))
Expand Down Expand Up @@ -219,7 +219,7 @@ def create_widgets(self):
self.widgets[self.field_c] = (3, 1, 1, 1)
self.widgets[self.field_d] = (4, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.field_b.set_text(component.button)
Expand Down Expand Up @@ -288,7 +288,7 @@ def _clicked_del(self, _btn, pos):
self.show(self.component, editable=True)
self._on_update_callback()

def show(self, component, editable):
def show(self, component, editable=True):
n = len(component.args)
while len(self.fields) < n:
self._create_field()
Expand Down
6 changes: 3 additions & 3 deletions lib/solaar/ui/rule_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ def _show_widgets(self, editable):
widget.show()

@classmethod
def left_label(cls, component):
def left_label(cls, component) -> str:
return type(component).__name__

@classmethod
def right_label(cls, _component):
def right_label(cls, _component) -> str:
return ""

@classmethod
def icon_name(cls):
def icon_name(cls) -> str:
return ""

def _remove_panel_items(self):
Expand Down
20 changes: 10 additions & 10 deletions lib/solaar/ui/rule_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def create_widgets(self):
self.field.connect("changed", self._on_update)
self.widgets[self.field] = (0, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.field.set_text(component.process)
Expand Down Expand Up @@ -77,7 +77,7 @@ def create_widgets(self):
self.field.connect("changed", self._on_update)
self.widgets[self.field] = (0, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.field.set_text(component.process)
Expand Down Expand Up @@ -124,7 +124,7 @@ def create_widgets(self):
CompletionEntry.add_completion_to_entry(self.field.get_child(), all_features)
self.widgets[self.field] = (0, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
f = str(component.feature) if component.feature else ""
Expand Down Expand Up @@ -166,7 +166,7 @@ def create_widgets(self):
self.field.connect("changed", self._on_update)
self.widgets[self.field] = (0, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.field.set_value(component.report)
Expand Down Expand Up @@ -202,7 +202,7 @@ def create_widgets(self):
self.switches[m] = switch
switch.connect("notify::active", self._on_update)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
for m in diversion.MODIFIERS:
Expand Down Expand Up @@ -245,7 +245,7 @@ def create_widgets(self):
self.action_released_radio.connect("toggled", self._on_update, Key.UP)
self.widgets[self.action_released_radio] = (3, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.key_field.set_text(str(component.key) if self.component.key else "")
Expand Down Expand Up @@ -291,7 +291,7 @@ def create_widgets(self):
self.key_field.connect("changed", self._on_update)
self.widgets[self.key_field] = (0, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.key_field.set_text(str(component.key) if self.component.key else "")
Expand Down Expand Up @@ -343,7 +343,7 @@ def create_widgets(self):
self.parameter.connect("changed", self._on_update)
self.widgets[self.parameter] = (3, 1, 1, 1)

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)
with self.ignore_changes():
self.test.set_active_id(component.test)
Expand Down Expand Up @@ -454,7 +454,7 @@ def create_widgets(self):
self.mode_field.connect("changed", lambda cb: (self._on_update(), self._only_mode(cb.get_active_id())))
self.mode_field.set_active_id("range")

def show(self, component, editable):
def show(self, component, editable=True):
super().show(component, editable)

with self.ignore_changes():
Expand Down Expand Up @@ -572,7 +572,7 @@ def _on_update(self, *args):
)
f.get_child().set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, icon)

def show(self, component, editable):
def show(self, component, editable=True):
n = len(component.movements)
while len(self.fields) < n:
self._create_field()
Expand Down
80 changes: 80 additions & 0 deletions tests/solaar/ui/test_diversion_rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import platform

from unittest import mock

import pytest

from solaar.ui import diversion_rules


@pytest.mark.skipif(
platform.system() == "Linux",
reason="Not functional on Linux yet",
)
@pytest.mark.parametrize(
"component, left_label, right_label, icon_name",
[
("RuleComponentUI", "RuleComponentUI", "", ""),
("RuleUI", "Rule", "", "format-justify-fill"),
("AndUI", "And", "", ""),
("OrUI", "Or", "", ""),
("LaterUI", "Later", "delay123", ""),
("NotUI", "Not", "", ""),
("ActionUI", "ActionUI", "", "go-next"),
],
)
def test_rule_component_ui_classes(
component,
left_label,
right_label,
icon_name,
):
cls = getattr(diversion_rules, component)
default_mock = mock.PropertyMock(delay="delay123")

rule_comp = cls(mock.MagicMock())

assert cls.left_label(rule_comp) == left_label
assert cls.right_label(default_mock) == right_label
assert cls.icon_name() == icon_name


def test_device_info():
expected_serial = "Serial123"

device_info = diversion_rules.DeviceInfo(serial=expected_serial)

assert device_info.serial == expected_serial


@pytest.mark.parametrize(
"serial, expected",
[
("Serial12", False),
("Serial123", True),
("Serial1234", False),
],
)
def test_device_info_matches(serial, expected):
device_info = diversion_rules.DeviceInfo(serial=serial)

result = device_info.matches("Serial123")

assert result == expected


def test_device_info_update():
expected_serial = "Serial123"
expected_unit_id = "Id123"
device_update = diversion_rules.DeviceInfo(
serial=expected_serial,
unitId=expected_unit_id,
)
device_info = diversion_rules.DeviceInfo()

device_info.update(device_update)

assert device_info.serial == expected_serial
assert device_info.unitId == expected_unit_id
assert device_info.identifiers == [expected_serial, expected_unit_id]
assert device_info.display_name == f" ({expected_serial})"
46 changes: 46 additions & 0 deletions tests/solaar/ui/test_rule_conditions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from unittest import mock

import pytest

from solaar.ui import rule_conditions


@pytest.mark.parametrize(
"component, left_label, right_label, icon_name",
[
("ConditionUI", "ConditionUI", "", "dialog-question"),
("ProcessUI", "Process", "process123", "dialog-question"),
("MouseProcessUI", "MouseProcess", "process123", "dialog-question"),
("FeatureUI", "Feature", "12 (000C)", "dialog-question"),
("ReportUI", "Report", "report123", "dialog-question"),
("ModifiersUI", "Modifiers", "None", "dialog-question"),
("KeyUI", "Key", "123 (007B) (action123)", "dialog-question"),
("KeyIsDownUI", "KeyIsDown", "123 (007B)", "dialog-question"),
("TestUI", "Test", "test123 'param'", "dialog-question"),
("TestBytesUI", "Test bytes", "test123", "dialog-question"),
("MouseGestureUI", "Mouse Gesture", "No-op", "dialog-question"),
],
)
def test_rule_component_ui_classes(
component,
left_label,
right_label,
icon_name,
):
cls = getattr(rule_conditions, component)
process_mock = mock.PropertyMock(
process="process123",
feature="12",
report="report123",
action="action123",
parameter="param",
key="123",
test="test123",
__add__="",
)

rule_comp = cls(mock.MagicMock())

assert cls.left_label(rule_comp) == left_label
assert cls.right_label(process_mock) == right_label
assert cls.icon_name() == icon_name
Loading