Files
schedule_converter/parser/schedule_test.go

235 lines
5.1 KiB
Go
Raw Normal View History

2026-03-13 20:43:44 +08:00
package parser
import (
"os"
"path/filepath"
"testing"
"schedule_converter/models"
2026-03-13 20:43:44 +08:00
)
func TestParseScheduleHTML_FromTestHTML_MergedWeeks(t *testing.T) {
htmlPath := filepath.Join("..", "test.html")
body, err := os.ReadFile(htmlPath)
if err != nil {
t.Fatalf("读取 test.html 失败: %v", err)
}
courses, err := ParseScheduleHTML(string(body))
if err != nil {
t.Fatalf("解析课表失败: %v", err)
}
checkCourseHasWeek(t, courses, "大学物理X1", "王小赛", 1)
checkCourseHasWeek(t, courses, "大学物理X1", "王小赛", 16)
checkCourseHasWeek(t, courses, "数学分析2", "于战华", 2)
checkCourseHasWeek(t, courses, "数学分析2", "于战华", 15)
checkCourseHasRooms(t, courses, "中国近现代史纲要", "苏克", []string{"H楼-447", "H楼-434"})
}
func TestParseScheduleHTML_FromGrkbHTML_ChineseCommaWeeks(t *testing.T) {
htmlPath := filepath.Join("..", "grkb.html")
body, err := os.ReadFile(htmlPath)
if err != nil {
t.Fatalf("读取 grkb.html 失败: %v", err)
}
courses, err := ParseScheduleHTML(string(body))
if err != nil {
t.Fatalf("解析课表失败: %v", err)
}
checkCourseHasWeek(t, courses, "数理统计", "黄春茂", 10)
checkCourseHasWeek(t, courses, "数理统计", "黄春茂", 11)
checkCourseHasWeek(t, courses, "数理统计", "黄春茂", 12)
checkCourseHasWeek(t, courses, "微分几何", "李鹏程", 2)
checkCourseHasWeek(t, courses, "微分几何", "李鹏程", 8)
checkCourseHasWeek(t, courses, "微分几何", "李鹏程", 9)
checkCourseRoomForWeek(t, courses, "微分几何", "李鹏程", 9, "N楼-331")
checkCourseRoomForWeek(t, courses, "微分几何", "李鹏程", 8, "N楼-335")
}
func checkCourseWeeks(
t *testing.T,
courses []models.Course,
name, teacher, day string,
section []int,
wantStart, wantEnd int,
) {
t.Helper()
for _, c := range courses {
if c.Name != name || c.Teacher != teacher {
continue
}
for _, s := range c.Schedule {
if s.Day != day || !sameInts(s.Section, section) {
continue
}
if len(s.Weeks) == 0 {
t.Fatalf("%s/%s 周次为空", name, teacher)
}
if s.Weeks[0] != wantStart || s.Weeks[len(s.Weeks)-1] != wantEnd {
t.Fatalf("%s/%s 周次范围错误: got=%v want=%d..%d", name, teacher, s.Weeks, wantStart, wantEnd)
}
return
}
}
t.Fatalf("未找到课程: %s/%s day=%s section=%v", name, teacher, day, section)
}
func sameInts(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
func checkScheduleContainsWeeks(
t *testing.T,
courses []models.Course,
name, teacher, day string,
section []int,
wantWeeks []int,
) {
t.Helper()
for _, c := range courses {
if c.Name != name || c.Teacher != teacher {
continue
}
for _, s := range c.Schedule {
if s.Day != day || !sameInts(s.Section, section) {
continue
}
if len(s.Weeks) == 0 {
t.Fatalf("%s/%s 周次为空", name, teacher)
}
for _, w := range wantWeeks {
if !containsInt(s.Weeks, w) {
t.Fatalf("%s/%s 周次缺失: want include=%d got=%v", name, teacher, w, s.Weeks)
}
}
return
}
}
t.Fatalf("未找到课程: %s/%s day=%s section=%v", name, teacher, day, section)
}
func containsInt(arr []int, target int) bool {
for _, v := range arr {
if v == target {
return true
}
}
return false
}
func checkCourseHasWeek(
t *testing.T,
courses []models.Course,
name, teacher string,
week int,
) {
t.Helper()
for _, c := range courses {
if c.Name != name || c.Teacher != teacher {
continue
}
for _, s := range c.Schedule {
if containsInt(s.Weeks, week) {
return
}
}
}
t.Fatalf("%s/%s 缺少第%d周", name, teacher, week)
}
func checkCourseRoomForWeek(
t *testing.T,
courses []models.Course,
name, teacher string,
week int,
wantRoom string,
) {
t.Helper()
for _, c := range courses {
if c.Name != name || c.Teacher != teacher {
continue
}
for _, s := range c.Schedule {
if containsInt(s.Weeks, week) && c.Room == wantRoom {
return
}
}
}
t.Fatalf("%s/%s 第%d周未匹配到地点 %s", name, teacher, week, wantRoom)
}
func checkCourseHasRooms(
t *testing.T,
courses []models.Course,
name, teacher string,
wantRooms []string,
) {
t.Helper()
roomSet := map[string]bool{}
for _, c := range courses {
if c.Name == name && c.Teacher == teacher {
roomSet[c.Room] = true
}
}
for _, room := range wantRooms {
if !roomSet[room] {
t.Fatalf("%s/%s 缺少地点: %s, 当前地点集合: %v", name, teacher, room, roomSet)
}
}
}
func checkCourseAnyScheduleContainsWeeks(
t *testing.T,
courses []models.Course,
name, teacher string,
wantWeeks []int,
) {
t.Helper()
foundCourse := false
for _, c := range courses {
if c.Name != name || c.Teacher != teacher {
continue
}
foundCourse = true
for _, s := range c.Schedule {
allFound := true
for _, w := range wantWeeks {
if !containsInt(s.Weeks, w) {
allFound = false
break
}
}
if allFound {
return
}
}
}
if !foundCourse {
t.Fatalf("未找到课程: %s/%s", name, teacher)
}
t.Fatalf("%s/%s 所有排课都不包含预期周次: want=%v", name, teacher, wantWeeks)
}