"""Tests for the pure disc-split planner in project.py.""" from devedeng.project import ( plan_disc_split, _movie_chapter_seconds, _nearest_chapter_before, ) # ~4.2 GB usable disc in kBytes (matches get_dvd_size()[0]*1000 with margin) CAP = 4_200_000.0 # 4500k video + 192k audio = 4692 kbit/s -> /8 = 586.5 kByte/s RATE = (4500 + 192) / 8.0 # seconds that fill one disc at RATE SECS_PER_DISC = CAP / RATE def names(plan): return [[seg[0] for seg in disc] for disc in plan] def test_single_short_movie_one_disc(make_movie): m = make_movie(rate_kBps=RATE, length=3600) plan = plan_disc_split([m], CAP) assert len(plan) == 1 assert plan[0] == [(m, 0, 0)] def test_two_movies_fit_one_disc(make_movie): a = make_movie(rate_kBps=RATE, length=3000) b = make_movie(rate_kBps=RATE, length=3000) plan = plan_disc_split([a, b], CAP) assert len(plan) == 1 assert names(plan) == [[a, b]] def test_two_movies_overflow_to_two_discs(make_movie): a = make_movie(rate_kBps=RATE, length=5000) b = make_movie(rate_kBps=RATE, length=5000) plan = plan_disc_split([a, b], CAP) assert len(plan) == 2 assert plan[0] == [(a, 0, 0)] assert plan[1] == [(b, 0, 0)] def test_single_long_movie_splits_at_chapter(make_movie): # 200 min movie, chapters every 5 min (300 s) m = make_movie(rate_kBps=RATE, length=12000, chapters_step=5) plan = plan_disc_split([m], CAP) assert len(plan) >= 2 first = plan[0][0] assert first[0] is m and first[1] == 0 cut = first[2] # cut lands on a 300-s chapter boundary, just under one disc's capacity assert cut % 300 == 0 assert SECS_PER_DISC - 300 < cut <= SECS_PER_DISC # last segment runs to the end (duration 0) assert plan[-1][0][2] == 0 def test_single_long_movie_no_chapters_even_cut(make_movie): m = make_movie(rate_kBps=RATE, length=12000, divide=False) plan = plan_disc_split([m], CAP) assert len(plan) >= 2 # first cut is an exact time cut at capacity assert abs(plan[0][0][2] - SECS_PER_DISC) < 1.0 def test_segments_cover_whole_movie(make_movie): m = make_movie(rate_kBps=RATE, length=12000, divide=False) plan = plan_disc_split([m], CAP) # reconstruct covered span from (start, duration) segments covered = 0.0 for disc in plan: movie, start, duration = disc[0] end = movie.original_length if duration == 0 else start + duration assert start == covered # contiguous, no gaps/overlaps covered = end assert covered == m.original_length def test_menu_reservation_on_first_disc(make_movie): m = make_movie(rate_kBps=RATE, length=3000) # reserve a chunk on disc 1; small movie still fits plan = plan_disc_split([m], CAP, first_disc_reserved_kbytes=500_000) assert len(plan) == 1 def test_empty_project_returns_one_empty_disc(): plan = plan_disc_split([], CAP) assert plan == [[]] def test_zero_rate_does_not_crash(make_movie): m = make_movie(rate_kBps=0, length=3600) plan = plan_disc_split([m], CAP) assert len(plan) >= 1 # --- chapter helpers --- def test_chapter_seconds_auto_and_manual(make_movie): m = make_movie(length=1000, chapters_step=5, manual="2:30,9:00") # auto: 300, 600, 900 (< length-4); manual: 150 (2:30), 540 (9:00) assert _movie_chapter_seconds(m) == [150, 300, 540, 600, 900] def test_chapter_seconds_disabled(make_movie): m = make_movie(length=1000, divide=False) assert _movie_chapter_seconds(m) == [] def test_nearest_chapter_before(): assert _nearest_chapter_before([300, 600, 900], 0, 700) == 600 assert _nearest_chapter_before([300, 600, 900], 0, 250) is None assert _nearest_chapter_before([300, 600, 900], 600, 1000) == 900