Skip to content

Commit 75f5a91

Browse files
committed
Fix lint and coverage
1 parent a7dba6d commit 75f5a91

File tree

3 files changed

+140
-9
lines changed

3 files changed

+140
-9
lines changed

src/daq_config_server/converters/_converters.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ def beamline_parameters_to_dict(contents: str) -> dict[str, Any]:
1919
lines = contents.splitlines()
2020
config_pairs: dict[str, Any] = {}
2121

22-
# Get list of parameter keys and values
22+
# Get dict of parameter keys and values
2323
for line in remove_comments(lines):
2424
splitline = line.split("=")
2525
if len(splitline) >= 2:
2626
param, value = line.split("=")
27-
if param in config_pairs:
27+
if param.strip() in config_pairs:
2828
raise ValueError(f"Repeated key in parameters: {param}")
2929
config_pairs[param.strip()] = value.strip()
3030

@@ -50,11 +50,13 @@ class DisplayConfig(BaseModel):
5050

5151
@model_validator(mode="after")
5252
def check_zoom_levels_match_required(self):
53-
if self.required_zoom_levels is not None and self.required_zoom_levels != set(
54-
self.zoom_levels.keys()
53+
existing_keys = set(self.zoom_levels.keys())
54+
if (
55+
self.required_zoom_levels is not None
56+
and self.required_zoom_levels != existing_keys
5557
):
5658
raise ValueError(
57-
f"Zoom levels {set(self.zoom_levels.keys())} "
59+
f"Zoom levels {existing_keys} "
5860
f"do not match required zoom levels: {self.required_zoom_levels}"
5961
)
6062
return self
@@ -72,7 +74,7 @@ def display_config_to_dict(contents: str) -> DisplayConfig:
7274
crosshairY = 600
7375
zoomLevel = 2.0
7476
crosshairX = 700
75-
crosshairY = 600
77+
crosshairY = 800
7678
7779
Example output:
7880
"""

src/daq_config_server/converters/convert.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import json
22
from pathlib import Path
3+
from typing import Any
34

45
from pydantic import BaseModel
56

67
import daq_config_server.converters._file_converter_map as file_converter_map
78
from daq_config_server.converters._converter_utils import ConverterParseError
89

910

10-
def get_converted_file_contents(file_path: Path) -> dict:
11+
def get_converted_file_contents(file_path: Path) -> dict[str, Any]:
1112
with file_path.open("r", encoding="utf-8") as f:
1213
raw_contents = f.read()
1314
if converter := file_converter_map.FILE_TO_CONVERTER_MAP.get(str(file_path)):

tests/unit_tests/test_converters.py

Lines changed: 130 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
DisplayConfig,
1717
DisplayConfigData,
1818
beamline_parameters_to_dict,
19+
beamline_pitch_lut,
20+
beamline_roll_lut,
21+
detector_xy_lut,
1922
display_config_to_dict,
23+
undulator_energy_gap_lut,
2024
xml_to_dict,
2125
)
2226
from daq_config_server.converters.convert import get_converted_file_contents
@@ -36,6 +40,18 @@ def test_get_converted_file_contents_uses_converter_if_file_in_map(
3640
mock_convert_function.assert_called_once()
3741

3842

43+
def test_get_converted_file_contents_converts_pydantic_model_to_dict(
44+
mock_file_converter_map: dict[str, Callable[[str], Any]],
45+
):
46+
file_to_convert = TestDataPaths.TEST_GOOD_LUT_PATH
47+
model = GenericLut(column_names=["column1", "column2"], rows=[[1, 2], [2, 3]])
48+
mock_convert_function = MagicMock(return_value=model)
49+
mock_file_converter_map[str(file_to_convert)] = mock_convert_function
50+
result = get_converted_file_contents(file_to_convert)
51+
assert isinstance(result, dict)
52+
mock_convert_function.assert_called_once()
53+
54+
3955
def test_error_is_raised_if_file_cant_be_parsed(
4056
mock_file_converter_map: dict[str, Callable[[str], Any]],
4157
):
@@ -64,6 +80,11 @@ def test_parsing_bad_lut_causes_error():
6480
parse_lut(contents, ("energy_eV", int), ("gap_mm", float))
6581

6682

83+
def test_lut_with_different_number_of_row_items_to_column_names_causes_error():
84+
with pytest.raises(ValueError):
85+
GenericLut(column_names=["column1", "column2"], rows=[[1, 2], [1, 2, 3]])
86+
87+
6788
def test_display_config_to_dict_gives_expected_result_and_can_be_jsonified():
6889
with open(TestDataPaths.TEST_GOOD_DISPLAY_CONFIG_PATH) as f:
6990
contents = f.read()
@@ -92,6 +113,29 @@ def test_display_config_to_dict_gives_expected_result_and_can_be_jsonified():
92113
json.dumps(result.model_dump())
93114

94115

116+
def test_display_config_with_wrong_zoom_levels_causes_error():
117+
zoom_levels = {
118+
1.0: DisplayConfigData(
119+
bottomRightX=410,
120+
bottomRightY=278,
121+
crosshairX=541,
122+
crosshairY=409,
123+
topLeftX=383,
124+
topLeftY=253,
125+
),
126+
2.5: DisplayConfigData(
127+
bottomRightX=388,
128+
bottomRightY=322,
129+
crosshairX=551,
130+
crosshairY=410,
131+
topLeftX=340,
132+
topLeftY=283,
133+
),
134+
}
135+
with pytest.raises(ValueError):
136+
DisplayConfig(zoom_levels=zoom_levels, required_zoom_levels=({1.0, 3.0}))
137+
138+
95139
def test_xml_to_dict_gives_expected_result_and_can_be_jsonified():
96140
with open(TestDataPaths.TEST_GOOD_XML_PATH) as f:
97141
contents = f.read()
@@ -121,7 +165,7 @@ def test_xml_to_dict_gives_expected_result_and_can_be_jsonified():
121165
json.dumps(result)
122166

123167

124-
def test_beamline_parameters_to_dict_gives_expected_result_and_can_be_jsonified():
168+
def test_beamline_parameters_to_dict_gives_expected_result():
125169
with open(TestDataPaths.TEST_BEAMLINE_PARAMETERS_PATH) as f:
126170
contents = f.read()
127171
with open(TestDataPaths.EXPECTED_BEAMLINE_PARAMETERS_JSON_PATH) as f:
@@ -130,13 +174,19 @@ def test_beamline_parameters_to_dict_gives_expected_result_and_can_be_jsonified(
130174
assert result == expected
131175

132176

133-
def test_bad_beamline_parameters_causes_error_to_be_raised():
177+
def test_bad_beamline_parameters_with_non_keyword_string_value_causes_error():
134178
with open(TestDataPaths.TEST_BAD_BEAMLINE_PARAMETERS_PATH) as f:
135179
contents = f.read()
136180
with pytest.raises(ValueError):
137181
beamline_parameters_to_dict(contents)
138182

139183

184+
def test_beam_line_parameters_with_repeated_key_causes_error():
185+
input = "thing = 1\nthing = 2"
186+
with pytest.raises(ValueError):
187+
beamline_parameters_to_dict(input)
188+
189+
140190
def test_remove_comments_works_as_expected():
141191
input = [
142192
"This line should not be changed",
@@ -171,3 +221,81 @@ def test_parse_value_works_as_expected(
171221
parsed_value = parse_value(value, convert_to)
172222
assert parsed_value == expected_parsed_value
173223
assert type(parsed_value) is type(expected_parsed_value)
224+
225+
226+
def test_detector_xy_lut_gives_expected_results():
227+
input = (
228+
"# distance beamY beamX (values from mosflm)\n"
229+
"Units mm mm mm\n"
230+
"150 152.2 166.26\n"
231+
"800 152.08 160.96\n"
232+
)
233+
expected = GenericLut(
234+
column_names=["detector_distances_mm", "beam_centre_x_mm", "beam_centre_y_mm"],
235+
rows=[[150, 152.2, 166.26], [800, 152.08, 160.96]],
236+
)
237+
result = detector_xy_lut(input)
238+
assert result == expected
239+
240+
241+
def test_beam_line_pitch_lut_gives_expected_result():
242+
input = (
243+
"# Bragg pitch\n"
244+
"# Degree values for pitch are interpreted as mrad\n"
245+
"# The values cannot change direction.\n"
246+
"# last update 2025/01/15 NP\n"
247+
"Units Deg mrad\n"
248+
"Units Deg Deg\n"
249+
"16.40956 -0.62681\n"
250+
"14.31123 -0.61833\n"
251+
"12.69285 -0.61243\n"
252+
"11.40557 -0.60849\n"
253+
)
254+
expected = GenericLut(
255+
column_names=["bragg_angle_deg", "pitch_mrad"],
256+
rows=[
257+
[16.40956, -0.62681],
258+
[14.31123, -0.61833],
259+
[12.69285, -0.61243],
260+
[11.40557, -0.60849],
261+
],
262+
)
263+
result = beamline_pitch_lut(input)
264+
assert result == expected
265+
266+
267+
def test_beam_line_roll_lut_gives_expected_result():
268+
input = (
269+
"#Bragg angle against roll( absolute number)\n"
270+
"#reloadLookupTables()\n"
271+
"# last update 2024/06/20 NP\n"
272+
"Units Deg mrad\n"
273+
"26.4095 2.6154\n"
274+
"6.3075 2.6154\n"
275+
)
276+
expected = GenericLut(
277+
column_names=["bragg_angle_deg", "roll_mrad"],
278+
rows=[[26.4095, 2.6154], [6.3075, 2.6154]],
279+
)
280+
result = beamline_roll_lut(input)
281+
assert result == expected
282+
283+
284+
def test_undulator_gap_lut_gives_expected_result():
285+
input = (
286+
"#######################\n"
287+
"# #\n"
288+
"# 5.5mm CPMU 20/11/22 #\n"
289+
"# #\n"
290+
"Units eV mm\n"
291+
"5700 5.4606\n"
292+
"5760 5.5\n"
293+
"6000 5.681\n"
294+
"6500 6.045\n"
295+
)
296+
expected = GenericLut(
297+
column_names=["energy_eV", "gap_mm"],
298+
rows=[[5700, 5.4606], [5760, 5.5], [6000, 5.681], [6500, 6.045]],
299+
)
300+
result = undulator_energy_gap_lut(input)
301+
assert result == expected

0 commit comments

Comments
 (0)