mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-28 11:16:37 +08:00
141 lines
5.3 KiB
Go
141 lines
5.3 KiB
Go
package service
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestDanmakuEpisodeNumber(t *testing.T) {
|
|
cases := []struct {
|
|
in string
|
|
want string
|
|
}{
|
|
{"第1话 裏切りの大空", "1"},
|
|
{"第18话 自己相似的两性同体-Fractal Androgynous-", "18"},
|
|
{"第11话", "11"},
|
|
{"【dandan&animeko】 第29集 那我们走吧", "29"},
|
|
{"第 202 集", "202"},
|
|
{"第1.5话 特别篇", "1.5"},
|
|
{"正片", ""},
|
|
{"", ""},
|
|
}
|
|
for _, tc := range cases {
|
|
if got := danmakuEpisodeNumber(tc.in); got != tc.want {
|
|
t.Errorf("danmakuEpisodeNumber(%q) = %q, want %q", tc.in, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDanmakuEpisodeSubtitle(t *testing.T) {
|
|
cases := []struct {
|
|
in string
|
|
want string
|
|
}{
|
|
{"第1话 裏切りの大空", "裏切りの大空"},
|
|
{"第18话 自己相似的两性同体-Fractal Androgynous-", "自己相似的两性同体-Fractal Androgynous-"},
|
|
{"第11话", ""},
|
|
{"【dandan&animeko】 第29集 那我们走吧", "那我们走吧"},
|
|
{"正片", ""},
|
|
}
|
|
for _, tc := range cases {
|
|
if got := danmakuEpisodeSubtitle(tc.in); got != tc.want {
|
|
t.Errorf("danmakuEpisodeSubtitle(%q) = %q, want %q", tc.in, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 刮削信息匹配:优先使用本地已刮削的年份、集数和集标题,不能再被同名续作
|
|
// 或缺少集标题的平台源抢走。
|
|
func TestMatchScrapedDanmakuEpisodesUsesYearAndEpisodeTitle(t *testing.T) {
|
|
candidates := []DanmakuAnime{
|
|
{AnimeID: 1, AnimeTitle: "命运石之门 0(2018)【TV动画】from dandan&animeko", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 10299, EpisodeTitle: "【dandan&animeko】 第1话 零化域的缺失之环-Absolute Zero-"},
|
|
}},
|
|
{AnimeID: 2, AnimeTitle: "命运石之门(2011)【TV动画】from dandan&animeko", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 10322, EpisodeTitle: "【dandan&animeko】 第1话 始与终的序章-Turning Point-"},
|
|
}},
|
|
{AnimeID: 3, AnimeTitle: "命运石之门(2011)【动漫】from 360", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 10218, EpisodeTitle: "【qq】 第1集"},
|
|
}},
|
|
}
|
|
|
|
got := matchScrapedDanmakuEpisodes(candidates, "命运石之门", 2011, "1", "起始与终结的序章")
|
|
if len(got) != 1 {
|
|
t.Fatalf("matched %d anime, want 1: %#v", len(got), got)
|
|
}
|
|
if got[0].AnimeID != 2 || len(got[0].Episodes) != 1 || got[0].Episodes[0].EpisodeID != 10322 {
|
|
t.Fatalf("picked wrong source: %#v", got)
|
|
}
|
|
}
|
|
|
|
// 真实数据形态:官方 match 给出的剧名+集数在配置源里会命中多季/多版本,
|
|
// 且顺序不可靠。必须靠副标题选中正确的那一集。
|
|
func TestPickDanmakuEpisodeIDDisambiguatesBySubtitle(t *testing.T) {
|
|
// 实测样本:官方 match「命运石之门 第18话 自己相似的两性同体-…」,
|
|
// 配置源首条却是《命运石之门 0》的同一集号。
|
|
candidates := []DanmakuAnime{
|
|
{AnimeID: 1, AnimeTitle: "命运石之门 0(2018)", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 11072, EpisodeTitle: "【dandan&animeko】 第18话 并进对称的牵牛星-Translational"},
|
|
}},
|
|
{AnimeID: 2, AnimeTitle: "命运石之门(2011)", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 11095, EpisodeTitle: "【dandan&animeko】 第18话 自己相似的两性同体-Fractal Androgynous-"},
|
|
}},
|
|
}
|
|
got, ok := pickDanmakuEpisodeID(candidates, "18", "第18话 自己相似的两性同体-Fractal Androgynous-")
|
|
if !ok {
|
|
t.Fatal("expected a confident match")
|
|
}
|
|
if got != 11095 {
|
|
t.Fatalf("picked episodeId %d, want 11095 (first candidate is a different season)", got)
|
|
}
|
|
}
|
|
|
|
// 目标带副标题但没有任何候选的副标题对得上时,必须放弃而不是退回第一条,
|
|
// 否则会给用户播放另一部番的弹幕。
|
|
func TestPickDanmakuEpisodeIDRejectsWhenSubtitleNotFound(t *testing.T) {
|
|
candidates := []DanmakuAnime{
|
|
{AnimeID: 1, AnimeTitle: "某番 第一季", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 111, EpisodeTitle: "第3话 完全不同的标题"},
|
|
}},
|
|
}
|
|
if got, ok := pickDanmakuEpisodeID(candidates, "3", "第3话 期望的标题"); ok {
|
|
t.Fatalf("expected no match, got episodeId %d", got)
|
|
}
|
|
}
|
|
|
|
// 目标没有副标题(如「第11话」)时,退而要求集数一致;集数对不上同样放弃。
|
|
func TestPickDanmakuEpisodeIDNumberOnlyFallback(t *testing.T) {
|
|
candidates := []DanmakuAnime{
|
|
{AnimeID: 1, AnimeTitle: "86 第二季", Episodes: []DanmakuEpisode{
|
|
// 该源对第二季采用绝对集号,第 11 集记作第 22 话。
|
|
{EpisodeID: 11113, EpisodeTitle: "第22话 辛"},
|
|
}},
|
|
}
|
|
if got, ok := pickDanmakuEpisodeID(candidates, "11", "第11话"); ok {
|
|
t.Fatalf("episode number mismatch must be rejected, got episodeId %d", got)
|
|
}
|
|
|
|
same := []DanmakuAnime{
|
|
{AnimeID: 1, AnimeTitle: "某番", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 222, EpisodeTitle: "第11话"},
|
|
}},
|
|
}
|
|
got, ok := pickDanmakuEpisodeID(same, "11", "第11话")
|
|
if !ok || got != 222 {
|
|
t.Fatalf("pickDanmakuEpisodeID = (%d,%v), want (222,true)", got, ok)
|
|
}
|
|
}
|
|
|
|
func TestPickDanmakuEpisodeIDSkipsInvalidIDs(t *testing.T) {
|
|
candidates := []DanmakuAnime{
|
|
{AnimeID: 1, AnimeTitle: "某番", Episodes: []DanmakuEpisode{
|
|
{EpisodeID: 0, EpisodeTitle: "第1话 目标"},
|
|
{EpisodeID: -5, EpisodeTitle: "第1话 目标"},
|
|
{EpisodeID: 333, EpisodeTitle: "第1话 目标"},
|
|
}},
|
|
}
|
|
got, ok := pickDanmakuEpisodeID(candidates, "1", "第1话 目标")
|
|
if !ok || got != 333 {
|
|
t.Fatalf("pickDanmakuEpisodeID = (%d,%v), want (333,true)", got, ok)
|
|
}
|
|
}
|