Files
astro/eclipse/context_test.go
T

187 lines
13 KiB
Go
Raw Normal View History

package eclipse
import (
"b612.me/astro/basic"
"b612.me/astro/internal/ephem"
"reflect"
"testing"
"time"
)
type contextAPI interface {
ClosestGeometricLocalLunarEclipse(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
ClosestGeometricLocalLunarEclipseChauvenet(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
ClosestGeometricLocalLunarEclipseDanjon(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
ClosestGeometricLocalSolarEclipse(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
ClosestGeometricLocalSolarEclipseIAUSingleK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
ClosestGeometricLocalSolarEclipseNASABulletinSplitK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
ClosestLocalAnnularSolarEclipse(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
ClosestLocalLunarEclipse(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
ClosestLocalLunarEclipseChauvenet(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
ClosestLocalLunarEclipseDanjon(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
ClosestLocalSolarEclipse(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
ClosestLocalSolarEclipseIAUSingleK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
ClosestLocalSolarEclipseNASABulletinSplitK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
ClosestLocalTotalLunarEclipse(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
ClosestLocalTotalSolarEclipse(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
ClosestLunarEclipse(date time.Time) LunarEclipseInfo
ClosestLunarEclipseChauvenet(date time.Time) LunarEclipseInfo
ClosestLunarEclipseDanjon(date time.Time) LunarEclipseInfo
ClosestSolarEclipse(date time.Time) SolarEclipseInfo
ClosestSolarEclipseIAUSingleK(date time.Time) SolarEclipseInfo
ClosestSolarEclipseNASABulletinSplitK(date time.Time) SolarEclipseInfo
ClosestSolarEclipseWithOptions(date time.Time, options SolarEclipseOptions) SolarEclipseInfo
GeometricLocalLunarEclipseOnDate(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
GeometricLocalLunarEclipseOnDateChauvenet(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
GeometricLocalLunarEclipseOnDateDanjon(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
GeometricLocalSolarEclipseOnDate(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
GeometricLocalSolarEclipseOnDateIAUSingleK(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
GeometricLocalSolarEclipseOnDateNASABulletinSplitK(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
LastGeometricLocalLunarEclipse(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
LastGeometricLocalLunarEclipseChauvenet(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
LastGeometricLocalLunarEclipseDanjon(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
LastGeometricLocalSolarEclipse(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
LastGeometricLocalSolarEclipseIAUSingleK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
LastGeometricLocalSolarEclipseNASABulletinSplitK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
LastLocalAnnularSolarEclipse(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
LastLocalLunarEclipse(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
LastLocalLunarEclipseChauvenet(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
LastLocalLunarEclipseDanjon(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
LastLocalSolarEclipse(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
LastLocalSolarEclipseIAUSingleK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
LastLocalSolarEclipseNASABulletinSplitK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
LastLocalTotalLunarEclipse(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
LastLocalTotalSolarEclipse(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
LastLunarEclipse(date time.Time) LunarEclipseInfo
LastLunarEclipseChauvenet(date time.Time) LunarEclipseInfo
LastLunarEclipseDanjon(date time.Time) LunarEclipseInfo
LastSolarEclipse(date time.Time) SolarEclipseInfo
LastSolarEclipseIAUSingleK(date time.Time) SolarEclipseInfo
LastSolarEclipseNASABulletinSplitK(date time.Time) SolarEclipseInfo
LastSolarEclipseWithOptions(date time.Time, options SolarEclipseOptions) SolarEclipseInfo
LocalLunarEclipseOnDate(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
LocalLunarEclipseOnDateChauvenet(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
LocalLunarEclipseOnDateDanjon(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
LocalSolarEclipseInfoInUT1(info LocalSolarEclipseInfo) LocalSolarEclipseInfo
LocalSolarEclipseOnDate(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
LocalSolarEclipseOnDateIAUSingleK(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
LocalSolarEclipseOnDateNASABulletinSplitK(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
LocalSolarEclipseOnDateWithOptions(date time.Time, lon, lat, height float64, options SolarEclipseOptions) (LocalSolarEclipseInfo, bool)
LunarEclipseGeocentricPanelAt(date time.Time) (LunarEclipseGeocentricPanel, bool)
LunarEclipseGeocentricPanelChauvenet(date time.Time) (LunarEclipseGeocentricPanel, bool)
LunarEclipseInfoInUT1(info LunarEclipseInfo) LunarEclipseInfo
LunarEclipseOnDate(date time.Time) (LunarEclipseInfo, bool)
LunarEclipseOnDateChauvenet(date time.Time) (LunarEclipseInfo, bool)
LunarEclipseOnDateDanjon(date time.Time) (LunarEclipseInfo, bool)
NewSolarEclipseShadowSolver(options SolarEclipseShadowSolverOptions) *SolarEclipseShadowSolver
NextGeometricLocalLunarEclipse(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
NextGeometricLocalLunarEclipseChauvenet(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
NextGeometricLocalLunarEclipseDanjon(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
NextGeometricLocalSolarEclipse(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
NextGeometricLocalSolarEclipseIAUSingleK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
NextGeometricLocalSolarEclipseNASABulletinSplitK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
NextLocalAnnularSolarEclipse(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
NextLocalLunarEclipse(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
NextLocalLunarEclipseChauvenet(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
NextLocalLunarEclipseDanjon(date time.Time, lon, lat, height float64) LocalLunarEclipseInfo
NextLocalSolarEclipse(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
NextLocalSolarEclipseIAUSingleK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
NextLocalSolarEclipseNASABulletinSplitK(date time.Time, lon, lat, height float64) LocalSolarEclipseInfo
NextLocalTotalLunarEclipse(date time.Time, lon, lat, height float64) (LocalLunarEclipseInfo, bool)
NextLocalTotalSolarEclipse(date time.Time, lon, lat, height float64) (LocalSolarEclipseInfo, bool)
NextLunarEclipse(date time.Time) LunarEclipseInfo
NextLunarEclipseChauvenet(date time.Time) LunarEclipseInfo
NextLunarEclipseDanjon(date time.Time) LunarEclipseInfo
NextSolarEclipse(date time.Time) SolarEclipseInfo
NextSolarEclipseIAUSingleK(date time.Time) SolarEclipseInfo
NextSolarEclipseNASABulletinSplitK(date time.Time) SolarEclipseInfo
NextSolarEclipseWithOptions(date time.Time, options SolarEclipseOptions) SolarEclipseInfo
SearchLocalCentralSolarEclipse(
date time.Time, lon, lat, height float64,
options SolarEclipseLocalSearchOptions,
) (LocalSolarEclipseInfo, SolarEclipseLocalSearchStatus)
SolarEclipseBesselianElements(
seedJDE float64, options SolarEclipseBesselianElementsOptions,
) (SolarEclipseBesselianElementsResult, bool)
SolarEclipseBesselianMuForPublishedTable(
mu SolarEclipseBesselianPolynomial, deltaTSeconds float64,
) SolarEclipseBesselianPolynomial
SolarEclipseCandidates(
start, end time.Time, options SolarEclipseCandidateOptions,
) []SolarEclipseCandidate
SolarEclipseCentralPath(date time.Time, options SolarEclipsePathOptions) (SolarEclipsePath, bool)
SolarEclipseCentralPathIAUSingleK(date time.Time, options SolarEclipsePathOptions) (SolarEclipsePath, bool)
SolarEclipseCentralPathNASABulletinSplitK(date time.Time, options SolarEclipsePathOptions) (SolarEclipsePath, bool)
SolarEclipseGeocentricPanelAt(date time.Time) (SolarEclipseGeocentricPanel, bool)
SolarEclipseGeocentricPanelIAUSingleK(date time.Time) (SolarEclipseGeocentricPanel, bool)
SolarEclipseGeocentricPanelInUT1(panel SolarEclipseGeocentricPanel) SolarEclipseGeocentricPanel
SolarEclipseGeocentricPanelWithOptions(date time.Time, options SolarEclipseOptions) (SolarEclipseGeocentricPanel, bool)
SolarEclipseInfoInUT1(info SolarEclipseInfo) SolarEclipseInfo
SolarEclipseOnDate(date time.Time) (SolarEclipseInfo, bool)
SolarEclipseOnDateIAUSingleK(date time.Time) (SolarEclipseInfo, bool)
SolarEclipseOnDateNASABulletinSplitK(date time.Time) (SolarEclipseInfo, bool)
SolarEclipseOnDateWithOptions(date time.Time, options SolarEclipseOptions) (SolarEclipseInfo, bool)
SolarEclipsePartialArea(date time.Time, options SolarEclipsePartialAreaOptions) (SolarEclipsePartialAreaInfo, bool)
SolarEclipsePartialAreaIAUSingleK(date time.Time, options SolarEclipsePartialAreaOptions) (SolarEclipsePartialAreaInfo, bool)
SolarEclipsePartialAreaNASABulletinSplitK(date time.Time, options SolarEclipsePartialAreaOptions) (SolarEclipsePartialAreaInfo, bool)
SolarEclipsePartialFootprints(date time.Time, options SolarEclipsePartialFootprintOptions) (SolarEclipsePartialFootprintsInfo, bool)
SolarEclipsePartialFootprintsIAUSingleK(date time.Time, options SolarEclipsePartialFootprintOptions) (SolarEclipsePartialFootprintsInfo, bool)
SolarEclipsePartialFootprintsInUT1(info SolarEclipsePartialFootprintsInfo) SolarEclipsePartialFootprintsInfo
SolarEclipsePartialFootprintsNASABulletinSplitK(date time.Time, options SolarEclipsePartialFootprintOptions) (SolarEclipsePartialFootprintsInfo, bool)
SolarEclipsePathInUT1(path SolarEclipsePath) SolarEclipsePath
SolarEclipseShadowAt(value time.Time) (SolarEclipseShadowInstant, bool)
SolarEclipseShadowBetween(
start, end time.Time, step time.Duration,
) []SolarEclipseShadowInstant
SolarEclipseShadowBetweenWithOptions(
start, end time.Time, step time.Duration, options SolarEclipseShadowSolverOptions,
) []SolarEclipseShadowInstant
SolarEclipseStationStateAt(value time.Time, lon, lat, height float64) SolarEclipseStationState
TimeLabelsInUT1(times []time.Time) []time.Time
}
var _ contextAPI = (*Eclipse)(nil)
func TestContextModuleIsolation(t *testing.T) {
previous := basic.GetEphemerisModel()
t.Cleanup(func() { basic.SetEphemerisModel(previous) })
date := time.Date(2024, 4, 8, 0, 0, 0, 0, time.UTC)
for _, model := range []ephem.Model{ephem.Legacy, ephem.Semianalytic} {
basic.SetEphemerisModel(basic.EphemerisModel(model))
want, wantOK := SolarEclipseOnDate(date)
module := NewWithInstance(ephem.NewModelInstance(model))
basic.SetEphemerisModel(basic.EphemerisModel(1 - int(model)))
got, gotOK := module.SolarEclipseOnDate(date)
if !wantOK || gotOK != wantOK || got != want {
t.Fatalf("model %d: solar eclipse escaped instance", model)
}
}
}
// 站心日食、候选枚举与中心食搜索必须使用模块实例,切换全局模型不得改变结果。
func TestContextLocalSolarEclipseIsolation(t *testing.T) {
previous := basic.GetEphemerisModel()
t.Cleanup(func() { basic.SetEphemerisModel(previous) })
date := time.Date(2024, 3, 1, 0, 0, 0, 0, time.UTC)
for _, model := range []ephem.Model{ephem.Legacy, ephem.Semianalytic} {
module := NewWithInstance(ephem.NewModelInstance(model))
run := func() []interface{} {
next := module.NextLocalSolarEclipse(date, -97, 32, 0)
iau := module.NextLocalSolarEclipseIAUSingleK(date, -97, 32, 0)
onDate, ok := module.LocalSolarEclipseOnDate(time.Date(2024, 4, 8, 0, 0, 0, 0, time.UTC), -97, 32, 0)
candidates := module.SolarEclipseCandidates(date, date.AddDate(1, 0, 0), SolarEclipseCandidateOptions{})
central, status := module.SearchLocalCentralSolarEclipse(date, -97, 32, 0, SolarEclipseLocalSearchOptions{MaxYears: 2})
return []interface{}{next, iau, onDate, ok, candidates, central, status}
}
basic.SetEphemerisModel(basic.EphemerisModel(model))
want := run()
basic.SetEphemerisModel(basic.EphemerisModel(1 - int(model)))
got := run()
for i := range want {
if !reflect.DeepEqual(got[i], want[i]) {
t.Fatalf("model %d: result %d escaped instance:\n got %+v\nwant %+v", model, i, got[i], want[i])
}
}
}
}