Skip to content

Commit

Permalink
Refactor rule loading for testability
Browse files Browse the repository at this point in the history
Introduce tests for YAML rule loading functionality.
  • Loading branch information
MattHag committed Apr 27, 2024
1 parent 3160e3b commit 5ae30cb
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 17 deletions.
38 changes: 22 additions & 16 deletions lib/logitech_receiver/diversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -1547,23 +1547,29 @@ def convert(elem):
return True


def _load_config_rule_file():
def load_config_rule_file():
"""Loads user configured rules."""
global rules
loaded_rules = []

if _path.isfile(_file_path):
try:
with open(_file_path) as config_file:
loaded_rules = []
for loaded_rule in _yaml_safe_load_all(config_file):
rule = Rule(loaded_rule, source=_file_path)
if logger.isEnabledFor(logging.DEBUG):
logger.debug("load rule: %s", rule)
loaded_rules.append(rule)
if logger.isEnabledFor(logging.INFO):
logger.info("loaded %d rules from %s", len(loaded_rules), config_file.name)
except Exception as e:
logger.error("failed to load from %s\n%s", _file_path, e)
rules = Rule([Rule(loaded_rules, source=_file_path), built_in_rules])
rules = _load_rule_config(_file_path)


def _load_rule_config(file_path: str) -> Rule:
loaded_rules = []
try:
with open(file_path) as config_file:
loaded_rules = []
for loaded_rule in _yaml_safe_load_all(config_file):
rule = Rule(loaded_rule, source=file_path)
if logger.isEnabledFor(logging.DEBUG):
logger.debug("load rule: %s", rule)
loaded_rules.append(rule)
if logger.isEnabledFor(logging.INFO):
logger.info("loaded %d rules from %s", len(loaded_rules), config_file.name)
except Exception as e:
logger.error("failed to load from %s\n%s", file_path, e)
return Rule([Rule(loaded_rules, source=file_path), built_in_rules])


_load_config_rule_file()
load_config_rule_file()
2 changes: 1 addition & 1 deletion lib/solaar/ui/diversion_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def _reload_yaml_file(self):
self.dirty = False
for c in self.selected_rule_edit_panel.get_children():
self.selected_rule_edit_panel.remove(c)
_DIV._load_config_rule_file()
_DIV.load_config_rule_file()
self.model = self._create_model()
self.view.set_model(self.model)
self.view.expand_all()
Expand Down
57 changes: 57 additions & 0 deletions tests/logitech_receiver/test_diversion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import textwrap

from unittest import mock
from unittest.mock import mock_open

import pytest

from logitech_receiver import diversion


@pytest.fixture
def rule_config():
rule_content = """
%YAML 1.3
---
- MouseGesture: Mouse Left
- KeyPress:
- [Control_L, Alt_L, Left]
- click
...
---
- MouseGesture: Mouse Up
- KeyPress:
- [Super_L, Up]
- click
...
---
- Test: [thumb_wheel_up, 10]
- KeyPress:
- [Control_L, Page_Down]
- click
...
---
"""
return textwrap.dedent(rule_content)


def test_load_rule_config(rule_config):
expected_rules = [
[
diversion.MouseGesture,
diversion.KeyPress,
],
[diversion.MouseGesture, diversion.KeyPress],
[diversion.Test, diversion.KeyPress],
]

with mock.patch("builtins.open", new=mock_open(read_data=rule_config)):
loaded_rules = diversion._load_rule_config(file_path=mock.Mock())

assert len(loaded_rules.components) == 2 # predefined and user configured rules
user_configured_rules = loaded_rules.components[0]
assert isinstance(user_configured_rules, diversion.Rule)

for components, expected_components in zip(user_configured_rules.components, expected_rules):
for component, expected_component in zip(components.components, expected_components):
assert isinstance(component, expected_component)

0 comments on commit 5ae30cb

Please sign in to comment.