package web import ( "testing" "time" "gitea.kazu634.com/kazu634/tver/internal/store" ) func TestSortJobsNaturally(t *testing.T) { base := time.Date(2026, 10, 10, 0, 0, 0, 0, time.UTC) jobs := []store.Job{ {ID: 8, Title: "第10話", FinishedAt: timePointer(base)}, {ID: 7, Title: "第2話", FinishedAt: timePointer(base)}, {ID: 6, Title: "#10", FinishedAt: timePointer(base)}, {ID: 5, Title: "#9", FinishedAt: timePointer(base)}, {ID: 4, Title: "第2話", FinishedAt: timePointer(base.Add(time.Hour))}, {ID: 3, Title: "第2話", FinishedAt: timePointer(base.Add(-time.Hour))}, {ID: 2, Title: "第02話", FinishedAt: timePointer(base.Add(-time.Hour))}, {ID: 1, Title: "おまけ", FinishedAt: timePointer(base)}, } sortJobsNaturally(jobs) got := make([]int64, len(jobs)) for i := range jobs { got[i] = jobs[i].ID } want := []int64{5, 6, 1, 2, 3, 7, 4, 8} for i := range want { if got[i] != want[i] { t.Fatalf("自然順=%v want=%v", got, want) } } } func TestNaturalOrderUsesIDAfterEqualTitleAndFinishedAt(t *testing.T) { finished := time.Date(2026, 10, 10, 0, 0, 0, 0, time.UTC) jobs := []store.Job{ {ID: 20, Title: "#9", FinishedAt: &finished}, {ID: 10, Title: "#9", FinishedAt: &finished}, } sortJobsNaturally(jobs) if jobs[0].ID != 10 || jobs[1].ID != 20 { t.Fatalf("同順位のID順: %+v", jobs) } } func TestNaturalOrderTreatsLeadingZerosAsTheSameNumber(t *testing.T) { base := time.Date(2026, 10, 10, 0, 0, 0, 0, time.UTC) jobs := []store.Job{ {ID: 30, Title: "数字なし", FinishedAt: timePointer(base.Add(-time.Hour))}, {ID: 20, Title: "#09", FinishedAt: timePointer(base)}, {ID: 10, Title: "#9", FinishedAt: timePointer(base.Add(time.Hour))}, } sortJobsNaturally(jobs) if jobs[0].ID != 20 || jobs[1].ID != 10 || jobs[2].ID != 30 { t.Fatalf("先頭ゼロと数字なしの自然順: %+v", jobs) } } func timePointer(value time.Time) *time.Time { return &value }