docs(code): document deliberate duplicates instead of merging them

The audit surfaced several near-duplicate implementations that turned
out to be either deliberate forks or behaviorally different — merging
any of them would risk changing behavior on installed devices, so each
now carries an explicit comment stating the relationship:

- VisualDisplayManager: headless fork of DisplayManager; header now
  lists the ~15 mirrored methods and warns that DisplayManager changes
  must be mirrored.
- normalize_abbreviation: LogoDownloader's version (called directly by
  nine scoreboard plugins) replaces filesystem-unsafe characters;
  LogoHelper's strips spaces. Logo filenames on existing installs
  depend on both behaviors staying put.
- The two PluginTestBase classes: the shipped one is plugin-author
  API, the repo's own richer harness lives in test/plugins/ — now
  cross-referenced.

Also verified (no change needed): ConfigManager's backup/rollback
methods genuinely delegate to AtomicConfigManager, and SportsCore
already delegates _read_bdf_native_size to FontManager.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SXb4mKcAkVaxkeTb3YnAdr
This commit is contained in:
Claude
2026-08-06 00:08:01 +00:00
parent b68c1fa8fe
commit 0ec3431815
4 changed files with 33 additions and 3 deletions
+9 -2
View File
@@ -187,10 +187,17 @@ class LogoHelper:
def normalize_abbreviation(self, team_abbr: str) -> str: def normalize_abbreviation(self, team_abbr: str) -> str:
""" """
Normalize team abbreviation for consistent filename usage. Normalize team abbreviation for consistent filename usage.
NOTE: this deliberately differs from
LogoDownloader.normalize_abbreviation (src/logo_downloader.py),
which replaces filesystem-unsafe characters (/ \\ : * ? " < > |)
but does not strip spaces. Plugins call the LogoDownloader
version; changing either implementation changes which logo
filenames resolve on existing installs.
Args: Args:
team_abbr: Raw team abbreviation team_abbr: Raw team abbreviation
Returns: Returns:
Normalized abbreviation Normalized abbreviation
""" """
+8 -1
View File
@@ -118,7 +118,14 @@ class LogoDownloader:
@staticmethod @staticmethod
def normalize_abbreviation(abbreviation: str) -> str: def normalize_abbreviation(abbreviation: str) -> str:
"""Normalize team abbreviation for consistent filename usage.""" """Normalize team abbreviation for consistent filename usage.
Public API: sports scoreboard plugins call this directly.
NOTE: LogoHelper.normalize_abbreviation (src/common/logo_helper.py)
is a deliberately different variant (strips spaces, fewer character
replacements) — keep both behaviors stable; logo filenames on
existing installs depend on them.
"""
# Handle special characters that can cause filesystem issues # Handle special characters that can cause filesystem issues
normalized = abbreviation.upper() normalized = abbreviation.upper()
@@ -2,6 +2,11 @@
Base test class for LEDMatrix plugins. Base test class for LEDMatrix plugins.
Provides common fixtures and helper methods for plugin testing. Provides common fixtures and helper methods for plugin testing.
Note: this is the plugin-author-facing base class shipped with the
core (importable as src.plugin_system.testing.plugin_test_base). The
repo's own plugin tests use a separate, richer harness in
test/plugins/test_plugin_base.py — the two are intentionally distinct.
""" """
import unittest import unittest
@@ -10,6 +10,17 @@ without requiring hardware or the RGBMatrixEmulator. Used for:
Unlike MockDisplayManager (which logs calls but doesn't render) or Unlike MockDisplayManager (which logs calls but doesn't render) or
MagicMock (which tracks nothing visual), this class creates a real MagicMock (which tracks nothing visual), this class creates a real
PIL Image canvas and draws text using the actual project fonts. PIL Image canvas and draws text using the actual project fonts.
MAINTENANCE WARNING: this class is a deliberate fork of
src/display_manager.py so it can run without hardware. It mirrors
these DisplayManager methods by name and behavior: _load_fonts,
_draw_bdf_text, get_font_height, get_text_width, draw_text,
draw_text_with_icons, draw_weather_icon (and the _draw_sun/_draw_cloud/
_draw_rain/_draw_snow/_draw_storm family), format_date_with_ordinal,
capture_mode, set_scrolling_state, is_currently_scrolling,
process_deferred_updates, update_display, render_size. A behavior
change to any of those in DisplayManager must be mirrored here, or
plugin visual tests will pass against stale behavior.
""" """
import math import math