Files
schedule_converter/parser/schedule_test.go
lafay 74438c1f7f refactor: 重构代码架构并使用 Modern Go 特性
- 重命名模块 jwts -> schedule_converter
- 新增 service 包,统一业务逻辑层
- 新增 pkg/logger 包,使用 slog 结构化日志
- 新增 pkg/errors 包,统一错误处理
- 拆分 captcha 包,图片识别移至 service/recognizer
- 清理 models 包,只保留数据结构定义
- 消除 grpc/handler.go 中的重复代码
- 简化 main.go,使用 slog 和 context
- 配置支持单例模式和结构化配置
- 使用 any 替代 interface{}
- 使用 sync.Map 替代 map + RWMutex
2026-03-16 13:40:53 +08:00

235 lines
5.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package parser
import (
"os"
"path/filepath"
"testing"
"schedule_converter/models"
)
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)
}