Picarones / tests /domain /test_provenance_errors.py
Claude
test(rename): dé-sprintage tests/domain (7 fichiers, git mv)
ade2cbf unverified
"""Sprint A14-S4 — ``ProvenanceRecord`` + hiérarchie d'erreurs."""
from __future__ import annotations
from datetime import datetime, timezone
import pytest
from picarones.domain import (
ArtifactValidationError,
CorpusSpecError,
PicaronesError,
ProjectionError,
ProvenanceRecord,
)
class TestProvenanceRecord:
def test_minimal_provenance(self) -> None:
p = ProvenanceRecord(code_version="1.0.0")
assert p.code_version == "1.0.0"
assert p.parameters_hash is None
assert isinstance(p.timestamp, datetime)
assert p.timestamp.tzinfo == timezone.utc
def test_with_parameters_hash(self) -> None:
p = ProvenanceRecord(code_version="1.0.0", parameters_hash="a" * 64)
assert p.parameters_hash == "a" * 64
def test_compatibility_check(self) -> None:
p1 = ProvenanceRecord(code_version="1.0.0", parameters_hash="x" * 64)
p2 = ProvenanceRecord(code_version="1.0.0", parameters_hash="x" * 64)
assert p1.is_compatible_with(p2)
p3 = ProvenanceRecord(code_version="1.0.1", parameters_hash="x" * 64)
assert not p1.is_compatible_with(p3) # code_version diffère
p4 = ProvenanceRecord(code_version="1.0.0", parameters_hash="y" * 64)
assert not p1.is_compatible_with(p4) # parameters_hash diffère
def test_frozen(self) -> None:
from pydantic import ValidationError
p = ProvenanceRecord(code_version="1.0.0")
with pytest.raises(ValidationError):
p.code_version = "1.0.1" # type: ignore[misc]
def test_json_roundtrip(self) -> None:
p = ProvenanceRecord(code_version="1.0.0", parameters_hash="x" * 64)
p2 = ProvenanceRecord.model_validate_json(p.model_dump_json())
assert p == p2
class TestErrorHierarchy:
def test_all_errors_inherit_picarones_error(self) -> None:
for cls in (
ArtifactValidationError,
ProjectionError,
CorpusSpecError,
):
assert issubclass(cls, PicaronesError), (
f"{cls.__name__} doit hériter de PicaronesError pour "
"permettre un `except PicaronesError` global au niveau "
"de la couche transport."
)
def test_picarones_error_is_exception(self) -> None:
assert issubclass(PicaronesError, Exception)
def test_can_raise_and_catch_via_base(self) -> None:
with pytest.raises(PicaronesError):
raise ArtifactValidationError("x")
with pytest.raises(PicaronesError):
raise ProjectionError("y")
with pytest.raises(PicaronesError):
raise CorpusSpecError("z")