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>
61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
from unittest.mock import patch
|
|
|
|
from ameba_control_panel.config import Direction
|
|
from ameba_control_panel.services.log_buffer import LogBuffer, LogLine
|
|
|
|
|
|
class TestLogBuffer:
|
|
def test_append_returns_logline(self):
|
|
buf = LogBuffer(max_tail=10)
|
|
line = buf.append("hello", Direction.RX)
|
|
assert isinstance(line, LogLine)
|
|
assert line.text == "hello"
|
|
assert line.direction == Direction.RX
|
|
|
|
def test_tail_bounded(self):
|
|
buf = LogBuffer(max_tail=5)
|
|
for i in range(10):
|
|
buf.append(f"line {i}", Direction.RX)
|
|
assert len(buf.tail()) == 5
|
|
assert buf.tail()[0].text == "line 5"
|
|
|
|
def test_archive_bounded(self):
|
|
with patch("ameba_control_panel.services.log_buffer.config.LOG_ARCHIVE_MAX", 3):
|
|
buf = LogBuffer(max_tail=10)
|
|
for i in range(5):
|
|
buf.append(f"line {i}", Direction.RX)
|
|
assert len(buf.archive()) == 3
|
|
assert buf.archive()[0].text == "line 2"
|
|
|
|
def test_clear(self):
|
|
buf = LogBuffer(max_tail=10)
|
|
buf.append("test", Direction.INFO)
|
|
buf.clear()
|
|
assert len(buf.tail()) == 0
|
|
assert len(buf.archive()) == 0
|
|
|
|
def test_as_text(self):
|
|
buf = LogBuffer(max_tail=10)
|
|
buf.append("hello", Direction.RX)
|
|
buf.append("world", Direction.TX)
|
|
text = buf.as_text()
|
|
assert "hello" in text
|
|
assert "world" in text
|
|
|
|
def test_direction_preserved(self):
|
|
buf = LogBuffer(max_tail=10)
|
|
buf.append("rx data", Direction.RX)
|
|
buf.append("tx data", Direction.TX)
|
|
buf.append("info msg", Direction.INFO)
|
|
lines = list(buf.tail())
|
|
assert lines[0].direction == Direction.RX
|
|
assert lines[1].direction == Direction.TX
|
|
assert lines[2].direction == Direction.INFO
|
|
|
|
def test_newline_stripped(self):
|
|
buf = LogBuffer(max_tail=10)
|
|
line = buf.append("with newline\n", Direction.RX)
|
|
assert line.text == "with newline"
|