Build and Publish Server / build (push) Successful in 2m13s
维基百科在生产服务器被阻断,改用百度百科开放接口:
- 端点 /cms/home/eventsOnHistory/{MM}.json,按月返回结构化 JSON
- 12 次请求替代原 366 次,大幅减负
- type 直接映射 event/birth/death,festival 字段提取节假日
- 清洗 title/desc 中的 HTML 标签
- 2 月无 29 日,全年 365 天
- 本地验证:365 天 4805 条,12/12 月全成功
115 lines
4.1 KiB
Go
115 lines
4.1 KiB
Go
package service
|
||
|
||
import (
|
||
"strings"
|
||
"testing"
|
||
)
|
||
|
||
// 取自百度百科 /cms/home/eventsOnHistory/08.json 的真实片段(8月12日/13日)
|
||
const sampleBaikeJSON = `{"08":{
|
||
"0812":[
|
||
{"year":"-30","title":"埃及艳后<a target=\"_blank\" href=\"https://baike.baidu.com/item/x\">克利奥帕特拉七世</a>逝世","festival":"","link":"https://baike.baidu.com/item/x","type":"death","desc":"克利奥帕特拉七世"},
|
||
{"year":"1848","title":"英国著名小说家<a target=\"_blank\" href=\"x\">乔治·艾略特</a>出生","festival":"","link":"x","type":"birth","desc":"x"},
|
||
{"year":"1848","title":"英国著名小说家乔治·艾略特出生","festival":"","link":"x","type":"birth","desc":"x"},
|
||
{"year":"1905","title":"挪威音乐家<a href=\"x\">某</a>指挥首演","festival":"","link":"x","type":"event","desc":"x"}
|
||
],
|
||
"0813":[
|
||
{"year":"604","title":"隋文帝<a href=\"x\">杨坚</a>逝世","festival":"国际左撇子日","link":"x","type":"death","desc":"x"},
|
||
{"year":"1926","title":"古巴革命领导人<a href=\"x\">卡斯特罗</a>出生","festival":"国际左撇子日","link":"x","type":"birth","desc":"x"},
|
||
{"year":"1910","title":"某事件<a href=\"x\">发生</a>","festival":"国际左撇子日","link":"x","type":"event","desc":"x"},
|
||
{"year":"abc","title":"年份非法的<a href=\"x\">事件</a>条目","festival":"国际左撇子日","link":"x","type":"event","desc":"x"}
|
||
]
|
||
}}`
|
||
|
||
func TestParseBaikeMonth(t *testing.T) {
|
||
items, err := parseBaikeMonth([]byte(sampleBaikeJSON), 8)
|
||
if err != nil {
|
||
t.Fatalf("parseBaikeMonth 失败: %v", err)
|
||
}
|
||
|
||
count := func(kind string) int {
|
||
n := 0
|
||
for _, it := range items {
|
||
if it.Kind == kind {
|
||
n++
|
||
}
|
||
}
|
||
return n
|
||
}
|
||
|
||
// 0812: 1 death + 2 birth(重复去重后1) + 1 event = 3;0813: 1 death + 1 birth + 2 event = 4
|
||
if got := count("death"); got != 2 {
|
||
t.Errorf("death 条目数 = %d, 期望 2", got)
|
||
}
|
||
if got := count("birth"); got != 2 { // 0812 重复出生条目应去重
|
||
t.Errorf("birth 条目数 = %d, 期望 2", got)
|
||
}
|
||
if got := count("event"); got != 3 {
|
||
t.Errorf("event 条目数 = %d, 期望 3", got)
|
||
}
|
||
// 国际左撇子日只在 0813,去重后 1 条 festival
|
||
if got := count("festival"); got != 1 {
|
||
t.Errorf("festival 条目数 = %d, 期望 1", got)
|
||
}
|
||
|
||
// 校验具体条目
|
||
assertItem := func(kind string, day, wantYear int, wantContent string) {
|
||
for _, it := range items {
|
||
if it.Kind == kind && it.Day == day && it.Content == wantContent {
|
||
if it.Year != wantYear {
|
||
t.Errorf("%q 年份 = %d, 期望 %d", wantContent, it.Year, wantYear)
|
||
}
|
||
if it.Month != 8 {
|
||
t.Errorf("%q 月份 = %d, 期望 8", wantContent, it.Month)
|
||
}
|
||
return
|
||
}
|
||
}
|
||
t.Errorf("未找到条目: kind=%s day=%d content=%q", kind, day, wantContent)
|
||
}
|
||
assertItem("death", 12, -30, "埃及艳后克利奥帕特拉七世逝世")
|
||
assertItem("birth", 12, 1848, "英国著名小说家乔治·艾略特出生")
|
||
assertItem("event", 13, 0, "年份非法的事件条目") // 非法年份应为 0
|
||
assertItem("festival", 13, 0, "国际左撇子日")
|
||
|
||
// 不应残留 HTML 标签
|
||
for _, it := range items {
|
||
if strings.Contains(it.Content, "<a") || strings.Contains(it.Content, "href") ||
|
||
strings.Contains(it.Content, "</a>") {
|
||
t.Errorf("条目残留 HTML 标签: %q", it.Content)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestParseBaikeYear(t *testing.T) {
|
||
cases := map[string]int{
|
||
"1912": 1912,
|
||
"-30": -30,
|
||
"0": 0,
|
||
"abc": 0,
|
||
"": 0,
|
||
" 77 ": 77,
|
||
}
|
||
for in, want := range cases {
|
||
if got := parseBaikeYear(in); got != want {
|
||
t.Errorf("parseBaikeYear(%q) = %d, 期望 %d", in, got, want)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestNormalizeKind(t *testing.T) {
|
||
if normalizeKind("event") != "event" || normalizeKind("birth") != "birth" ||
|
||
normalizeKind("death") != "death" || normalizeKind("other") != "" ||
|
||
normalizeKind(" EVENT ") != "event" {
|
||
t.Error("normalizeKind 映射异常")
|
||
}
|
||
}
|
||
|
||
func TestCleanHTMLText(t *testing.T) {
|
||
in := `埃及艳后<a target="_blank" href="x">克利奥帕特拉七世</a> 逝世 test`
|
||
want := "埃及艳后克利奥帕特拉七世 逝世 test"
|
||
if got := cleanHTMLText(in); got != want {
|
||
t.Errorf("cleanHTMLText = %q, 期望 %q", got, want)
|
||
}
|
||
}
|