| 1 | """Tests for the exception hierarchy.""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import pytest |
| 6 | |
| 7 | from dlm_sway.core.errors import ( |
| 8 | BackendNotAvailableError, |
| 9 | ProbeError, |
| 10 | SpecValidationError, |
| 11 | SwayError, |
| 12 | ) |
| 13 | |
| 14 | |
| 15 | class TestSwayError: |
| 16 | def test_is_root_exception(self) -> None: |
| 17 | assert issubclass(SpecValidationError, SwayError) |
| 18 | assert issubclass(BackendNotAvailableError, SwayError) |
| 19 | assert issubclass(ProbeError, SwayError) |
| 20 | |
| 21 | def test_raised_and_caught_as_sway_error(self) -> None: |
| 22 | with pytest.raises(SwayError): |
| 23 | raise ProbeError("delta_kl", "shape mismatch") |
| 24 | |
| 25 | |
| 26 | class TestSpecValidationError: |
| 27 | def test_format_without_source(self) -> None: |
| 28 | err = SpecValidationError("unknown key 'topp'") |
| 29 | assert str(err) == "unknown key 'topp'" |
| 30 | assert err.source is None |
| 31 | |
| 32 | def test_format_with_source(self) -> None: |
| 33 | err = SpecValidationError("unknown key 'topp'", source="sway.yaml") |
| 34 | assert str(err) == "sway.yaml: unknown key 'topp'" |
| 35 | assert err.source == "sway.yaml" |
| 36 | |
| 37 | |
| 38 | class TestBackendNotAvailableError: |
| 39 | def test_hint_rendered_in_message(self) -> None: |
| 40 | err = BackendNotAvailableError("hf", extra="hf") |
| 41 | assert "pip install 'dlm-sway[hf]'" in str(err) |
| 42 | assert err.backend == "hf" |
| 43 | assert err.extra == "hf" |
| 44 | |
| 45 | def test_appends_optional_hint(self) -> None: |
| 46 | err = BackendNotAvailableError("mlx", extra="mlx", hint="Apple Silicon only.") |
| 47 | assert "Apple Silicon only." in str(err) |
| 48 | |
| 49 | |
| 50 | class TestProbeError: |
| 51 | def test_includes_probe_name(self) -> None: |
| 52 | err = ProbeError("delta_kl", "NaN logits") |
| 53 | assert "delta_kl" in str(err) |
| 54 | assert "NaN logits" in str(err) |
| 55 | assert err.probe == "delta_kl" |