交付卡、旁白和遥测在有簇区间时按段书写。打分、出题和进区间门槛未改;对半出题和门槛 6 因为没有真值保留回放而没有交付。 Co-Authored-By: Grok (agent loop)
78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
"""Display merge for living candidate intervals. Decision envelopes stay untouched."""
|
||
from __future__ import annotations
|
||
|
||
from scripts.rectification.candidate_window import interval_union_width
|
||
from scripts.rectification.living_display_intervals import (
|
||
inclusive_interval_minutes,
|
||
living_display_label,
|
||
merge_living_display_intervals,
|
||
)
|
||
|
||
DAY = "2000-01-01"
|
||
|
||
|
||
def _at(clock: str) -> str:
|
||
return f"{DAY}T{clock}"
|
||
|
||
|
||
def _interval(start: str, end: str, segment: int = 0, start_offset: int = 0, end_offset: int = 0) -> dict:
|
||
return {
|
||
"start_at": _at(start),
|
||
"end_at": _at(end),
|
||
"segment_index": segment,
|
||
"start_index": start_offset,
|
||
"end_index": end_offset,
|
||
"start_offset_minutes": start_offset,
|
||
"end_offset_minutes": end_offset,
|
||
}
|
||
|
||
|
||
def test_single_segment_stays_one_piece():
|
||
rows = [_interval("08:00", "08:09")]
|
||
merged = merge_living_display_intervals(rows)
|
||
assert len(merged) == 1
|
||
assert inclusive_interval_minutes(merged) == 10
|
||
assert living_display_label(merged, DAY) == "08:00–08:09"
|
||
|
||
|
||
def test_gap_of_four_minutes_merges_and_five_stays_split():
|
||
touch = merge_living_display_intervals([
|
||
_interval("08:00", "08:10"),
|
||
_interval("08:15", "08:20"),
|
||
])
|
||
assert len(touch) == 1
|
||
assert touch[0]["end_at"] == _at("08:20")
|
||
assert inclusive_interval_minutes(touch) == 21
|
||
|
||
split = merge_living_display_intervals([
|
||
_interval("08:00", "08:10"),
|
||
_interval("08:16", "08:20"),
|
||
])
|
||
assert len(split) == 2
|
||
assert inclusive_interval_minutes(split) == 11 + 5
|
||
assert living_display_label(split, DAY) == "08:00–08:10、08:16–08:20"
|
||
|
||
|
||
def test_five_segments_label_keeps_the_first_three_and_the_total():
|
||
rows = [
|
||
_interval("08:00", "08:01"),
|
||
_interval("08:12", "08:13"),
|
||
_interval("08:24", "08:25"),
|
||
_interval("08:36", "08:37"),
|
||
_interval("08:48", "08:49"),
|
||
]
|
||
merged = merge_living_display_intervals(rows)
|
||
assert len(merged) == 5
|
||
assert inclusive_interval_minutes(merged) == 10
|
||
assert living_display_label(merged, DAY) == "08:00–08:01、08:12–08:13、08:24–08:25,等 5 段,共约 10 分钟"
|
||
|
||
|
||
def test_decision_envelope_still_fills_a_declared_segment_gap():
|
||
"""原口径:同一 segment_index 的首尾包络。显示合并不得改这个函数。"""
|
||
rows = [
|
||
_interval("08:00", "08:01", start_offset=0, end_offset=1),
|
||
_interval("08:48", "08:49", start_offset=48, end_offset=49),
|
||
]
|
||
assert interval_union_width(rows) == 50
|
||
assert len(merge_living_display_intervals(rows)) == 2
|