mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-01 16:58:06 +00:00
Discoverability: re-export the adaptive layout/image API from src.common (the blessed-helpers package plugin authors already know) — canonical paths stay src.adaptive_layout / src.adaptive_images so nothing breaks. Document it in src/common/README.md and cross-link ADAPTIVE_LAYOUT.md from the developer docs authors actually read (quick reference, API reference, advanced dev, font manager, dev preview, plugin dev guide); ADAPTIVE_LAYOUT.md gains adaptive-images, composite-layouts and preserving-user-customization sections. Compat: PluginLoader now logs one advisory warning (never raises) when a plugin's manifest declares a min LEDMatrix version newer than the running core, checking the min_ledmatrix_version / requires.* / versions[] spellings found in the wild. Guarded against stale core version numbers. src/__init__.py __version__ bumped 1.0.0 -> 3.1.0 to match the latest release tag (v3.1.0) — it had never been updated and the compat check needs a truthful number. NOTE: verify this matches the intended release numbering before the next tag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
71 lines
2.8 KiB
Python
71 lines
2.8 KiB
Python
"""Tests for the plugin loader's advisory version-compatibility warning."""
|
|
|
|
import logging
|
|
|
|
import pytest
|
|
|
|
from src.plugin_system.plugin_loader import PluginLoader
|
|
|
|
|
|
@pytest.fixture
|
|
def loader():
|
|
return PluginLoader(logger=logging.getLogger("test-loader"))
|
|
|
|
|
|
def _warnings(caplog):
|
|
return [r for r in caplog.records if r.levelno == logging.WARNING]
|
|
|
|
|
|
class TestParseSemver:
|
|
def test_basic(self, loader):
|
|
assert loader._parse_semver("3.1.0") == (3, 1, 0)
|
|
assert loader._parse_semver("v2.0") == (2, 0, 0)
|
|
assert loader._parse_semver("2.0.0-beta.1") == (2, 0, 0)
|
|
|
|
def test_unparseable(self, loader):
|
|
assert loader._parse_semver(None) is None
|
|
assert loader._parse_semver(123) is None
|
|
|
|
|
|
class TestWarnIfIncompatible:
|
|
def test_warns_when_plugin_needs_newer_core(self, loader, caplog, monkeypatch):
|
|
import src
|
|
monkeypatch.setattr(src, "__version__", "3.1.0")
|
|
with caplog.at_level(logging.WARNING, logger="test-loader"):
|
|
loader._warn_if_incompatible("p", {"min_ledmatrix_version": "9.0.0"})
|
|
assert len(_warnings(caplog)) == 1
|
|
assert "9.0.0" in _warnings(caplog)[0].message
|
|
|
|
def test_silent_when_compatible(self, loader, caplog, monkeypatch):
|
|
import src
|
|
monkeypatch.setattr(src, "__version__", "3.1.0")
|
|
with caplog.at_level(logging.WARNING, logger="test-loader"):
|
|
loader._warn_if_incompatible("p", {"min_ledmatrix_version": "2.0.0"})
|
|
assert not _warnings(caplog)
|
|
|
|
def test_silent_when_field_absent(self, loader, caplog):
|
|
with caplog.at_level(logging.WARNING, logger="test-loader"):
|
|
loader._warn_if_incompatible("p", {"name": "no version fields"})
|
|
assert not _warnings(caplog)
|
|
|
|
def test_reads_requires_and_versions_spellings(self, loader, caplog, monkeypatch):
|
|
import src
|
|
monkeypatch.setattr(src, "__version__", "3.1.0")
|
|
with caplog.at_level(logging.WARNING, logger="test-loader"):
|
|
loader._warn_if_incompatible(
|
|
"a", {"requires": {"min_ledmatrix_version": "9.0.0"}})
|
|
loader._warn_if_incompatible(
|
|
"b", {"versions": [{"ledmatrix_min_version": "9.0.0"}]})
|
|
loader._warn_if_incompatible(
|
|
"c", {"versions": [{"ledmatrix_min": "9.0.0"}]})
|
|
assert len(_warnings(caplog)) == 3
|
|
|
|
def test_stale_core_version_skips_comparison(self, loader, caplog, monkeypatch):
|
|
# Anti-spam guard: a core whose __version__ is below the ecosystem
|
|
# floor must not warn about every plugin.
|
|
import src
|
|
monkeypatch.setattr(src, "__version__", "1.0.0")
|
|
with caplog.at_level(logging.WARNING, logger="test-loader"):
|
|
loader._warn_if_incompatible("p", {"min_ledmatrix_version": "2.0.0"})
|
|
assert not _warnings(caplog)
|