Add physics model unit tests

Test dataclass creation, immutability, equality, and hashability for
ThermalState and ElectricalState. Also test PhysicsEngine stub methods.
This commit is contained in:
2025-02-27 21:23:36 +00:00
parent ca4613e318
commit eb13bb5bc4

View File

@@ -0,0 +1,214 @@
"""Unit tests for physics state dataclasses and engine stub."""
import pytest
from py_dvt_ate.simulation.physics.engine import PhysicsEngine
from py_dvt_ate.simulation.physics.state import ElectricalState, ThermalState
class TestThermalState:
"""Tests for the ThermalState dataclass."""
def test_creation(self) -> None:
"""Test ThermalState can be created with valid values."""
state = ThermalState(
chamber_temperature=25.0,
case_temperature=30.0,
junction_temperature=35.0,
timestamp=0.0,
)
assert state.chamber_temperature == 25.0
assert state.case_temperature == 30.0
assert state.junction_temperature == 35.0
assert state.timestamp == 0.0
def test_immutability(self) -> None:
"""Test ThermalState is immutable (frozen dataclass)."""
state = ThermalState(
chamber_temperature=25.0,
case_temperature=30.0,
junction_temperature=35.0,
timestamp=0.0,
)
with pytest.raises(AttributeError):
state.chamber_temperature = 50.0 # type: ignore[misc]
def test_equality(self) -> None:
"""Test ThermalState equality comparison."""
state1 = ThermalState(
chamber_temperature=25.0,
case_temperature=30.0,
junction_temperature=35.0,
timestamp=0.0,
)
state2 = ThermalState(
chamber_temperature=25.0,
case_temperature=30.0,
junction_temperature=35.0,
timestamp=0.0,
)
assert state1 == state2
def test_hashable(self) -> None:
"""Test ThermalState is hashable (for use in sets/dicts)."""
state = ThermalState(
chamber_temperature=25.0,
case_temperature=30.0,
junction_temperature=35.0,
timestamp=0.0,
)
# Should not raise
hash(state)
{state} # Can be added to a set
class TestElectricalState:
"""Tests for the ElectricalState dataclass."""
def test_creation(self) -> None:
"""Test ElectricalState can be created with valid values."""
state = ElectricalState(
input_voltage=5.0,
output_voltage=3.3,
load_current=0.1,
quiescent_current=50e-6,
power_dissipation=0.17,
)
assert state.input_voltage == 5.0
assert state.output_voltage == 3.3
assert state.load_current == 0.1
assert state.quiescent_current == 50e-6
assert state.power_dissipation == 0.17
def test_immutability(self) -> None:
"""Test ElectricalState is immutable (frozen dataclass)."""
state = ElectricalState(
input_voltage=5.0,
output_voltage=3.3,
load_current=0.1,
quiescent_current=50e-6,
power_dissipation=0.17,
)
with pytest.raises(AttributeError):
state.output_voltage = 1.8 # type: ignore[misc]
def test_equality(self) -> None:
"""Test ElectricalState equality comparison."""
state1 = ElectricalState(
input_voltage=5.0,
output_voltage=3.3,
load_current=0.1,
quiescent_current=50e-6,
power_dissipation=0.17,
)
state2 = ElectricalState(
input_voltage=5.0,
output_voltage=3.3,
load_current=0.1,
quiescent_current=50e-6,
power_dissipation=0.17,
)
assert state1 == state2
class TestPhysicsEngineStub:
"""Tests for the PhysicsEngine stub."""
def test_creation_default(self) -> None:
"""Test PhysicsEngine can be created with defaults."""
engine = PhysicsEngine()
assert engine.dt == pytest.approx(0.01) # 100Hz -> 10ms
def test_creation_custom_rate(self) -> None:
"""Test PhysicsEngine with custom update rate."""
engine = PhysicsEngine(update_rate_hz=50.0)
assert engine.dt == pytest.approx(0.02) # 50Hz -> 20ms
def test_step_advances_time(self) -> None:
"""Test step() advances simulation time."""
engine = PhysicsEngine(update_rate_hz=100.0)
assert engine.simulation_time == pytest.approx(0.0)
engine.step()
assert engine.simulation_time == pytest.approx(0.01)
engine.step()
assert engine.simulation_time == pytest.approx(0.02)
def test_get_thermal_state(self) -> None:
"""Test get_thermal_state returns ThermalState."""
engine = PhysicsEngine()
state = engine.get_thermal_state()
assert isinstance(state, ThermalState)
assert state.chamber_temperature == 25.0 # Default
assert state.timestamp == 0.0
def test_get_electrical_state(self) -> None:
"""Test get_electrical_state returns ElectricalState."""
engine = PhysicsEngine()
state = engine.get_electrical_state()
assert isinstance(state, ElectricalState)
def test_set_chamber_setpoint(self) -> None:
"""Test set_chamber_setpoint updates setpoint."""
engine = PhysicsEngine()
engine.set_chamber_setpoint(85.0)
# Stub doesn't update chamber temp, just stores setpoint
state = engine.get_thermal_state()
assert state.chamber_temperature == 25.0 # Still at initial
def test_set_input_voltage(self) -> None:
"""Test set_input_voltage updates voltage."""
engine = PhysicsEngine()
engine.set_input_voltage(5.0)
state = engine.get_electrical_state()
assert state.input_voltage == 5.0
def test_set_load_current(self) -> None:
"""Test set_load_current updates current."""
engine = PhysicsEngine()
engine.set_output_enabled(True)
engine.set_load_current(0.1)
state = engine.get_electrical_state()
assert state.load_current == 0.1
def test_output_disabled_by_default(self) -> None:
"""Test output is disabled by default."""
engine = PhysicsEngine()
assert not engine.is_output_enabled
def test_enable_output(self) -> None:
"""Test set_output_enabled enables output."""
engine = PhysicsEngine()
engine.set_output_enabled(True)
assert engine.is_output_enabled
def test_load_current_zero_when_disabled(self) -> None:
"""Test load current is zero when output disabled."""
engine = PhysicsEngine()
engine.set_load_current(0.1)
state = engine.get_electrical_state()
assert state.load_current == 0.0 # Disabled, so zero