"""Unit tests for engine.py's pure continuation planning — the bounded-lead + generation-buffer math. No model, no GPU: `plan_continuation` is a pure function, so these run anywhere torch+numpy import. Contract (post deployed-bug fix): plan_continuation(source, total) returns (lead, new_seconds, buffer_seconds) where - lead = min(source, MAX_LEAD_SECONDS) — tail run-up fed to SA3 - new = extend to `total`, floored at MIN_NEW, bounded so lead+new <= cap - buffer = lead + new — the masked region is [lead, buffer] """ import pytest import engine def test_short_source_keeps_whole_clip_as_lead(): # source shorter than the lead cap: keep the whole clip, extend to total lead, new, buf = engine.plan_continuation(30, 60) assert lead == 30 # whole 30s clip is the lead-in assert new == 30 # generate up to the 60s finished length assert buf == 60 # buffer = lead + new def test_buffer_capped_at_120(): lead, new, buf = engine.plan_continuation(30, 200) assert lead == 30 assert buf == engine.MAX_TOTAL_SECONDS == 120 assert new == 90 # lead(30) + new(90) == 120 cap def test_min_new_floor_enforced(): # asking for barely-longer-than-source still generates at least MIN_NEW lead, new, buf = engine.plan_continuation(30, 31) assert new == engine.MIN_NEW_SECONDS == 5 assert lead == 30 and buf == 35 def test_long_source_clamps_lead_and_still_extends(): # the deployed bug: a 100s source kept the whole clip and masked ~5s, which # the sampler rendered as near-silence. now the lead is clamped and the # request still extends toward the asked-for total. lead, new, buf = engine.plan_continuation(100, 120) assert lead == engine.MAX_LEAD_SECONDS == 30 # not 100s of kept context assert new == 20 # 120 - 100 of fresh audio assert buf == 50 # bounded, healthy buffer assert buf - lead == new # masked span == new audio def test_request_below_source_still_makes_real_audio(): # total < source is contradictory (can't shorten); we still generate a # MIN_NEW tail rather than nothing, and the lead stays bounded. lead, new, buf = engine.plan_continuation(100, 60) assert lead == 30 assert new == engine.MIN_NEW_SECONDS == 5 assert buf == 35 assert buf > lead # mask never inverts def test_mask_brackets_the_new_region_across_inputs(): for src, req in [(15, 40), (29.5, 60), (50, 90), (10, 120), (100, 110)]: lead, new, buf = engine.plan_continuation(src, req) assert lead == min(src, engine.MAX_LEAD_SECONDS) assert abs((buf - lead) - new) < 1e-6 # masked span == new audio assert buf > lead # never inverts assert new >= engine.MIN_NEW_SECONDS - 1e-6 assert buf <= engine.MAX_TOTAL_SECONDS def test_normal_request_reaches_requested_total(): # for a legitimate request (total > source) the finished length is exactly # source + new == total: it extends to what the user asked for. for src, total in [(15, 40), (29.5, 60), (20, 90)]: _, new, _ = engine.plan_continuation(src, total) assert abs((src + new) - total) < 1e-6 def test_overlong_source_raises(): # a clip longer than MAX_SOURCE_SECONDS is a finished track, not a clip for src in (116, 120, 125, 200): with pytest.raises(ValueError): engine.plan_continuation(src, 60) def test_constants_match_sa3_contract(): assert engine.SR == 44100 assert engine.STEPS == 8 assert engine.SAMPLER == "pingpong" assert engine.MAX_TOTAL_SECONDS == 120 assert engine.MAX_LEAD_SECONDS == 30