Files
kunail0804-ComfyUI-Scene-Co…/tests/test_message_codes.py
T
3f0358bfa9 feat(validator): implement the Scene Validator (#11) (#55)
Add the Scene Validator per MASTER_SPEC §14 and a central message-code registry.

- compiler/common/message_codes.py: single source of truth for message codes
  (Appendix B SC0001-SC0014 plus documented extensions SC0015 Unexpected Field
  Removed, SC0016 Empty Concept Removed, SC0017 Interaction Dropped) with a
  message() factory that pins each code's severity and title.
- compiler/validator/scene_validator.py: validate_scene(scene_json, config,
  logger=None) -> CompilerResult.
  - Strict schema validation classifies failures: missing required -> SC0009,
    wrong type/malformed -> SC0002 (Errors that stop the compilation).
  - Recoverable normalization: unexpected fields -> SC0015 warning + removed
    (suppressed when config.validator.allow_unknown_fields is true); empty/
    whitespace concepts -> SC0016 warning + removed after trimming; interactions
    whose participants reference a non-existent character -> SC0017 warning +
    dropped.
  - Never creates concepts, generates tags, or does KB lookup. Output is a
    Scene model wrapped in a CompilerResult; order is deterministic.

New warning codes (SC0015-SC0017) are extensions to be folded into Appendix B.

Tests: valid input, hard errors (SC0009/SC0002) that stop, recoverable warnings
(SC0015/SC0016/SC0017), allow_unknown_fields suppression, determinism, and the
code registry.

Co-authored-by: kunail0804 <kunail0804@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 19:52:24 +02:00

32 lines
861 B
Python

"""Tests for the message-code registry (issue #11)."""
from __future__ import annotations
import pytest
from compiler.common.message_codes import CODES, message
from compiler.common.result import Severity
def test_appendix_b_and_extensions_registered() -> None:
assert "SC0001" in CODES
assert "SC0014" in CODES
assert {"SC0015", "SC0016", "SC0017"}.issubset(CODES)
def test_message_uses_registry_severity_and_title() -> None:
m = message("SC0009", "missing")
assert m.severity is Severity.ERROR
assert m.title == "Missing Required Field"
assert m.code == "SC0009"
def test_message_carries_context() -> None:
m = message("SC0015", "removed", path="characters/0")
assert m.context["path"] == "characters/0"
def test_unknown_code_raises() -> None:
with pytest.raises(KeyError):
message("SC9999", "nope")