Python · 2365 bytes Raw Blame History
1 """Tests for :mod:`dlm_sway.core.result`."""
2
3 from __future__ import annotations
4
5 from dataclasses import FrozenInstanceError
6
7 import pytest
8
9 from dlm_sway.core.result import (
10 DEFAULT_COMPONENT_WEIGHTS,
11 ProbeResult,
12 SuiteResult,
13 SwayScore,
14 Verdict,
15 utcnow,
16 )
17
18
19 class TestVerdict:
20 def test_is_str_enum(self) -> None:
21 assert Verdict.PASS.value == "pass"
22 assert str(Verdict.WARN.value) == "warn"
23
24 def test_all_expected_members(self) -> None:
25 assert {v.value for v in Verdict} == {
26 "pass",
27 "fail",
28 "warn",
29 "skip",
30 "error",
31 }
32
33
34 class TestProbeResult:
35 def test_minimum_construction(self) -> None:
36 r = ProbeResult(name="t", kind="delta_kl", verdict=Verdict.PASS, score=0.82)
37 assert r.raw is None
38 assert r.evidence == {}
39 assert r.message == ""
40 assert r.duration_s == 0.0
41
42 def test_frozen(self) -> None:
43 r = ProbeResult(name="t", kind="t", verdict=Verdict.PASS, score=0.5)
44 with pytest.raises(FrozenInstanceError):
45 r.score = 0.6 # type: ignore[misc]
46
47
48 class TestSuiteResult:
49 def test_wall_seconds(self) -> None:
50 from datetime import timedelta
51
52 started = utcnow()
53 finished = started + timedelta(seconds=2, milliseconds=500)
54 result = SuiteResult(
55 spec_path="sway.yaml",
56 started_at=started,
57 finished_at=finished,
58 base_model_id="b",
59 adapter_id="a",
60 sway_version="0.1.0.dev0",
61 )
62 assert result.wall_seconds == pytest.approx(2.5, abs=1e-6)
63
64
65 class TestSwayScore:
66 def test_default_weights_sum_to_one(self) -> None:
67 assert abs(sum(DEFAULT_COMPONENT_WEIGHTS.values()) - 1.0) < 1e-9
68
69 def test_band_boundaries(self) -> None:
70 assert SwayScore.band_for(0.0) == "noise"
71 assert SwayScore.band_for(0.29) == "noise"
72 assert SwayScore.band_for(0.30) == "partial"
73 assert SwayScore.band_for(0.59) == "partial"
74 assert SwayScore.band_for(0.60) == "healthy"
75 assert SwayScore.band_for(0.85) == "healthy"
76 assert SwayScore.band_for(0.851) == "suspicious"
77 assert SwayScore.band_for(0.99) == "suspicious"
78
79
80 def test_utcnow_is_tz_aware() -> None:
81 now = utcnow()
82 assert now.tzinfo is not None