Skip to content

Commit

Permalink
Merge dev to main (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbruno25 authored Apr 26, 2023
1 parent f354a00 commit 7eda6e3
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 61 deletions.
14 changes: 0 additions & 14 deletions .github/workflows/pre-commit.yml

This file was deleted.

37 changes: 37 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI

on:
pull_request:
push:
branches: ['main', 'dev']

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: pre-commit/[email protected]

test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install poetry
poetry install
- name: Setup container display
# https://arbitrary-but-fixed.net/2022/01/21/headless-gui-github-actions.html
run: Xvfb :1 -screen 0 1600x1200x24 &
- name: Test with pytest
run: poetry run pytest -v
env:
DISPLAY: :1
26 changes: 0 additions & 26 deletions .github/workflows/tox.yml

This file was deleted.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ python = ">=3.8, <4.0"
pyserial = "^3.5"
python-can = "^4.1.0"
dearpygui = "^1.9.0"
dearpygui-ext = "^0.9.5"

[tool.poetry.group.dev.dependencies]
pytest = "^7.2.2"
Expand Down
5 changes: 1 addition & 4 deletions src/can_explorer/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ def set_state(self, state: bool) -> None:
"""
self._state = State(state)

if self._state:
self.start()
else:
self.stop()
self.start() if self._state else self.stop()

def repopulate(self) -> None:
"""
Expand Down
8 changes: 4 additions & 4 deletions src/can_explorer/can_bus.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from collections import defaultdict, deque
from typing import Final
from typing import Final, Optional

from can.bus import BusABC
from can.interfaces import VALID_INTERFACES
Expand Down Expand Up @@ -41,9 +41,9 @@ def __getitem__(self, index) -> tuple: # type: ignore [override]

class Recorder(defaultdict):
_active = False
_bus: BusABC
_notifier: Notifier
_listener: _Listener
_bus: Optional[BusABC] = None

def __init__(self):
super().__init__(PayloadBuffer)
Expand All @@ -57,7 +57,7 @@ def start(self) -> None:
return

self._listener = _Listener(self)
self._notifier = Notifier(self.bus, [self._listener])
self._notifier = Notifier(self._bus, [self._listener])
self._active = True

def stop(self) -> None:
Expand All @@ -67,4 +67,4 @@ def stop(self) -> None:
self._notifier.stop() # type: ignore [union-attr]

def set_bus(self, bus: BusABC) -> None:
self.bus = bus
self._bus = bus
24 changes: 22 additions & 2 deletions src/can_explorer/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Callable, Final, Iterable, Union

import dearpygui.dearpygui as dpg
from dearpygui_ext.themes import create_theme_imgui_light

from can_explorer.can_bus import PayloadBuffer
from can_explorer.resources import Percentage
Expand All @@ -20,8 +21,14 @@ class Default:


class Font:
DEFAULT: str
LABEL: str
DEFAULT: int
LABEL: int


class Theme:
DEFAULT: int
LIGHT: int
MIDNIGHT: int


@unique
Expand Down Expand Up @@ -91,6 +98,11 @@ def _init_fonts():


def _init_themes():
global Theme

Theme.DEFAULT = 0
Theme.LIGHT = create_theme_imgui_light()

default_background = (50, 50, 50, 255)
with dpg.theme() as disabled_theme:
with dpg.theme_component(dpg.mvButton, enabled_state=False):
Expand Down Expand Up @@ -195,6 +207,14 @@ def _settings_tab() -> None:
dpg.add_spacer(height=5)

with dpg.collapsing_header(label="GUI"):

def light_theme_calllback(sender, app_data, user_data):
dpg.bind_theme(Theme.LIGHT if dpg.get_value(sender) else Theme.DEFAULT)

with dpg.group(horizontal=True):
dpg.add_text("Light Theme")
dpg.add_checkbox(callback=light_theme_calllback)

dpg.add_button(
label="Launch Font Manager", width=-1, callback=dpg.show_font_manager
)
Expand Down
48 changes: 42 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,52 @@
from unittest.mock import Mock, patch

import pytest
from can_explorer import app, can_bus, plotting


@pytest.fixture
def mock_buffer():
with patch("can_explorer.can_bus.PayloadBuffer", autospec=True) as mock:
yield mock


@pytest.fixture
def mock_listener():
with patch("can_explorer.can_bus._Listener", autospec=True) as mock:
yield mock


@pytest.fixture
def mock_recorder():
...
def mock_notifier():
with patch("can_explorer.can_bus.Notifier", autospec=True) as mock:
yield mock


@pytest.fixture
def mock_plot_manager():
...
def fake_recorder(mock_listener, mock_notifier):
recorder = can_bus.Recorder()

with patch("can_explorer.can_bus.Recorder") as mock:
mock.return_value = recorder

yield recorder


@pytest.fixture
def fake_manager():
with patch("can_explorer.plotting.Row"):
manager = plotting.PlotManager()

with patch("can_explorer.plotting.PlotManager") as mock:
mock.return_value = manager

yield manager


@pytest.fixture
def mock_app():
...
def fake_app(fake_manager, fake_recorder):
main_app = app.MainApp()
main_app.plot_manager = fake_manager
main_app.can_recorder = fake_recorder
main_app.set_bus(Mock())
yield main_app
45 changes: 40 additions & 5 deletions tests/test_app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
# for 3.8, 3.9, etc.
def test_app_launches_without_errors():
...
from random import sample
from threading import Thread
from time import sleep

import dearpygui.dearpygui as dpg
from can_explorer import app

def test_app_populates_data_in_ascending_order():
...
DELAY = 0.1


def test_app_launch_basic():
Thread(target=app.main).start()
sleep(DELAY)
assert dpg.is_dearpygui_running()
dpg.stop_dearpygui()


def test_set_app_state_starts_worker(fake_app):
fake_app.set_state(True)
assert fake_app._worker.is_alive()


def test_set_app_state_stops_worker(fake_app):
fake_app.set_state(True)
assert fake_app._worker.is_alive()
fake_app.set_state(False)
assert not fake_app._worker.is_alive()


def test_app_populates_data_in_ascending_order(fake_app, fake_manager, fake_recorder):
data = sample(range(250), 25)

fake_app.start()

for i in data:
fake_recorder[i] = [0]

sleep(DELAY)
sorted_data = list(sorted(data))
sorted_keys = list(fake_manager.row.keys())

assert sorted_data == sorted_keys

0 comments on commit 7eda6e3

Please sign in to comment.