test: address review feedback — fixture lifecycle, test names, ClassVar

- ci-fixture-plugin: call display_manager.clear() before rendering (per
  plugin guidelines — the fixture should model a well-behaved plugin),
  add a class docstring, and document why Pillow is deliberately not
  pinned in its requirements.txt (core dependency; harness installs
  nothing).
- Rename two tests whose names contradicted their assertions:
  test_unparseable_core_version_is_compatible ->
  test_unparseable_core_with_high_floor_is_blocked, and
  test_unreadable_secrets_file... -> test_corrupt_secrets_file...
- Annotate TestGetSchemaProperty.SCHEMA as ClassVar (RUF012).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NohXi78cwsAKtN1sCfxjUh
This commit is contained in:
Claude
2026-08-06 22:38:48 +00:00
parent b8b0c8e2e2
commit d159f2866d
5 changed files with 17 additions and 4 deletions
+6
View File
@@ -16,10 +16,16 @@ from src.plugin_system.base_plugin import BasePlugin
class CIFixturePlugin(BasePlugin):
"""Deterministic CI-only fixture plugin: renders a border + diagonals
pattern sized from the display's declared dimensions. Never shipped to
devices; exists solely so the plugin safety harness has a real plugin
to exercise in CI."""
def update(self) -> None:
"""Nothing to fetch — the render is self-contained."""
def display(self, force_clear: bool = False) -> None:
self.display_manager.clear()
width = self.display_manager.matrix.width
height = self.display_manager.matrix.height
border = tuple(self.config.get("border_color", [0, 255, 0]))
@@ -1 +1,7 @@
# No dependencies — the fixture must load in any environment.
#
# Pillow is deliberately NOT pinned here even though manager.py imports
# PIL: it is a core LEDMatrix dependency (see the repo-root
# requirements.txt), so it is always present wherever the harness runs,
# and the harness loads plugins with install_deps=False anyway. Pinning
# it here would only invite a needless pip install during test runs.
+1 -1
View File
@@ -216,7 +216,7 @@ class TestCheck:
assert ok is False
assert "2.0.0 - 2.9.9" in reason
def test_unparseable_core_version_is_compatible(self):
def test_unparseable_core_with_high_floor_is_blocked(self):
manifest = {"min_ledmatrix_version": "3.2.0",
"compatible_versions": [">=3.2.0"]}
# An unparseable core version is "unknown", not "old"... but note
+2 -2
View File
@@ -99,9 +99,9 @@ class TestSaveStripsSecrets:
on_disk = json.loads((tmp_path / "config.json").read_text())
assert on_disk == {"timezone": "UTC"}
def test_unreadable_secrets_file_writes_secrets_to_config_json(self, tmp_path):
def test_corrupt_secrets_file_writes_secrets_to_config_json(self, tmp_path):
# SUSPECTED BUG (characterized, not fixed): when the secrets file is
# unreadable/corrupt at save time, save_config proceeds without
# corrupt (or otherwise unloadable) at save time, save_config proceeds without
# stripping — writing the merged secrets into config.json in
# plaintext. The code comments acknowledge the tradeoff (it prevents
# data loss); this test pins the behavior so any future change to it
+2 -1
View File
@@ -11,6 +11,7 @@ characterized quirks marked below.
import sys
from pathlib import Path
from typing import Any, ClassVar, Dict
import pytest
@@ -153,7 +154,7 @@ class TestParseFormValue:
class TestGetSchemaProperty:
SCHEMA = {
SCHEMA: ClassVar[Dict[str, Any]] = {
"properties": {
"brightness": {"type": "integer"},
"customization": {