Skip to content

Commit d593c6b

Browse files
committed
test: restore helpful comments, assert messages, and fix zip compatibility
1 parent 82cc45f commit d593c6b

3 files changed

Lines changed: 75 additions & 38 deletions

File tree

experanto/experiment.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from __future__ import annotations
22

33
import logging
4-
import re
54
import warnings
6-
from collections.abc import Sequence
75
from pathlib import Path
86

97
import numpy as np

tests/create_experiment.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ def make_modality_config(*device_names, sampling_rates=None, offsets=None):
3838
elif isinstance(offsets, (int, float)):
3939
offsets = [offsets] * len(device_names)
4040

41-
assert len(device_names) == len(
42-
sampling_rates
43-
), f"sampling_rates length {len(sampling_rates)} does not match device_names length {len(device_names)}"
44-
assert len(device_names) == len(
45-
offsets
46-
), f"offsets length {len(offsets)} does not match device_names length {len(device_names)}"
41+
assert len(device_names) == len(sampling_rates), (
42+
f"sampling_rates length {len(sampling_rates)} does not match device_names length {len(device_names)}"
43+
)
44+
assert len(device_names) == len(offsets), (
45+
f"offsets length {len(offsets)} does not match device_names length {len(device_names)}"
46+
)
4747

4848
return {
4949
name: {"interpolation": {"sampling_rate": sr, "offset": off}}
50-
for name, sr, off in zip(device_names, sampling_rates, offsets, strict=True)
50+
for name, sr, off in zip(device_names, sampling_rates, offsets)
5151
}

tests/test_experiment.py

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,19 @@
3535
"large_time_stamps",
3636
]
3737

38+
# Inverted range is intentionally separate from INVALID_META_CASES -
39+
# None/NaN/inf are caught per-device before being added to self.devices,
40+
# whereas start > end is only caught after all devices are loaded.
3841
INVALID_META_CASES = [
39-
{"start_time": None, "end_time": None},
40-
{"start_time": None, "end_time": 10.0},
41-
{"start_time": 0.0, "end_time": None},
42-
{"start_time": float("inf"), "end_time": 10.0},
43-
{"start_time": 0.0, "end_time": float("inf")},
44-
{"start_time": float("-inf"), "end_time": 10.0},
45-
{"start_time": 0.0, "end_time": float("-inf")},
46-
{"start_time": float("nan"), "end_time": 10.0},
47-
{"start_time": 0.0, "end_time": float("nan")},
42+
{"start_time": None, "end_time": None}, # Both missing
43+
{"start_time": None, "end_time": 10.0}, # Missing start_time
44+
{"start_time": 0.0, "end_time": None}, # Missing end_time
45+
{"start_time": float("inf"), "end_time": 10.0}, # Infinite start_time
46+
{"start_time": 0.0, "end_time": float("inf")}, # Infinite end_time
47+
{"start_time": float("-inf"), "end_time": 10.0}, # Negative Infinite start_time
48+
{"start_time": 0.0, "end_time": float("-inf")}, # Negative Infinite end_time
49+
{"start_time": float("nan"), "end_time": 10.0}, # NaN start_time
50+
{"start_time": 0.0, "end_time": float("nan")}, # NaN end_time
4851
]
4952

5053
INVALID_META_IDS = [
@@ -89,10 +92,14 @@ def test_experiment_initialization_and_device_loading(tmp_path, mock_interpolato
8992
"eye_tracker": {"interpolation": mock_interpolator},
9093
}
9194
exp = Experiment(root_folder=str(tmp_path), modality_config=config)
92-
assert "screen" in exp.devices
93-
assert "eye_tracker" in exp.devices
94-
assert "ignored_device" not in exp.devices
95-
assert set(exp.device_names) == {"screen", "eye_tracker"}
95+
assert "screen" in exp.devices, "Expected 'screen' in experiment devices"
96+
assert "eye_tracker" in exp.devices, "Expected 'eye_tracker' in experiment devices"
97+
assert "ignored_device" not in exp.devices, (
98+
"Expected 'ignored_device' to be excluded"
99+
)
100+
assert set(exp.device_names) == {"screen", "eye_tracker"}, (
101+
f"Expected {{'screen', 'eye_tracker'}}, got {set(exp.device_names)}"
102+
)
96103

97104

98105
def test_experiment_interpolate_routing(tmp_path, mock_interpolator):
@@ -105,10 +112,20 @@ def test_experiment_interpolate_routing(tmp_path, mock_interpolator):
105112
mock_interpolator.interpolate.assert_called_once_with(
106113
test_times, return_valid=False
107114
)
108-
np.testing.assert_array_equal(res, np.array([1, 2, 3]))
115+
np.testing.assert_array_equal(
116+
res,
117+
np.array([1, 2, 3]),
118+
err_msg="Interpolated result does not match mock output",
119+
)
109120
res_dict = exp.interpolate(test_times, device=None)
110-
assert isinstance(res_dict, dict)
111-
np.testing.assert_array_equal(res_dict["screen"], np.array([1, 2, 3]))
121+
assert isinstance(res_dict, dict), (
122+
f"Expected dict return for device=None, got {type(res_dict)}"
123+
)
124+
np.testing.assert_array_equal(
125+
res_dict["screen"],
126+
np.array([1, 2, 3]),
127+
err_msg="Interpolated dict result does not match mock output",
128+
)
112129

113130

114131
@pytest.mark.parametrize(
@@ -136,7 +153,9 @@ def test_get_valid_range_all_devices(tmp_path, device_name, start_t, end_t):
136153
root_folder=str(experiment_path), modality_config=config
137154
)
138155
valid_range = experiment.get_valid_range(device_name)
139-
assert valid_range == (start_t, end_t)
156+
assert valid_range == (start_t, end_t), (
157+
f"Expected valid range {(start_t, end_t)} for {device_name}, got {valid_range}"
158+
)
140159

141160

142161
def test_get_valid_range_raises_for_invalid_device(tmp_path):
@@ -259,8 +278,12 @@ def test_experiment_start_end_time_reflects_union(
259278
)
260279

261280
# Removed pytest.approx here
262-
assert experiment.start_time == expected_start
263-
assert experiment.end_time == expected_end
281+
assert experiment.start_time == (expected_start), (
282+
f"Expected start_time={expected_start}, got {experiment.start_time}"
283+
)
284+
assert experiment.end_time == (expected_end), (
285+
f"Expected end_time={expected_end}, got {experiment.end_time}"
286+
)
264287

265288

266289
@pytest.mark.parametrize("override_meta", INVALID_META_CASES, ids=INVALID_META_IDS)
@@ -270,7 +293,7 @@ def test_experiment_invalid_metadata(tmp_path, override_meta):
270293
) as experiment_path:
271294
# Explicitly corrupt the generated metadata file
272295
meta_file = experiment_path / "device_0" / "meta.yml"
273-
with open(meta_file, "r") as f:
296+
with open(meta_file) as f:
274297
meta = yaml.safe_load(f)
275298
meta.update(override_meta)
276299
with open(meta_file, "w") as f:
@@ -286,10 +309,14 @@ def test_experiment_invalid_metadata(tmp_path, override_meta):
286309

287310
@pytest.mark.parametrize("override_meta", INVALID_META_CASES, ids=INVALID_META_IDS)
288311
def test_experiment_skips_invalid_devices(tmp_path, override_meta, caplog):
289-
start_val, duration_val = (
290-
np.random.lognormal(0.0, 1.0),
291-
np.random.lognormal(0.0, 1.0),
292-
)
312+
"""
313+
Experiment should skip devices with invalid start_time or end_time and
314+
log a warning, but still initialize successfully if at least one valid
315+
device is present. The experiment time range should reflect only the
316+
valid device.
317+
"""
318+
start_val = np.random.lognormal(mean=0.0, sigma=1.0) # Strictly positive float
319+
duration_val = np.random.lognormal(mean=0.0, sigma=1.0)
293320
end_val = start_val + duration_val
294321

295322
devices_kwargs = [
@@ -306,7 +333,7 @@ def test_experiment_skips_invalid_devices(tmp_path, override_meta, caplog):
306333

307334
# Explicitly corrupt the metadata file for the invalid device
308335
meta_file = experiment_path / "invalid_device" / "meta.yml"
309-
with open(meta_file, "r") as f:
336+
with open(meta_file) as f:
310337
meta = yaml.safe_load(f)
311338
meta.update(override_meta)
312339
with open(meta_file, "w") as f:
@@ -319,8 +346,20 @@ def test_experiment_skips_invalid_devices(tmp_path, override_meta, caplog):
319346
root_folder=str(experiment_path), modality_config=config
320347
)
321348

322-
assert "valid_device" in experiment.devices
323-
assert "invalid_device" not in experiment.devices
349+
assert "valid_device" in experiment.devices, (
350+
"Expected 'valid_device' to be initialized"
351+
)
352+
assert "invalid_device" not in experiment.devices, (
353+
"Expected 'invalid_device' to be skipped"
354+
)
355+
324356
# Removed pytest.approx here
325-
assert experiment.start_time == start_val
326-
assert experiment.end_time == end_val
357+
assert experiment.start_time == (start_val), (
358+
f"Expected start_time={start_val}, got {experiment.start_time}"
359+
)
360+
assert experiment.end_time == (end_val), (
361+
f"Expected end_time={end_val}, got {experiment.end_time}"
362+
)
363+
assert any("invalid_device" in message for message in caplog.messages), (
364+
"Expected warning about invalid_device was skipped"
365+
)

0 commit comments

Comments
 (0)