"""Entropyk — Unit Tests for Exception Hierarchy. Tests that all exception types exist, inherit correctly, and carry messages. """ import pytest import entropyk class TestExceptionHierarchy: """Tests for Python exception class hierarchy.""" def test_entropyk_error_exists(self): assert hasattr(entropyk, "EntropykError") assert issubclass(entropyk.EntropykError, Exception) def test_solver_error_inherits(self): assert issubclass(entropyk.SolverError, entropyk.EntropykError) def test_timeout_error_inherits(self): assert issubclass(entropyk.TimeoutError, entropyk.SolverError) def test_control_saturation_error_inherits(self): assert issubclass(entropyk.ControlSaturationError, entropyk.SolverError) def test_fluid_error_inherits(self): assert issubclass(entropyk.FluidError, entropyk.EntropykError) def test_component_error_inherits(self): assert issubclass(entropyk.ComponentError, entropyk.EntropykError) def test_topology_error_inherits(self): assert issubclass(entropyk.TopologyError, entropyk.EntropykError) def test_validation_error_inherits(self): assert issubclass(entropyk.ValidationError, entropyk.EntropykError) class TestExceptionMessages: """Tests that exceptions carry descriptive messages.""" def test_entropyk_error_message(self): err = entropyk.EntropykError("test message") assert str(err) == "test message" def test_solver_error_message(self): err = entropyk.SolverError("convergence failed") assert "convergence failed" in str(err) def test_timeout_error_message(self): err = entropyk.TimeoutError("timed out after 5s") assert "timed out" in str(err) def test_fluid_error_message(self): err = entropyk.FluidError("R134a not found") assert "R134a" in str(err) def test_topology_error_message(self): err = entropyk.TopologyError("graph cycle detected") assert "cycle" in str(err) class TestExceptionCatching: """Tests that exceptions can be caught at different hierarchy levels.""" def test_catch_solver_as_entropyk(self): with pytest.raises(entropyk.EntropykError): raise entropyk.SolverError("test") def test_catch_timeout_as_solver(self): with pytest.raises(entropyk.SolverError): raise entropyk.TimeoutError("test") def test_catch_timeout_as_entropyk(self): with pytest.raises(entropyk.EntropykError): raise entropyk.TimeoutError("test") def test_catch_fluid_as_entropyk(self): with pytest.raises(entropyk.EntropykError): raise entropyk.FluidError("test") def test_catch_component_as_entropyk(self): with pytest.raises(entropyk.EntropykError): raise entropyk.ComponentError("test") def test_timeout_not_caught_as_fluid(self): """TimeoutError should NOT be caught by FluidError.""" with pytest.raises(entropyk.TimeoutError): raise entropyk.TimeoutError("test") # Verify it doesn't match FluidError try: raise entropyk.TimeoutError("test") except entropyk.FluidError: pytest.fail("TimeoutError should not be caught by FluidError") except entropyk.TimeoutError: pass # Expected