Coverage for tests/test_robustness_edge_cases.py: 99%
79 statements
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-18 05:24 +0000
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-18 05:24 +0000
1import pytest
2import numpy as np
3from evutils.types import EventArray, TriggerArray
4from evutils.types import EventsChecker
5from evutils.chunking import window_delta_t, sliding_window, stream_n_events, stream_delta_t
6from evutils.filtering import mask_events
7from evutils.transforms.functional import normalize_ts
8from evutils.transforms import drop_random_events
9from evutils.vis.plot3d import plot_3d, plot_3d_timesurface
11# --- 1. Chunking Edge Cases ---
13def test_chunking_zero_delta_t_raises():
14 events = EventArray(t=[1, 2, 3], x=[0, 0, 0], y=[0, 0, 0], p=[0, 0, 0])
15 with pytest.raises(ValueError, match="delta_t must be positive"):
16 next(window_delta_t(events, delta_t=0))
18 with pytest.raises(ValueError, match="delta_t and window_size must be positive"):
19 next(sliding_window(events, delta_t=0, window_size=10))
21def test_stream_n_events_zero_raises():
22 def dummy_stream():
23 yield EventArray(t=[1], x=[0], y=[0], p=[0])
25 with pytest.raises(ValueError, match="n_events must be positive"):
26 next(stream_n_events(dummy_stream(), n_events=0))
28def test_stream_delta_t_trigger_only_stream():
29 # Stream with only triggers, no events
30 def trigger_stream():
31 for i in range(1, 4):
32 ev = EventArray(t=[], x=[], y=[], p=[])
33 tr = TriggerArray(t=[i * 1000], p=[1], id=[1])
34 yield ev, tr
36 chunks = list(stream_delta_t(trigger_stream(), delta_t=1000))
37 # It should yield chunks based on trigger timestamps
38 assert len(chunks) > 0
39 # Last chunk should have triggers
40 assert len(chunks[-1][1]) > 0
43# --- 2. Vis Empty Array Edge Cases ---
45def test_vis_empty_arrays():
46 import matplotlib.pyplot as plt
47 empty_events = EventArray.empty()
49 # These should not crash
50 fig, ax = plot_3d(empty_events)
51 assert ax is not None
52 plt.close(fig)
54 fig, ax = plot_3d_timesurface(empty_events)
55 assert ax is not None
56 plt.close(fig)
58 # Open3D
59 pytest.importorskip("open3d")
60 from evutils.vis.open3d import o3d_draw_events
61 o3d_draw_events(empty_events)
64# --- 3. Types and Utils Edge Cases ---
66def test_event_array_length_mismatch():
67 with pytest.raises(ValueError, match="Length mismatch"):
68 EventArray(t=[1, 2], x=[1], y=[1, 2], p=[1, 2])
70def test_trigger_array_length_mismatch():
71 with pytest.raises(ValueError, match="Length mismatch"):
72 TriggerArray(t=[1, 2], p=[1], id=[1, 2])
74def test_event_array_flattening():
75 # Multidimensional inputs should be flattened gracefully
76 events = EventArray(t=[[1, 2]], x=[[1, 2]], y=[[1, 2]], p=[[0, 1]])
77 assert len(events) == 2
78 assert events.t.ndim == 1
80def test_events_checker_invalid_type():
81 with pytest.raises(TypeError, match="events must be a NumPy array or SoaArray"):
82 EventsChecker([1, 2, 3])
84def test_empty_list_indexing():
85 events = EventArray(t=[1], x=[1], y=[1], p=[1])
86 with pytest.raises(ValueError, match="empty list of fields"):
87 events[[]]
90# --- 4. Processing and Augment Edge Cases ---
92def test_drop_random_events_nan():
93 events = EventArray(t=[1, 2], x=[1, 2], y=[1, 2], p=[0, 1]).to_numpy()
94 with pytest.raises(ValueError, match="drop_rate must be between 0 and 1"):
95 drop_random_events(events, drop_rate=np.nan)
97def test_mask_events_negative_coordinates():
98 # If using a custom signed dtype
99 custom_dtype = np.dtype([('t', np.int64), ('x', np.int16), ('y', np.int16), ('p', np.uint8)])
100 events = np.array([(100, -5, 10, 1), (200, 10, 10, 1)], dtype=custom_dtype)
101 mask = np.ones((20, 20), dtype=np.uint8)
103 with pytest.raises(ValueError, match="non-negative"):
104 mask_events(events, mask)
106def test_normalize_ts_readonly():
107 events = EventArray(t=[100, 200], x=[1, 2], y=[1, 2], p=[0, 1]).to_numpy()
108 events.flags.writeable = False # Simulate read-only mmap view
110 # Should not crash, but return a normalized copy
111 norm_events = normalize_ts(events)
112 assert norm_events['t'][0] == 0
113 assert norm_events['t'][1] == 100
114 # Original is untouched
115 assert events['t'][0] == 100
117def test_normalize_ts_unstructured():
118 events = np.array([[100, 1, 1, 1]])
119 with pytest.raises(TypeError, match="Unsupported event format"):
120 normalize_ts(events)