"""[end:handle] explicit end markers: a video started with end_on=end_marker stops at the first [end:handle] placed after it.""" import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from gnommo.transformer import _extract_video_events, MarkerTiming from gnommo.models import VideoSource, CutoutDefinition def check(name, cond): print(f" {'PASS' if cond else 'FAIL'} {name}") assert cond, name VIDEOS = {"fart": VideoSource(source_file="fart.mp4", cutout="fullscreen", layer="below")} CUTOUTS = {"fullscreen": CutoutDefinition(x=0, y=0, height=1080, width=1920)} def mt(mid, t, ov=None): return MarkerTiming(mid, t, "text", 1.0, ov) # 1. [vfb:fart, end_on=end_marker] @10 ; [end:fart] @25 → ends at 25 events, warns = _extract_video_events( [mt("vfb:fart", 10.0, {"end_on": "end_marker"}), mt("end:fart", 25.0)], VIDEOS, CUTOUTS, {}, 100.0, ) check("[end:fart] is not itself a video event", len(events) == 1) check("video starts at 10.0", abs(events[0].start_time - 10.0) < 1e-6) check("video ends at the [end:fart] marker (25.0)", abs(events[0].end_time - 25.0) < 1e-6) check("no warnings", not warns) # 2. earliest [end:fart] AFTER the start wins; an earlier one is ignored (reuse handle) events2, _ = _extract_video_events( [ mt("end:fart", 5.0), # before start → ignored mt("vfb:fart", 10.0, {"end_on": "end_marker"}), mt("end:fart", 20.0), # first after start mt("end:fart", 40.0), ], VIDEOS, CUTOUTS, {}, 100.0, ) check("uses first end marker after start (20.0)", abs(events2[0].end_time - 20.0) < 1e-6) # 3. fallback: end_on=end_marker but no [end:fart] → next video + warning videos3 = {**VIDEOS, "other": VideoSource(source_file="o.mp4", cutout="square")} cutouts3 = {**CUTOUTS, "square": CutoutDefinition(x=0, y=0, height=864, width=864)} events3, warns3 = _extract_video_events( [mt("vfb:fart", 10.0, {"end_on": "end_marker"}), mt("vst:other", 30.0)], videos3, cutouts3, {}, 100.0, ) fart_ev = next(e for e in events3 if e.video_id == "fart") check("fallback ends at next video (30.0)", abs(fart_ev.end_time - 30.0) < 1e-6) check("warns about the missing [end:fart]", any("end_on=end_marker" in w for w in warns3)) print("\nAll [end:handle] tests passed.")