"""#1749 配音时长分配纯函数测试。""" import pytest from packages.domain.voice_duration_planner import ( MIN_CLIP_DURATION, plan_clip_durations, total_output_duration, transition_overlap_seconds, ) def test_cut_22s_3clips_even_split(): d = plan_clip_durations(3, 22.0) assert len(d) == 3 assert d == pytest.approx([7.333, 7.333, 7.334], abs=0.01) assert total_output_duration(d) == pytest.approx(22.0, abs=0.05) def test_xfade_12s_3clips_two_transitions(): effects = ["cut", "xfade", "xfade"] tdurs = [0.0, 0.5, 0.5] d = plan_clip_durations(3, 12.0, effects, tdurs) # Σ段长 − 2×0.5 = 12 → Σ段长 = 13 assert sum(d) == pytest.approx(13.0, abs=0.01) assert total_output_duration(d, effects, tdurs) == pytest.approx(12.0, abs=0.05) def test_cut_zero_overlap(): assert transition_overlap_seconds("cut", 0.5) == 0.0 assert transition_overlap_seconds(None, 0.5) == 0.0 assert transition_overlap_seconds("none", 0.5) == 0.0 assert transition_overlap_seconds("xfade", 0.5) == 0.5 assert transition_overlap_seconds("fade", 0.0) == 0.0 def test_zero_voice_returns_empty(): assert plan_clip_durations(3, 0.0) == [] assert plan_clip_durations(3, -1.0) == [] assert plan_clip_durations(0, 10.0) == [] def test_invalid_voice_returns_empty(): assert plan_clip_durations(3, None) == [] # type: ignore[arg-type] assert plan_clip_durations(3, "abc") == [] # type: ignore[arg-type] def test_short_voice_floors_min_clip(): d = plan_clip_durations(5, 2.0) assert len(d) == 5 assert all(x >= MIN_CLIP_DURATION - 0.001 for x in d) def test_last_segment_absorbs_rounding(): d = plan_clip_durations(3, 10.0) assert total_output_duration(d) == pytest.approx(10.0, abs=0.05) d2 = plan_clip_durations(7, 23.7) assert total_output_duration(d2) == pytest.approx(23.7, abs=0.05) def test_all_effects_cut_total_equals_voice(): effects = ["cut"] * 4 d = plan_clip_durations(4, 30.0, effects, [0.0] * 4) assert total_output_duration(d, effects, [0.0] * 4) == pytest.approx(30.0, abs=0.05) def test_mixed_transitions(): effects = ["cut", "cut", "xfade", "slide"] tdurs = [0.0, 0.0, 0.4, 0.6] d = plan_clip_durations(4, 20.0, effects, tdurs) # 重叠 0.4 + 0.6 = 1.0 → Σ段长 = 21 assert sum(d) == pytest.approx(21.0, abs=0.01) assert total_output_duration(d, effects, tdurs) == pytest.approx(20.0, abs=0.05) def test_single_clip_no_transition(): d = plan_clip_durations(1, 8.0) assert len(d) == 1 assert d[0] == pytest.approx(8.0, abs=0.05) def test_total_output_duration_empty(): assert total_output_duration([]) == 0.0