File size: 2,688 Bytes
52412a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0d00572
 
52412a3
0d00572
52412a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""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")