| """Unit tests for cores.face — box conversions, embedding distance, matching.""" |
|
|
| from __future__ import annotations |
|
|
| import numpy as np |
|
|
| from cores.face import ( |
| xywh_to_xyxy, xyxy_to_xywh, xywh_to_face_recognition_tuple, |
| cosine_similarity, euclidean_distance, best_match, |
| ) |
|
|
|
|
| class TestBoxConversions: |
| def test_xywh_to_xyxy(self): |
| assert xywh_to_xyxy(10, 20, 100, 50) == (10, 20, 110, 70) |
|
|
| def test_xyxy_to_xywh(self): |
| assert xyxy_to_xywh(10, 20, 110, 70) == (10, 20, 100, 50) |
|
|
| def test_face_recognition_tuple(self): |
| |
| assert xywh_to_face_recognition_tuple(10, 20, 100, 50) == (20, 110, 70, 10) |
|
|
|
|
| class TestEmbeddingDistance: |
| def test_cosine_similarity_identical(self): |
| v = np.array([1.0, 2.0, 3.0]) |
| assert cosine_similarity(v, v) == pytest.approx(1.0) if (pytest := __import__("pytest")) else True |
|
|
| def test_cosine_similarity_orthogonal(self): |
| a = np.array([1.0, 0.0]) |
| b = np.array([0.0, 1.0]) |
| assert cosine_similarity(a, b) == 0.0 |
|
|
| def test_cosine_similarity_zero_vector(self): |
| a = np.zeros(3) |
| b = np.array([1.0, 2.0, 3.0]) |
| assert cosine_similarity(a, b) == 0.0 |
|
|
| def test_euclidean_distance_identical(self): |
| v = np.array([1.0, 2.0, 3.0]) |
| assert euclidean_distance(v, v) == 0.0 |
|
|
| def test_euclidean_distance_known(self): |
| a = np.array([0.0, 0.0]) |
| b = np.array([3.0, 4.0]) |
| assert euclidean_distance(a, b) == 5.0 |
|
|
|
|
| class TestBestMatch: |
| def test_empty_gallery_returns_none(self): |
| name, score, all_scores = best_match(np.zeros(128), {}) |
| assert name is None |
| assert all_scores == {} |
|
|
| def test_finds_best_match_cosine(self): |
| query = np.array([1.0, 0.0, 0.0]) |
| gallery = { |
| "alice": [np.array([0.95, 0.05, 0.0])], |
| "bob": [np.array([0.0, 1.0, 0.0])], |
| } |
| name, score, all_scores = best_match(query, gallery, metric="cosine") |
| assert name == "alice" |
| assert score > 0.9 |
| assert "alice" in all_scores |
| assert "bob" in all_scores |
| assert all_scores["alice"] > all_scores["bob"] |
|
|
| def test_finds_best_match_euclidean(self): |
| query = np.array([0.0, 0.0, 0.0]) |
| gallery = { |
| "near": [np.array([1.0, 0.0, 0.0])], |
| "far": [np.array([5.0, 5.0, 5.0])], |
| } |
| name, score, all_scores = best_match(query, gallery, metric="euclidean") |
| assert name == "near" |
| assert score == 1.0 |
| assert all_scores["near"] < all_scores["far"] |
|
|
| def test_handles_empty_person_embeddings(self): |
| query = np.array([1.0, 0.0]) |
| gallery = {"empty_person": []} |
| name, score, all_scores = best_match(query, gallery) |
| assert name is None |
| assert all_scores == {} |
|
|