Files
astro/eclipse/svg/solar_map_date_gate_test.go
T
b612 2bf8478639 feat: 完善日月食与月掩几何链路并扩展历法接口
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑
- 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口
- 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界
- 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名
- 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验
- 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口
- 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
2026-09-17 12:27:40 +08:00

88 lines
2.8 KiB
Go

package svg
import (
"strings"
"testing"
"time"
eclipsecore "b612.me/astro/eclipse"
)
// 核心判定当天无日食时,三个日食图入口都必须返回 false,与 LunarEclipseMapSVG 的日期门一致;
// 偏食足迹是“取最近一次”语义,缺这道门会把邻近日期的图当成当天的图交出去。
func TestSolarEclipseMapSVGRequiresEclipseOnDate(t *testing.T) {
type entry struct {
name string
render func(time.Time, SolarEclipseMapSVGOptions) (string, bool)
global func(time.Time) (eclipsecore.SolarEclipseInfo, bool)
}
entries := []entry{
{
name: "default",
render: SolarEclipseMapSVG,
global: eclipsecore.SolarEclipseOnDateNASABulletinSplitK,
},
{
name: "nasaSplitK",
render: SolarEclipseMapSVGNASABulletinSplitK,
global: eclipsecore.SolarEclipseOnDateNASABulletinSplitK,
},
{
name: "iauSingleK",
render: SolarEclipseMapSVGIAUSingleK,
global: eclipsecore.SolarEclipseOnDateIAUSingleK,
},
}
// 2024-04-08 是本组日期里唯一有日食的一天,其余都在最近一次日食前后半个朔望月内。
for _, test := range []struct {
day string
want bool
}{
{day: "2024-04-08", want: true},
{day: "2024-04-15"},
{day: "2024-04-20"},
{day: "2024-04-23"},
{day: "2024-04-24"},
} {
date, err := time.Parse("2006-01-02", test.day)
if err != nil {
t.Fatalf("bad fixture date %q: %v", test.day, err)
}
for _, entry := range entries {
_, coreOK := entry.global(date)
if coreOK != test.want {
t.Fatalf("%s %s: core eclipse gate = %v, want %v", entry.name, test.day, coreOK, test.want)
}
rendered, ok := entry.render(date, SolarEclipseMapSVGOptions{
Width: 900, Height: 620, Location: time.UTC, PartialStep: 10 * time.Minute,
})
if ok != test.want {
t.Fatalf("%s %s: map gate = %v, want %v (core says %v)", entry.name, test.day, ok, test.want, coreOK)
}
if test.want && rendered == "" {
t.Fatalf("%s %s: gate passed but the map is empty", entry.name, test.day)
}
if !test.want && rendered != "" {
t.Fatalf("%s %s: rejected date still returned %d bytes", entry.name, test.day, len(rendered))
}
}
}
}
// 过了日期门的日期必须仍带完整等时线层:等时线自己还要查一次核心,门不能把它挡掉。
func TestSolarEclipseMapOnDateKeepsIsochrones(t *testing.T) {
rendered, ok := SolarEclipseMapSVG(
time.Date(2024, time.April, 8, 0, 0, 0, 0, time.UTC),
SolarEclipseMapSVGOptions{
Width: 900, Height: 620, Location: time.UTC,
PartialStep: 10 * time.Minute, GreatestTimeStep: 30 * time.Minute,
},
)
if !ok {
t.Fatal("2024-04-08 is an eclipse date but the map was rejected")
}
if got := strings.Count(rendered, `class="solar-greatest-time-isoline"`); got != 7 {
t.Fatalf("isochrone paths = %d, want the full 7-branch fan", got)
}
}