mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-01 03:56:38 +08:00
112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
package service
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/truewhile/MeBox/internal/model"
|
|
)
|
|
|
|
// 章节标题只有「有语义」时才认。西文关键词要词边界,否则 Options / Weekend
|
|
// 这类标题会被误判成片头/片尾;中文日文按子串匹配。
|
|
func TestChapterTitleKind(t *testing.T) {
|
|
cases := []struct {
|
|
title string
|
|
want string
|
|
}{
|
|
{"Intro", model.SegmentKindIntro},
|
|
{"Opening", model.SegmentKindIntro},
|
|
{"Opening Title", model.SegmentKindIntro},
|
|
{"OP", model.SegmentKindIntro},
|
|
{"NCOP", model.SegmentKindIntro},
|
|
{"片头", model.SegmentKindIntro},
|
|
{"オープニング", model.SegmentKindIntro},
|
|
|
|
{"Recap", model.SegmentKindRecap},
|
|
{"Previously on", model.SegmentKindRecap},
|
|
{"前情提要", model.SegmentKindRecap},
|
|
{"回顾", model.SegmentKindRecap},
|
|
{"あらすじ", model.SegmentKindRecap},
|
|
|
|
{"End Credits", model.SegmentKindCredits},
|
|
{"Credits", model.SegmentKindCredits},
|
|
{"Ending", model.SegmentKindCredits},
|
|
{"ED", model.SegmentKindCredits},
|
|
{"Outro", model.SegmentKindCredits},
|
|
{"片尾", model.SegmentKindCredits},
|
|
{"エンディング", model.SegmentKindCredits},
|
|
|
|
{"Next Episode", model.SegmentKindPreview},
|
|
{"Next time", model.SegmentKindPreview},
|
|
{"Preview", model.SegmentKindPreview},
|
|
{"预告", model.SegmentKindPreview},
|
|
{"次回予告", model.SegmentKindPreview},
|
|
|
|
// 无语义或容易误判的标题一律不认:猜错比没有数据更糟。
|
|
{"", ""},
|
|
{" ", ""},
|
|
{"Chapter 01", ""},
|
|
{"Chapter 12", ""},
|
|
{"Options", ""},
|
|
{"Weekend", ""},
|
|
{"Main Menu", ""},
|
|
{"Menu", ""},
|
|
}
|
|
for _, tc := range cases {
|
|
if got := chapterTitleKind(tc.title); got != tc.want {
|
|
t.Errorf("chapterTitleKind(%q) = %q, want %q", tc.title, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestChaptersToSegmentsOnlyKeepsSemanticChapters(t *testing.T) {
|
|
rows := chaptersToSegments([]ProbeChapter{
|
|
{Index: 0, StartMs: 0, EndMs: 95_000, Title: "Chapter 01"},
|
|
{Index: 1, StartMs: 228_664, EndMs: 246_143, Title: "Opening"},
|
|
{Index: 2, StartMs: 246_500, EndMs: 247_400, Title: "Recap"}, // 不足 chapterMinMs
|
|
{Index: 3, StartMs: 3_431_000, EndMs: 0, Title: "End Credits"},
|
|
})
|
|
if len(rows) != 2 {
|
|
t.Fatalf("rows = %#v, want 2 (Opening + End Credits)", rows)
|
|
}
|
|
if rows[0].Kind != model.SegmentKindIntro || rows[0].StartMs != 228_664 || rows[0].EndMs != 246_143 {
|
|
t.Fatalf("first row = %#v", rows[0])
|
|
}
|
|
if rows[1].Kind != model.SegmentKindCredits || rows[1].StartMs != 3_431_000 || rows[1].EndMs != 0 {
|
|
t.Fatalf("second row = %#v", rows[1])
|
|
}
|
|
for _, row := range rows {
|
|
if row.Source != SegmentSourceFFprobe {
|
|
t.Fatalf("source = %q, want %q", row.Source, SegmentSourceFFprobe)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestChaptersToSegmentsIgnoresUntitledAndNegativeChapters(t *testing.T) {
|
|
rows := chaptersToSegments([]ProbeChapter{
|
|
{Index: 0, StartMs: 0, EndMs: 60_000, Title: ""},
|
|
{Index: 1, StartMs: -1, EndMs: 60_000, Title: "Intro"},
|
|
})
|
|
if len(rows) != 0 {
|
|
t.Fatalf("rows = %#v, want none", rows)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeSegmentSourceFallsBackToAuto(t *testing.T) {
|
|
cases := map[string]string{
|
|
"": SegmentSourceAuto,
|
|
" ": SegmentSourceAuto,
|
|
"auto": SegmentSourceAuto,
|
|
"AUTO": SegmentSourceAuto,
|
|
"ffprobe": SegmentSourceFFprobe,
|
|
" FFprobe ": SegmentSourceFFprobe,
|
|
"theintrodb": SegmentSourceTheIntroDB,
|
|
"TheIntroDB": SegmentSourceTheIntroDB,
|
|
"aniskip": SegmentSourceAuto, // 未知值按 auto 处理
|
|
}
|
|
for input, want := range cases {
|
|
if got := NormalizeSegmentSource(input); got != want {
|
|
t.Errorf("NormalizeSegmentSource(%q) = %q, want %q", input, got, want)
|
|
}
|
|
}
|
|
}
|