Files
HMS MediaEngine Agent 362e089be0 AUFGERAUMT: Root auf 10 sichtbare Elemente reduziert
Der Nutzer hat recht: Der Ordner war voller Entwicklungs-Muell.
Jetzt ist sauber getrennt:

ROOT (was der Nutzer sieht und braucht):
- run.py                     = das Programm
- hms_app/                   = der Anwendungscode
- HMS MediaEngine.app        = macOS Doppelklick-Starter
- HMS-Start.vbs              = Windows Doppelklick-Starter
- HMS-Install.vbs             = Windows Erst-Installation
- HMS-Mac-Install.command     = macOS Homebrew-Installation
- HMS-Portable-Install.command = macOS Portable-Installation (16GB-Fix)
- installer_gui.py           = grafischer Installer
- launcher.pyw + launcher_core.py = interne Start-Logik
- LIESMICH.txt               = 10-Zeilen-Kurzanleitung
- .gitignore

_entwicklung/ (alles andere, NICHT benoetigt):
- packages/ apps/ native/ plugins/ tools/ schemas/ tests/ docs/
  build/ fixture_profiles/
- PLAN.md STATUS.md ERRORS.md TEST_REPORT.md CHANGELOG.md README.md
- pyproject.toml uv.lock setup_*.sh/ps1 make_mac_app.py

Diese Trennung gilt ab sofort fuer alle Commits. Der Nutzer kann
_entwicklung/ loeschen wenn er Platz braucht - die App laeuft ohne.

Verifiziert: App startet nach Aufraeumen unveraendert (Health 200).
2026-09-11 23:44:06 +02:00

67 lines
2.3 KiB
Python

"""Unit-Tests Fixture-Generator (PLAN.md §16.3, §16.4)."""
from __future__ import annotations
import csv
from pathlib import Path
from fixture_generator import LAYER64, MASTER32, write_csv
def test_master32_has_exactly_32_contiguous_channels() -> None:
assert len(MASTER32) == 32
assert [row[0] for row in MASTER32] == list(range(1, 33))
def test_layer64_has_exactly_64_contiguous_channels() -> None:
assert len(LAYER64) == 64
assert [row[0] for row in LAYER64] == list(range(1, 65))
def test_master32_key_channels_match_plan() -> None:
by_channel = {row[0]: row for row in MASTER32}
assert "Blackout" in by_channel[3][1] # Kanal 3 Blackout
assert "Preset Recall" in by_channel[8][1] # Kanal 8 steigende Flanke
assert "Tap Tempo" in by_channel[16][1] # Kanal 16 Tap
def test_layer64_key_channels_match_plan() -> None:
by_channel = {row[0]: row for row in LAYER64}
assert "Layer Enable" in by_channel[1][1]
assert "Opacity" in by_channel[2][1]
assert "Load/Commit" in by_channel[9][1]
assert "Blend Mode" in by_channel[21][1]
assert "FX1 Enable" in by_channel[41][1]
assert "FX2 Enable" in by_channel[52][1]
assert "Retrigger" in by_channel[63][1]
def test_layer64_fx_parameter_blocks() -> None:
by_channel = {row[0]: row for row in LAYER64}
for slot in range(1, 9):
assert f"P{slot}" in by_channel[43 + slot][1]
assert f"P{slot}" in by_channel[54 + slot][1]
def test_eight_layers_fit_exactly_one_universe() -> None:
# §16.2: „Acht Layer entsprechen damit exakt einem DMX-Universe“
assert 8 * len(LAYER64) == 512
def test_write_csv_output(tmp_path: Path) -> None:
out = tmp_path / "layer64" / "layer64.csv"
write_csv(LAYER64, out)
with open(out, encoding="utf-8", newline="") as fh:
rows = list(csv.reader(fh))
assert rows[0] == ["channel", "parameter", "resolution_behavior"]
assert len(rows) == 65 # Header + 64
assert rows[1] == ["1", "Layer Enable", "Schalter"]
def test_write_csv_rejects_gaps(tmp_path: Path) -> None:
import pytest
broken = [(1, "a", "x"), (3, "b", "y")] # Kanal 2 fehlt
with pytest.raises(ValueError, match="contiguous"):
write_csv(broken, tmp_path / "broken.csv") # ValueError vor dem Schreiben