Major refactor of Ameba Control Panel v3.1.0: - Three-column layout: icon sidebar, config+history, log view - Dracula PRO theme with light/dark toggle - DTR/RTS GPIO control (replaces ASCII commands) - Multi-CDC firmware support for AmebaSmart control device - Dynamic DUT tabs with +/- management - NN Model flash image support - Settings dialog (Font, Serial, Flash, Command tabs) - Background port scanning, debounced session store - Adaptive log flush rate, format cache optimization - Smooth sidebar animation, deferred startup - pytest test framework with session/log/settings tests - Thread safety fixes: _alive guards, parented timers, safe baud parsing - Find highlight: needle-only highlighting with focused match color - Partial line buffering for table output - PyInstaller packaging with version stamp and module exclusions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
67 lines
2.8 KiB
Python
67 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from unittest.mock import patch
|
|
|
|
from ameba_control_panel.services.session_store import SessionStore
|
|
|
|
|
|
class TestSessionStore:
|
|
def test_load_empty(self, tmp_path):
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store = SessionStore()
|
|
assert store.get("nonexistent") == {}
|
|
|
|
def test_set_and_get(self, tmp_path):
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store = SessionStore()
|
|
store.set("dut_1", {"port": "COM3", "baud": 115200})
|
|
store.save_now()
|
|
# Reload from disk
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store2 = SessionStore()
|
|
result = store2.get("dut_1")
|
|
assert result["port"] == "COM3"
|
|
assert result["baud"] == 115200
|
|
|
|
def test_remove(self, tmp_path):
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store = SessionStore()
|
|
store.set("dut_1", {"port": "COM3"})
|
|
store.remove("dut_1")
|
|
store.save_now()
|
|
assert store.get("dut_1") == {}
|
|
|
|
def test_tab_list(self, tmp_path):
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store = SessionStore()
|
|
tabs = [{"key": "dut_1", "label": "DUT 1"}, {"key": "dut_2", "label": "DUT 2"}]
|
|
store.set_tab_list(tabs)
|
|
store.save_now()
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store2 = SessionStore()
|
|
assert store2.get_tab_list() == tabs
|
|
|
|
def test_corrupt_file_recovers(self, tmp_path):
|
|
(tmp_path / "session.json").write_text("{bad json", encoding="utf-8")
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store = SessionStore()
|
|
assert store.get("anything") == {}
|
|
|
|
def test_schema_version_written(self, tmp_path):
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store = SessionStore()
|
|
store.set("x", {"val": 1})
|
|
store.save_now()
|
|
data = json.loads((tmp_path / "session.json").read_text())
|
|
assert data["_schema_version"] == 1
|
|
|
|
def test_atomic_write(self, tmp_path):
|
|
with patch("ameba_control_panel.services.session_store.app_data_dir", return_value=tmp_path):
|
|
store = SessionStore()
|
|
store.set("test", {"data": "value"})
|
|
store.save_now()
|
|
# No .tmp file should remain
|
|
assert not (tmp_path / "session.json.tmp").exists()
|
|
assert (tmp_path / "session.json").exists()
|