feat: 扩展天文计算能力
- 新增日食、月食、本地可见性、中心线、半影区域、SVG 图示与沙罗周期信息 - 新增行星冲合、留、方照、物理星历、视直径、相位、亮肢角、轨道节点等计算 - 新增木星伽利略卫星位置、现象与接触事件计算 - 新增恒星星表、星座判定、自行修正与观测辅助能力 - 新增 coord、formula、orbit、sundial、lite/sun、lite/moon 等扩展包 - 完善农历年号、月相英文别名、视差角、大气质量、折射、日晷与双星计算 - 增加 NASA、JPL Horizons、IMCCE 等回归测试数据与基线测试 - 重构基础算法文件组织,补充大量公开 API 注释和语义回归测试 - 更新中文和英文 README,补充示例、精度说明、SVG 配图
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package svg
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"b612.me/astro/basic"
|
||||
)
|
||||
|
||||
func TestLunarEclipseSVG(t *testing.T) {
|
||||
svg, ok := LunarEclipseSVG(
|
||||
time.Date(2026, 3, 3, 0, 0, 0, 0, time.UTC),
|
||||
LunarEclipseSVGOptions{Width: 720, Height: 480, Step: 10 * time.Minute},
|
||||
)
|
||||
if !ok {
|
||||
t.Fatalf("expected lunar eclipse SVG")
|
||||
}
|
||||
for _, want := range []string{"<svg", "月全食", "黄道", "赤经", "黄经", "狮子座", "方位", "P1", "U1", "U2", "食甚", "U3", "U4", "P4", "UTC+8", "沙罗"} {
|
||||
if !strings.Contains(svg, want) {
|
||||
t.Fatalf("SVG missing %q", want)
|
||||
}
|
||||
}
|
||||
if got := strings.Count(svg, `class="event-moon"`); got != 7 {
|
||||
t.Fatalf("event moon count = %d, want 7", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunarEclipseSVGEnglishOption(t *testing.T) {
|
||||
svg, ok := LunarEclipseSVG(
|
||||
time.Date(2026, 3, 3, 0, 0, 0, 0, time.UTC),
|
||||
LunarEclipseSVGOptions{Language: "en", Location: time.UTC},
|
||||
)
|
||||
if !ok {
|
||||
t.Fatalf("expected lunar eclipse SVG")
|
||||
}
|
||||
for _, want := range []string{"Total Lunar Eclipse", "Ecliptic", "Moon: RA", "ecl.lon", "PA", "Greatest", "Contacts (UTC)", "Lunar Saros"} {
|
||||
if !strings.Contains(svg, want) {
|
||||
t.Fatalf("SVG missing %q", want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunarEclipseSVGCustomText(t *testing.T) {
|
||||
svg, ok := LunarEclipseSVG(
|
||||
time.Date(2026, 3, 3, 0, 0, 0, 0, time.UTC),
|
||||
LunarEclipseSVGOptions{
|
||||
Title: "Custom lunar title",
|
||||
SummaryText: "Custom lunar summary",
|
||||
MaximumText: "Custom lunar maximum",
|
||||
CoordinatesText: "Custom lunar coordinates",
|
||||
DurationText: "Custom lunar duration",
|
||||
MetaText: "Custom lunar meta",
|
||||
ContactsTitle: "Custom lunar contacts",
|
||||
DirectionText: "Custom lunar direction",
|
||||
FooterNote: "Custom lunar footer",
|
||||
},
|
||||
)
|
||||
if !ok {
|
||||
t.Fatalf("expected lunar eclipse SVG")
|
||||
}
|
||||
for _, want := range []string{
|
||||
"Custom lunar title",
|
||||
"Custom lunar summary",
|
||||
"Custom lunar maximum",
|
||||
"Custom lunar coordinates",
|
||||
"Custom lunar duration",
|
||||
"Custom lunar meta",
|
||||
"Custom lunar contacts",
|
||||
"Custom lunar direction",
|
||||
"Custom lunar footer",
|
||||
} {
|
||||
if !strings.Contains(svg, want) {
|
||||
t.Fatalf("SVG missing custom text %q", want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunarEclipseSVGNoEvent(t *testing.T) {
|
||||
_, ok := LunarEclipseSVG(time.Date(2026, 1, 3, 0, 0, 0, 0, time.UTC), LunarEclipseSVGOptions{})
|
||||
if ok {
|
||||
t.Fatalf("unexpected lunar eclipse SVG for no-event date")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunarEclipseSVGEventPointsExpandMergedLabels(t *testing.T) {
|
||||
events := lunarEclipseSVGEventPoints([]lunarEclipseSVGPoint{
|
||||
{
|
||||
LunarEclipseDiagramPoint: basic.LunarEclipseDiagramPoint{
|
||||
Label: "Greatest",
|
||||
Labels: []string{"U2", "Greatest", "U3"},
|
||||
},
|
||||
},
|
||||
})
|
||||
if got, want := len(events), 3; got != want {
|
||||
t.Fatalf("event point count = %d, want %d", got, want)
|
||||
}
|
||||
want := []string{"U2", "Greatest", "U3"}
|
||||
for i, label := range want {
|
||||
if events[i].Label != label {
|
||||
t.Fatalf("event labels = %#v, want %v", []string{events[0].Label, events[1].Label, events[2].Label}, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user