|
6 | 6 | import numpy as np |
7 | 7 | from lf_toolkit.evaluation import Params |
8 | 8 | from .evaluation import _build_student_message, evaluation_function |
9 | | -from .yolo_pipeline import _quality_advice, compute_image_quality_metrics |
| 9 | +from .yolo_pipeline import ( |
| 10 | + _quality_advice, |
| 11 | + compute_image_quality_metrics, |
| 12 | + evaluate_spacer_step_errors, |
| 13 | +) |
10 | 14 |
|
11 | 15 |
|
12 | 16 | def _as_file_uri(path: str) -> str: |
@@ -234,6 +238,36 @@ def test_spacer_feedback_reports_no_spacers_detected(self): |
234 | 238 | self.assertFalse(is_correct) |
235 | 239 | self.assertIn("no spacers", message.lower()) |
236 | 240 |
|
| 241 | + def test_spacer_feedback_reports_too_many_spacers(self): |
| 242 | + is_correct, message = _build_student_message( |
| 243 | + task="spacer", |
| 244 | + img_bgr=np.zeros((10, 10, 3), dtype=np.uint8), |
| 245 | + out={"counts": {"spacer_long": 2, "spacer_short": 1}}, |
| 246 | + errors=[], |
| 247 | + selected_errors=[], |
| 248 | + part_type="", |
| 249 | + ) |
| 250 | + |
| 251 | + self.assertFalse(is_correct) |
| 252 | + self.assertIn("too many spacers", message.lower()) |
| 253 | + |
| 254 | + def test_spacer_assignment_feedback_mentions_placement_and_photo_quality(self): |
| 255 | + errors = [{"code": "E_SPACER_ASSIGNMENT_FAIL", "message": "Assignment failed."}] |
| 256 | + |
| 257 | + is_correct, message = _build_student_message( |
| 258 | + task="spacer", |
| 259 | + img_bgr=np.zeros((10, 10, 3), dtype=np.uint8), |
| 260 | + out={"counts": {"spacer_long": 1, "spacer_short": 1}, "errors": errors}, |
| 261 | + errors=errors, |
| 262 | + selected_errors=errors, |
| 263 | + part_type="", |
| 264 | + ) |
| 265 | + lower_message = message.lower() |
| 266 | + |
| 267 | + self.assertFalse(is_correct) |
| 268 | + self.assertIn("placed on the shafts", lower_message) |
| 269 | + self.assertIn("clear top view", lower_message) |
| 270 | + |
237 | 271 | def test_shaft_feedback_reports_short_shaft_missing_from_counts(self): |
238 | 272 | is_correct, message = _build_student_message( |
239 | 273 | task="shaft", |
@@ -301,6 +335,40 @@ def test_shaft_feedback_reports_too_many_shafts(self): |
301 | 335 | self.assertFalse(is_correct) |
302 | 336 | self.assertIn("too many shafts", message.lower()) |
303 | 337 |
|
| 338 | + def test_spacer_assignment_checked_before_distance_order(self): |
| 339 | + errors = evaluate_spacer_step_errors( |
| 340 | + gears=[{"gid": 11, "center": (0.0, 0.0), "r": 10.0}], |
| 341 | + shafts=[ |
| 342 | + {"center": (10.0, 0.0), "major_len": 40.0}, |
| 343 | + {"center": (30.0, 0.0), "major_len": 40.0}, |
| 344 | + ], |
| 345 | + spacers=[ |
| 346 | + {"sid": 1, "cls": "short_spacer", "center": (100.0, 0.0)}, |
| 347 | + {"sid": 2, "cls": "long_spacer", "center": (5.0, 0.0)}, |
| 348 | + ], |
| 349 | + gear11_gid=11, |
| 350 | + spacer_to_si={2: 1}, |
| 351 | + ) |
| 352 | + |
| 353 | + self.assertEqual(errors[0]["code"], "E_SPACER_ASSIGNMENT_FAIL") |
| 354 | + |
| 355 | + def test_spacer_position_checked_before_distance_order(self): |
| 356 | + errors = evaluate_spacer_step_errors( |
| 357 | + gears=[{"gid": 11, "center": (0.0, 0.0), "r": 10.0}], |
| 358 | + shafts=[ |
| 359 | + {"center": (10.0, 0.0), "major_len": 40.0}, |
| 360 | + {"center": (30.0, 0.0), "major_len": 40.0}, |
| 361 | + ], |
| 362 | + spacers=[ |
| 363 | + {"sid": 1, "cls": "short_spacer", "center": (100.0, 0.0)}, |
| 364 | + {"sid": 2, "cls": "long_spacer", "center": (5.0, 0.0)}, |
| 365 | + ], |
| 366 | + gear11_gid=11, |
| 367 | + spacer_to_si={1: 1, 2: 0}, |
| 368 | + ) |
| 369 | + |
| 370 | + self.assertEqual(errors[0]["code"], "E_SPACER_POSITION_MISMATCH") |
| 371 | + |
304 | 372 |
|
305 | 373 | if __name__ == "__main__": |
306 | 374 | unittest.main() |
0 commit comments