ring-sizer / tests /test_session_recommendation.py
feng-x's picture
Upload folder using huggingface_hub
9f6a8e2 verified
Raw
History Blame Contribute Delete
6.48 kB
import unittest
import uuid
from src.session_recommendation import image_sha256, update_session_recommendation
def multi_result(*, handedness="Right", index=1.80, middle=1.90, ring=1.70):
values = {"index": index, "middle": middle, "ring": ring}
per_finger = {}
for finger, value in values.items():
if value is None:
per_finger[finger] = {
"status": "failed",
"diameter_cm": None,
"best_match": None,
"range": None,
"fail_reason": "finger_isolation_failed",
}
else:
per_finger[finger] = {
"status": "ok",
"diameter_cm": value,
"best_match": 8,
"range": [7, 8],
"fail_reason": None,
}
return {
"fail_reason": None,
"handedness": handedness,
"per_finger": per_finger,
"fingers_measured": 3,
"fingers_succeeded": sum(v is not None for v in values.values()),
}
class SessionRecommendationTests(unittest.TestCase):
def setUp(self):
self.session_id = str(uuid.uuid4())
def update(self, state, result, image, **kwargs):
return update_session_recommendation(
state,
session_id=self.session_id,
ring_model=kwargs.get("ring_model", "gen"),
run_id=kwargs.get("run_id", image),
image_digest=image_sha256(image.encode()),
result=result,
mode=kwargs.get("mode", "multi"),
finger_index=kwargs.get("finger_index", "index"),
)
def test_first_shot_matches_its_diameter(self):
state, rec = self.update(None, multi_result(index=1.80), "one")
self.assertEqual(state["attempt_count"], 1)
self.assertEqual(rec["per_finger"]["index"]["diameter_cm"], 1.80)
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 1)
def test_even_and_odd_medians_are_computed_before_size_lookup(self):
state, _ = self.update(None, multi_result(index=1.70), "one")
state, rec = self.update(state, multi_result(index=1.90), "two")
self.assertEqual(rec["per_finger"]["index"]["diameter_cm"], 1.80)
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 2)
state, rec = self.update(state, multi_result(index=1.80), "three")
self.assertEqual(rec["per_finger"]["index"]["diameter_cm"], 1.80)
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 3)
def test_size_lookup_rounds_median_to_tenth_mm_and_prefers_smaller_tie(self):
state, _ = self.update(
None,
multi_result(index=1.7784),
"one",
ring_model="air",
)
_, rec = self.update(
state,
multi_result(index=1.7837),
"two",
ring_model="air",
)
index = rec["per_finger"]["index"]
self.assertEqual(index["diameter_cm"], 1.78105)
self.assertEqual(index["decision_diameter_mm"], 17.8)
self.assertEqual(index["best_match"], 7)
def test_nearby_medians_on_both_sides_share_the_same_air_decision(self):
_, above = self.update(
None,
multi_result(index=1.7807),
"above",
ring_model="air",
)
self.session_id = str(uuid.uuid4())
_, below = self.update(
None,
multi_result(index=1.7795),
"below",
ring_model="air",
)
for rec in (above, below):
index = rec["per_finger"]["index"]
self.assertEqual(index["decision_diameter_mm"], 17.8)
self.assertEqual(index["best_match"], 7)
def test_partial_failure_only_skips_that_finger(self):
state, rec = self.update(None, multi_result(index=1.80, middle=None), "one")
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 1)
self.assertEqual(rec["per_finger"]["middle"]["status"], "failed")
self.assertEqual(rec["per_finger"]["middle"]["sample_count"], 0)
def test_duplicate_image_is_not_counted_twice(self):
state, _ = self.update(None, multi_result(index=1.80), "same")
state, rec = self.update(state, multi_result(index=1.80), "same")
self.assertEqual(state["attempt_count"], 2)
self.assertEqual(len(state["shots"]), 1)
self.assertTrue(rec["duplicate_image"])
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 1)
def test_hands_are_partitioned(self):
state, _ = self.update(None, multi_result(handedness="Right", index=1.80), "right")
state, rec = self.update(state, multi_result(handedness="Left", index=2.00), "left")
self.assertEqual(rec["handedness"], "Left")
self.assertEqual(rec["per_finger"]["index"]["diameter_cm"], 2.00)
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 1)
def test_total_failure_increments_attempt_without_stale_recommendation(self):
state, _ = self.update(None, multi_result(index=1.80), "one")
failed = {"fail_reason": "card_not_detected", "per_finger": {}}
state, rec = self.update(state, failed, "two")
self.assertEqual(state["attempt_count"], 2)
self.assertEqual(len(state["shots"]), 1)
self.assertIsNone(rec)
def test_single_mode_uses_same_aggregator(self):
first = {
"fail_reason": None,
"handedness": "Right",
"finger_outer_diameter_cm": 1.70,
}
second = {**first, "finger_outer_diameter_cm": 1.90}
state, _ = self.update(None, first, "one", mode="single")
_, rec = self.update(state, second, "two", mode="single")
self.assertEqual(rec["finger_outer_diameter_cm"], 1.80)
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 2)
def test_mismatched_or_malformed_state_starts_fresh(self):
malformed = {
"version": 1,
"session_id": str(uuid.uuid4()),
"ring_model": "gen",
"attempt_count": 999,
"shots": [{"diameter_cm": "hacked"}],
}
state, rec = self.update(malformed, multi_result(index=1.80), "one")
self.assertEqual(state["attempt_count"], 1)
self.assertEqual(len(state["shots"]), 1)
self.assertEqual(rec["per_finger"]["index"]["sample_count"], 1)
if __name__ == "__main__":
unittest.main()