from hef.selection import Coordinate from tools.drafting import Draft, HeuristicProposer, Signals def _sig(**o): base = dict( title="", description="", source_archive="nasa", mode="video", duration_s=600, ) base.update(o) return Signals(**base) def test_returns_draft_with_coordinate_and_rationale(): d = HeuristicProposer().propose(_sig()) assert isinstance(d, Draft) assert isinstance(d.coordinate, Coordinate) assert d.rationale and "\n" not in d.rationale def test_librivox_seeds_left(): d = HeuristicProposer().propose( _sig(title="Meditations", source_archive="librivox", mode="audio") ) assert d.coordinate.left >= 3 and d.rationale def test_music_archives_seed_right(): for arch in ("musopen", "fma", "nasa", "freesound"): d = HeuristicProposer().propose(_sig(source_archive=arch, mode="audio")) assert d.coordinate.right >= 3, arch def test_internet_archive_seeds_left(): d = HeuristicProposer().propose(_sig(source_archive="internet_archive")) assert d.coordinate.left >= 3 def test_storm_seeds_dark(): d = HeuristicProposer().propose( _sig(title="Thunderstorm at Night", source_archive="nasa") ) assert d.coordinate.dark >= 2 def test_sunrise_seeds_light(): d = HeuristicProposer().propose( _sig(title="Sunrise over the Garden", source_archive="nasa") ) assert d.coordinate.light >= 2 def test_coordinates_clamped_to_0_4(): d = HeuristicProposer().propose( _sig( title="storm night war funeral decay requiem minor", description="noir death grief", source_archive="librivox", ) ) for v in (d.coordinate.left, d.coordinate.right, d.coordinate.dark, d.coordinate.light): assert 0 <= v <= 4 def test_rationale_cites_a_signal(): d = HeuristicProposer().propose( _sig(title="Storm", source_archive="librivox", mode="audio") ) assert "librivox" in d.rationale.lower() def test_deterministic(): s = _sig(title="Storm at Dawn", source_archive="nasa") a = HeuristicProposer().propose(s) b = HeuristicProposer().propose(s) assert a == b