import math import pytest from hef.catalog import Record from hef.selection import Coordinate, Weights, distance, record_coordinate def make_record(**overrides): base = dict( id="r", title="t", source_url="u", source_archive="internet_archive", license="public_domain", mode="video", left=0, right=0, dark=0, light=0, duration_s=600, file_path="/media/r.mp4", ) base.update(overrides) return Record(**base) def test_distance_zero_for_same_point(): c = Coordinate(2, 2, 2, 2) assert distance(c, c) == 0.0 def test_distance_is_euclidean_by_default(): a = Coordinate(0, 0, 0, 0) b = Coordinate(1, 1, 1, 1) assert distance(a, b) == pytest.approx(2.0) # sqrt(1+1+1+1) def test_weights_scale_planes_independently(): a = Coordinate(0, 0, 0, 0) brain_only = Coordinate(1, 0, 0, 0) mood_only = Coordinate(0, 0, 1, 0) w = Weights(brain=4.0, mood=1.0) assert distance(a, brain_only, w) == pytest.approx(2.0) # sqrt(4*1) assert distance(a, mood_only, w) == pytest.approx(1.0) # sqrt(1*1) def test_record_coordinate_extracts_axes(): record = make_record(left=1, right=2, dark=3, light=4) assert record_coordinate(record) == Coordinate(1, 2, 3, 4) from hef.selection import candidates_for_mode def test_candidates_filter_to_exact_mode(): records = [make_record(id="v", mode="video"), make_record(id="a", mode="audio")] result = candidates_for_mode(records, "audio", pool_size=4) assert [r.id for r in result] == ["a"] def test_av_does_not_fall_back_when_enough_av(): records = [make_record(id=f"av{i}", mode="av") for i in range(4)] records.append(make_record(id="a", mode="audio")) result = candidates_for_mode(records, "av", pool_size=4) assert {r.id for r in result} == {"av0", "av1", "av2", "av3"} def test_av_falls_back_to_audio_and_video_when_thin(): records = [ make_record(id="av0", mode="av"), make_record(id="a", mode="audio"), make_record(id="v", mode="video"), ] result = candidates_for_mode(records, "av", pool_size=4) assert {r.id for r in result} == {"av0", "a", "v"} def test_candidates_rejects_none_mode(): with pytest.raises(ValueError): candidates_for_mode([], "none", pool_size=4) import random from hef.selection import select def test_none_mode_returns_none(): records = [make_record(id="v", mode="video")] assert select(records, Coordinate(0, 0, 0, 0), "none") is None def test_empty_pool_returns_none(): assert select([], Coordinate(0, 0, 0, 0), "video") is None def test_select_returns_nearest_by_default(): near = make_record(id="near", mode="video", left=2, right=2, dark=2, light=2) far = make_record(id="far", mode="video", left=0, right=0, dark=0, light=0) result = select([far, near], Coordinate(2, 2, 2, 2), "video") assert result.id == "near" def test_select_is_deterministic_without_rng(): records = [ make_record(id="b", mode="video", left=1), make_record(id="a", mode="video", left=1), ] # Equal distance -> tie broken by id, so "a" wins deterministically. result = select(records, Coordinate(1, 0, 0, 0), "video") assert result.id == "a" def test_select_with_rng_picks_within_nearest_pool(): records = [make_record(id=f"r{i}", mode="video", left=i % 5) for i in range(10)] coord = Coordinate(2, 0, 0, 0) rng = random.Random(0) chosen = {select(records, coord, "video", pool_size=3, rng=rng).id for _ in range(50)} # Only records inside the 3-nearest pool may ever be chosen. ranked = sorted(records, key=lambda r: abs(r.left - 2)) allowed = {r.id for r in ranked[:3]} assert chosen <= allowed def test_approved_only_excludes_proposed(): proposed = make_record(id="p", mode="video", review_status="proposed") approved = make_record(id="ok", mode="video", review_status="approved") result = select([proposed, approved], Coordinate(0, 0, 0, 0), "video", approved_only=True) assert result.id == "ok" def test_invalid_selector_mode_raises(): with pytest.raises(ValueError): select([], Coordinate(0, 0, 0, 0), "telepathy")