Skip to content

Commit

Permalink
Switch to pytest fixtures
Browse files Browse the repository at this point in the history
  • Loading branch information
pzbitskiy committed Aug 6, 2024
1 parent ae8214b commit 3c80502
Show file tree
Hide file tree
Showing 5 changed files with 307 additions and 235 deletions.
17 changes: 15 additions & 2 deletions src/media_center_kb/relays.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from abc import ABC, abstractmethod
from enum import Enum
import logging
from types import SimpleNamespace


Expand Down Expand Up @@ -88,10 +87,24 @@ def inner():
return inner


class Logger(ABC):
"""Logger interface to make mypy happier"""

def debug(self, msg, *args, **kwargs):
"""
Log 'msg % args' with severity 'DEBUG'.
"""

def info(self, msg, *args, **kwargs):
"""
Log 'msg % args' with severity 'INFO'.
"""


class RelayModule(RelayModuleIf):
"""Relay module class"""

def __init__(self, gpio: GPioIf, logger: logging.Logger):
def __init__(self, gpio: GPioIf, logger: Logger):
self._gpio: GPioIf = gpio
self._logger = logger
self.reset()
Expand Down
104 changes: 104 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""pytest fixtures and stuff"""

from typing import Dict

import pytest

import media_center_kb.control
from media_center_kb.relays import RelayModule, GPioIf, RelayIf
from .mocks import GPMock, LoggerMock, ShellMock, YspMock


class WrapRelays(RelayModule): # pylint: disable=too-few-public-methods
"""Relays class wrapper for tests"""

def __init__(self, gpio: GPioIf): # pylint: disable=redefined-outer-name
self.cached: Dict[int, RelayIf] = {}
self.max_relays = 4
self.iter_idx = 1
super().__init__(gpio, LoggerMock())

def relay(self, relay: int):
"""Return a wrapped relay with extra methods for testing"""

class Wrapped(RelayIf):
"""Wrap relay to track state changes"""

def __init__(self, orig):
self.is_on = None
self.relay = orig

def on(self): # pylint: disable=invalid-name
"""enable and save state"""
self.is_on = True
self.relay.on()

def off(self):
"""disable and save state"""
self.is_on = False
self.relay.off()

def enabled(self) -> bool:
return self.is_on

result = self.cached.get(relay)
if not result:
result = Wrapped(super().relay(relay))
self.cached[relay] = result
return result

def reset(self):
"""Wrapped Relays.reset"""
super().reset()
for relay in self.cached.values():
relay.is_on = False

def __iter__(self):
self.iter_idx = 1
return self

def __next__(self):
if self.iter_idx <= self.max_relays:
res = self.relay(self.iter_idx)
self.iter_idx += 1
return res
raise StopIteration


@pytest.fixture
def nosleep():
"""disable 1s sleep on graceful shutdown"""
orig = media_center_kb.control.sleeper
media_center_kb.control.sleeper = lambda x: None
yield
media_center_kb.control.sleeper = orig


@pytest.fixture
def gpio() -> GPioIf:
"""gpio for tests"""
return GPMock()


@pytest.fixture
def rel_module(gpio: GPioIf) -> RelayModule: # pylint: disable=redefined-outer-name
"""relay module for tests"""
return RelayModule(gpio, LoggerMock())


@pytest.fixture
def relays(gpio: GPioIf) -> WrapRelays: # pylint: disable=redefined-outer-name
"""wrapped relay module for tests"""
return WrapRelays(gpio)


@pytest.fixture
def ysp():
"""ysp mock"""
return YspMock()


@pytest.fixture
def shell():
"""shell mock"""
return ShellMock()
4 changes: 2 additions & 2 deletions tests/mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
from typing import Callable

from media_center_kb.relays import GPioIf
from media_center_kb.relays import GPioIf, Logger

# pylint: disable=missing-function-docstring,invalid-name

Expand Down Expand Up @@ -122,7 +122,7 @@ def __call__(self, cmd):
self.last_cmd = cmd


class LoggerMock:
class LoggerMock(Logger):
"""Mock for logging"""

def __init__(self):
Expand Down
Loading

0 comments on commit 3c80502

Please sign in to comment.