Skip to content

Commit 7e9c5e9

Browse files
committed
new test_sensors suite
1 parent c5ec69b commit 7e9c5e9

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

tests/test_sensors.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import pydantic
2+
import pytest
3+
4+
from virtualship.instruments.sensors import (
5+
ADCP_SUPPORTED_SENSORS,
6+
ARGO_FLOAT_SUPPORTED_SENSORS,
7+
CTD_BGC_SUPPORTED_SENSORS,
8+
CTD_SUPPORTED_SENSORS,
9+
DRIFTER_SUPPORTED_SENSORS,
10+
UNDERWATER_ST_SUPPORTED_SENSORS,
11+
XBT_SUPPORTED_SENSORS,
12+
SensorType,
13+
)
14+
from virtualship.models.expedition import (
15+
SensorConfig,
16+
_check_sensor_compatibility,
17+
_serialize_sensor_list,
18+
)
19+
20+
EXPECTED_SENSOR_MEMBERS = {
21+
"TEMPERATURE",
22+
"SALINITY",
23+
"VELOCITY",
24+
"OXYGEN",
25+
"CHLOROPHYLL",
26+
"NITRATE",
27+
"PHOSPHATE",
28+
"PH",
29+
"PHYTOPLANKTON",
30+
"PRIMARY_PRODUCTION",
31+
}
32+
33+
34+
def test_sensor_type_all_members_exist():
35+
"""All expected SensorType members are present."""
36+
actual = {m.name for m in SensorType}
37+
assert actual == EXPECTED_SENSOR_MEMBERS
38+
39+
40+
def test_sensor_type_lookup_by_value():
41+
"""Can construct a SensorType from its string value."""
42+
assert SensorType("SALINITY") is SensorType.SALINITY
43+
44+
45+
def test_sensor_type_invalid_value_error():
46+
"""Invalid string raises ValueError."""
47+
with pytest.raises(ValueError):
48+
SensorType("NOT_A_SENSOR")
49+
50+
51+
def test_all_allowlists_are_frozenset():
52+
"""All per-instrument allowlists must be frozensets (immutable)."""
53+
for allowlist in (
54+
ARGO_FLOAT_SUPPORTED_SENSORS,
55+
CTD_SUPPORTED_SENSORS,
56+
CTD_BGC_SUPPORTED_SENSORS,
57+
DRIFTER_SUPPORTED_SENSORS,
58+
ADCP_SUPPORTED_SENSORS,
59+
UNDERWATER_ST_SUPPORTED_SENSORS,
60+
XBT_SUPPORTED_SENSORS,
61+
):
62+
assert isinstance(allowlist, frozenset)
63+
64+
65+
def test_sensor_config_basic_construction():
66+
"""Standard construction with SensorType enum."""
67+
sc = SensorConfig(sensor_type=SensorType.TEMPERATURE)
68+
assert sc.sensor_type is SensorType.TEMPERATURE
69+
assert sc.enabled is True
70+
71+
72+
def test_sensor_config_disabled():
73+
"""Can explicitly set enabled=False."""
74+
sc = SensorConfig(sensor_type=SensorType.SALINITY, enabled=False)
75+
assert sc.enabled is False
76+
77+
78+
def test_sensor_config_from_string_shorthand():
79+
"""A bare string should be accepted as shorthand."""
80+
sc = SensorConfig.model_validate("TEMPERATURE")
81+
assert sc.sensor_type is SensorType.TEMPERATURE
82+
assert sc.enabled is True
83+
84+
85+
def test_sensor_config_invalid_string_error():
86+
"""An unknown sensor name should raise error."""
87+
with pytest.raises(pydantic.ValidationError):
88+
SensorConfig.model_validate("NOT_REAL")
89+
90+
91+
def test_serialize_sensor_list_disabled_excluded():
92+
"""Disabled sensors are excluded from serialisation."""
93+
sensors = [
94+
SensorConfig(sensor_type=SensorType.TEMPERATURE, enabled=True),
95+
SensorConfig(sensor_type=SensorType.SALINITY, enabled=False),
96+
]
97+
assert _serialize_sensor_list(sensors) == ["TEMPERATURE"]
98+
99+
100+
def test_check_sensor_compatibility_unsupported_error():
101+
"""Unsupported sensor raises ValueError."""
102+
sensors = [SensorConfig(sensor_type=SensorType.OXYGEN)]
103+
with pytest.raises(ValueError, match="does not support sensor"):
104+
_check_sensor_compatibility(sensors, DRIFTER_SUPPORTED_SENSORS, "Drifter")
105+
106+
107+
def test_check_sensor_compatibility_all_disabled_error():
108+
"""All sensors disabled raises ValueError."""
109+
sensors = [SensorConfig(sensor_type=SensorType.TEMPERATURE, enabled=False)]
110+
with pytest.raises(ValueError, match="no enabled sensors"):
111+
_check_sensor_compatibility(sensors, DRIFTER_SUPPORTED_SENSORS, "Drifter")
112+
113+
114+
def test_check_sensor_compatibility_empty_error():
115+
"""Empty sensor list raises ValueError."""
116+
with pytest.raises(ValueError, match="no enabled sensors"):
117+
_check_sensor_compatibility([], DRIFTER_SUPPORTED_SENSORS, "Drifter")
118+
119+
120+
def test_check_sensor_compatibility_mixed_error():
121+
"""Mix of valid and invalid sensors raises ValueError."""
122+
sensors = [
123+
SensorConfig(sensor_type=SensorType.TEMPERATURE),
124+
SensorConfig(sensor_type=SensorType.OXYGEN),
125+
]
126+
with pytest.raises(ValueError, match="does not support"):
127+
_check_sensor_compatibility(sensors, DRIFTER_SUPPORTED_SENSORS, "Drifter")

0 commit comments

Comments
 (0)