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,96 @@
|
||||
package jupiter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"b612.me/astro/basic"
|
||||
)
|
||||
|
||||
func TestGalileanPhenomenonContactEventWrappersMatchBasic(t *testing.T) {
|
||||
records := loadGalileanPublicEventBaseline(t)
|
||||
loc := time.FixedZone("UTC+8", 8*3600)
|
||||
for _, record := range records {
|
||||
startUTC := mustParseGalileanEventTime(t, record.StartUTC)
|
||||
endUTC := mustParseGalileanEventTime(t, record.EndUTC)
|
||||
queryMid := startUTC.Add(endUTC.Sub(startUTC) / 2).In(loc)
|
||||
phenomenonType := GalileanPhenomenonType(record.Type)
|
||||
|
||||
got := ClosestGalileanPhenomenonContactEvent(queryMid, record.Satellite, phenomenonType)
|
||||
want := basic.ClosestJupiterGalileanPhenomenonContactEvent(
|
||||
basic.Date2JDE(queryMid.UTC()),
|
||||
record.Satellite,
|
||||
basic.JupiterGalileanPhenomenonType(phenomenonType),
|
||||
)
|
||||
assertGalileanContactWrapperMatchesBasic(t, record.Label, got, want, loc)
|
||||
}
|
||||
}
|
||||
|
||||
func assertGalileanContactWrapperMatchesBasic(
|
||||
t *testing.T,
|
||||
name string,
|
||||
got GalileanPhenomenonContactEvent,
|
||||
want basic.JupiterGalileanPhenomenonContactEvent,
|
||||
loc *time.Location,
|
||||
) {
|
||||
t.Helper()
|
||||
if got.Valid != want.Valid {
|
||||
t.Fatalf("%s valid mismatch: got %v want %v", name, got.Valid, want.Valid)
|
||||
}
|
||||
if !got.Valid {
|
||||
return
|
||||
}
|
||||
if got.Greatest.Location() != loc {
|
||||
t.Fatalf("%s greatest timezone mismatch", name)
|
||||
}
|
||||
wantGreatest := basic.JDE2DateByZone(want.Greatest, loc, false)
|
||||
if !got.Greatest.Equal(wantGreatest) {
|
||||
t.Fatalf("%s greatest mismatch: got %s want %s", name, got.Greatest.Format(time.RFC3339Nano), wantGreatest.Format(time.RFC3339Nano))
|
||||
}
|
||||
if got.Satellite != want.Satellite || string(got.Type) != string(want.Type) {
|
||||
t.Fatalf("%s id/type mismatch", name)
|
||||
}
|
||||
assertGalileanContactMatchesBasic(t, name+" disappearance", got.Disappearance, want.Disappearance, loc)
|
||||
assertGalileanContactMatchesBasic(t, name+" reappearance", got.Reappearance, want.Reappearance, loc)
|
||||
assertSameGalileanPhenomenon(t, name+" greatest", got.GreatestState, want.GreatestPhenomenon)
|
||||
}
|
||||
|
||||
func assertGalileanContactMatchesBasic(
|
||||
t *testing.T,
|
||||
name string,
|
||||
got GalileanPhenomenonContact,
|
||||
want basic.JupiterGalileanPhenomenonContact,
|
||||
loc *time.Location,
|
||||
) {
|
||||
t.Helper()
|
||||
if got.Valid != want.Valid {
|
||||
t.Fatalf("%s valid mismatch", name)
|
||||
}
|
||||
if !got.Valid {
|
||||
return
|
||||
}
|
||||
wantStart := basic.JDE2DateByZone(want.Start, loc, false)
|
||||
wantModel := basic.JDE2DateByZone(want.ModelCrossing, loc, false)
|
||||
wantEnd := basic.JDE2DateByZone(want.End, loc, false)
|
||||
if got.Start.Location() != loc || got.ModelCrossing.Location() != loc || got.End.Location() != loc {
|
||||
t.Fatalf("%s timezone mismatch", name)
|
||||
}
|
||||
if !got.Start.Equal(wantStart) || !got.ModelCrossing.Equal(wantModel) || !got.End.Equal(wantEnd) {
|
||||
t.Fatalf(
|
||||
"%s time mismatch: got [%s %s %s] want [%s %s %s]",
|
||||
name,
|
||||
got.Start.Format(time.RFC3339Nano),
|
||||
got.ModelCrossing.Format(time.RFC3339Nano),
|
||||
got.End.Format(time.RFC3339Nano),
|
||||
wantStart.Format(time.RFC3339Nano),
|
||||
wantModel.Format(time.RFC3339Nano),
|
||||
wantEnd.Format(time.RFC3339Nano),
|
||||
)
|
||||
}
|
||||
if got.Duration != got.End.Sub(got.Start) {
|
||||
t.Fatalf("%s duration mismatch", name)
|
||||
}
|
||||
if string(got.Phase) != string(want.Phase) {
|
||||
t.Fatalf("%s phase mismatch: got %q want %q", name, got.Phase, want.Phase)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user