Coverage for test/test_main.py: 100%

171 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-15 20:42 -0400

1import tempfile 

2from dataclasses import dataclass, field 

3 

4import numpy as np 

5import pandas as pd 

6import pytest 

7from pytest import fixture 

8 

9from peakipy.cli.main import ( 

10 get_vclist, 

11 check_for_include_column_and_add_if_missing, 

12 check_data_shape_is_consistent_with_dims, 

13 select_specified_planes, 

14 exclude_specified_planes, 

15 remove_excluded_peaks, 

16 warn_if_trying_to_fit_large_clusters, 

17 unpack_xy_bounds, 

18 validate_plane_selection, 

19 validate_sample_count, 

20 unpack_plotting_colors, 

21 get_fit_data_for_selected_peak_clusters, 

22) 

23 

24 

25@fixture 

26def actual_vclist(): 

27 with tempfile.TemporaryFile() as fp: 

28 fp.write(b"1\n2\n3\n") 

29 fp.seek(0) 

30 vclist = np.genfromtxt(fp) 

31 return vclist 

32 

33 

34@dataclass 

35class PeakipyData: 

36 df: pd.DataFrame = field(default_factory=lambda: pd.DataFrame()) 

37 data: np.array = field(default_factory=lambda: np.zeros((4, 10, 20))) 

38 dims: list = field(default_factory=lambda: [0, 1, 2]) 

39 pt_per_ppm_f2 = 10 

40 pt_per_ppm_f1 = 20 

41 

42 

43def test_get_vclist(actual_vclist): 

44 expected_vclist = np.array([1.0, 2.0, 3.0]) 

45 np.testing.assert_array_equal(actual_vclist, expected_vclist) 

46 

47 

48def test_get_vclist_none(): 

49 vclist = None 

50 args = {} 

51 args = get_vclist(vclist, args) 

52 expected_args = dict(vclist=False) 

53 assert args == expected_args 

54 

55 

56def test_get_vclist_error(): 

57 vclist = "vclist" 

58 args = {} 

59 with pytest.raises(Exception): 

60 get_vclist(vclist, args) 

61 

62 

63def test_check_for_include_column(): 

64 peakipy_data = PeakipyData(pd.DataFrame()) 

65 peakipy_data = check_for_include_column_and_add_if_missing(peakipy_data) 

66 assert "include" in peakipy_data.df.columns 

67 

68 

69def test_select_specified_planes(): 

70 plane = None 

71 expected_plane_numbers = np.arange(4) 

72 actual_plane_numbers, peakipy_data = select_specified_planes(plane, PeakipyData()) 

73 np.testing.assert_array_equal(expected_plane_numbers, actual_plane_numbers) 

74 

75 

76def test_select_specified_planes_2(): 

77 plane = [1, 2] 

78 expected_plane_numbers = np.array([1, 2]) 

79 actual_plane_numbers, peakipy_data = select_specified_planes(plane, PeakipyData()) 

80 np.testing.assert_array_equal(expected_plane_numbers, actual_plane_numbers) 

81 assert peakipy_data.data.shape == (2, 10, 20) 

82 

83 

84def test_select_specified_planes_all_planes_excluded(capsys): 

85 plane = [10] 

86 with pytest.raises(SystemExit): 

87 select_specified_planes(plane, PeakipyData()) 

88 captured = capsys.readouterr() 

89 assert "" in captured.err 

90 

91 

92def test_exclude_specified_planes(): 

93 plane = None 

94 expected_plane_numbers = np.arange(4) 

95 actual_plane_numbers, peakipy_data = exclude_specified_planes(plane, PeakipyData()) 

96 np.testing.assert_array_equal(expected_plane_numbers, actual_plane_numbers) 

97 

98 

99def test_exclude_specified_planes_2(): 

100 plane = [1, 2] 

101 expected_plane_numbers = np.array([0, 3]) 

102 actual_plane_numbers, peakipy_data = exclude_specified_planes(plane, PeakipyData()) 

103 np.testing.assert_array_equal(expected_plane_numbers, actual_plane_numbers) 

104 assert peakipy_data.data.shape == (2, 10, 20) 

105 

106 

107def test_exclude_specified_planes_all_planes_excluded(capsys): 

108 plane = [0, 1, 2, 3] 

109 with pytest.raises(SystemExit): 

110 exclude_specified_planes(plane, PeakipyData()) 

111 captured = capsys.readouterr() 

112 assert "" in captured.err 

113 

114 

115def test_remove_excluded_peaks(): 

116 actual_dict = dict( 

117 include=["yes", "yes", "no"], 

118 peak=[1, 2, 3], 

119 INDEX=[0, 1, 2], 

120 ASS=["one", "two", "three"], 

121 X_PPM=[1, 2, 3], 

122 Y_PPM=[1, 2, 3], 

123 CLUSTID=[1, 2, 3], 

124 MEMCNT=[1, 1, 1], 

125 ) 

126 expected_dict = {k: v[:-1] for k, v in actual_dict.items()} 

127 actual_df = pd.DataFrame(actual_dict) 

128 expected_df = pd.DataFrame(expected_dict) 

129 peakipy_data = PeakipyData(df=actual_df) 

130 pd.testing.assert_frame_equal(remove_excluded_peaks(peakipy_data).df, expected_df) 

131 

132 

133def test_warn_if_trying_to_fit_large_clusters(): 

134 max_cluster_size = 7 

135 df = pd.DataFrame(dict(MEMCNT=[1, 6], CLUSTID=[0, 1])) 

136 peakipy_data = PeakipyData(df=df) 

137 assert ( 

138 warn_if_trying_to_fit_large_clusters(max_cluster_size, peakipy_data) 

139 == max_cluster_size 

140 ) 

141 

142 

143def test_warn_if_trying_to_fit_large_clusters_none(): 

144 max_cluster_size = None 

145 df = pd.DataFrame(dict(MEMCNT=[1, 12], CLUSTID=[0, 1])) 

146 peakipy_data = PeakipyData(df=df) 

147 assert warn_if_trying_to_fit_large_clusters(max_cluster_size, peakipy_data) == 12 

148 

149 

150def test_unpack_xy_bounds_case_00(): 

151 xy_bounds = (0, 0) 

152 result = unpack_xy_bounds(xy_bounds, PeakipyData()) 

153 assert result == None 

154 

155 

156def test_unpack_xy_bounds_case_xy(): 

157 xy_bounds = (1, 2) 

158 result = unpack_xy_bounds(xy_bounds, PeakipyData()) 

159 assert result == [10, 40] 

160 

161 

162def test_unpack_xy_bounds_invalid_input(): 

163 with pytest.raises(TypeError): 

164 unpack_xy_bounds(None, PeakipyData()) 

165 

166 

167class MockPseudo3D: 

168 def __init__(self, n_planes): 

169 self.n_planes = n_planes 

170 

171 

172def test_empty_plane_selection(): 

173 pseudo3D = MockPseudo3D(n_planes=5) 

174 assert validate_plane_selection([], pseudo3D) == [0, 1, 2, 3, 4] 

175 

176 

177def test_plane_selection_none(): 

178 pseudo3D = MockPseudo3D(n_planes=5) 

179 assert validate_plane_selection(None, pseudo3D) == [0, 1, 2, 3, 4] 

180 

181 

182def test_valid_plane_selection(): 

183 pseudo3D = MockPseudo3D(n_planes=5) 

184 assert validate_plane_selection([0, 1, 2], pseudo3D) == [0, 1, 2] 

185 

186 

187def test_invalid_plane_selection_negative(): 

188 pseudo3D = MockPseudo3D(n_planes=5) 

189 with pytest.raises(ValueError): 

190 validate_plane_selection([-1], pseudo3D) 

191 

192 

193def test_invalid_plane_selection_too_high(): 

194 pseudo3D = MockPseudo3D(n_planes=5) 

195 with pytest.raises(ValueError): 

196 validate_plane_selection([5], pseudo3D) 

197 

198 

199def test_invalid_plane_selection_mix(): 

200 pseudo3D = MockPseudo3D(n_planes=5) 

201 with pytest.raises(ValueError): 

202 validate_plane_selection([-1, 3, 5], pseudo3D) 

203 

204 

205def test_valid_sample_count(): 

206 assert validate_sample_count(10) == 10 

207 

208 

209def test_invalid_sample_count_type(): 

210 with pytest.raises(TypeError): 

211 validate_sample_count("10") 

212 

213 

214def test_invalid_sample_count_float(): 

215 with pytest.raises(TypeError): 

216 validate_sample_count(10.5) 

217 

218 

219def test_invalid_sample_count_list(): 

220 with pytest.raises(TypeError): 

221 validate_sample_count([10]) 

222 

223 

224def test_invalid_sample_count_dict(): 

225 with pytest.raises(TypeError): 

226 validate_sample_count({"count": 10}) 

227 

228 

229def test_invalid_sample_count_none(): 

230 with pytest.raises(TypeError): 

231 validate_sample_count(None) 

232 

233 

234def test_valid_colors(): 

235 assert unpack_plotting_colors(("red", "black")) == ("red", "black") 

236 

237 

238def test_default_colors(): 

239 assert unpack_plotting_colors(()) == ("green", "blue") 

240 

241 

242def test_invalid_colors_type(): 

243 assert unpack_plotting_colors("red") == ("green", "blue") 

244 

245 

246def test_invalid_colors_single(): 

247 assert unpack_plotting_colors(("red",)) == ("green", "blue") 

248 

249 

250def test_invalid_colors_length(): 

251 assert unpack_plotting_colors(("red", "black", "green")) == ("green", "blue") 

252 

253 

254def test_no_clusters(): 

255 fits = pd.DataFrame({"clustid": [1, 2, 3]}) 

256 assert get_fit_data_for_selected_peak_clusters(fits, None).equals(fits) 

257 

258 

259def test_empty_clusters(): 

260 fits = pd.DataFrame({"clustid": [1, 2, 3]}) 

261 assert get_fit_data_for_selected_peak_clusters(fits, []).equals(fits) 

262 

263 

264def test_valid_clusters(): 

265 fits = pd.DataFrame({"clustid": [1, 2, 3]}) 

266 selected_clusters = [1, 3] 

267 expected_result = pd.DataFrame({"clustid": [1, 3]}) 

268 assert ( 

269 get_fit_data_for_selected_peak_clusters(fits, selected_clusters) 

270 .reset_index(drop=True) 

271 .equals(expected_result) 

272 ) 

273 

274 

275def test_invalid_clusters(): 

276 fits = pd.DataFrame({"clustid": [1, 2, 3]}) 

277 with pytest.raises(SystemExit): 

278 get_fit_data_for_selected_peak_clusters(fits, [4, 5, 6]) 

279 

280 

281def test_check_data_shape_is_consistent_with_dims(): 

282 peakipy_data = PeakipyData(data=np.zeros((4, 10))) 

283 with pytest.raises(SystemExit): 

284 check_data_shape_is_consistent_with_dims(peakipy_data)