113 lines
4.1 KiB
Go
113 lines
4.1 KiB
Go
|
|
package basic
|
||
|
|
|
||
|
|
import (
|
||
|
|
"math"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestPlanetOccultationDiagramSaturnIncludesFiveDynamicDiskStages(t *testing.T) {
|
||
|
|
location := time.FixedZone("UTC+8", 8*3600)
|
||
|
|
start := time.Date(2025, time.February, 1, 0, 0, 0, 0, location)
|
||
|
|
end := start.Add(24 * time.Hour)
|
||
|
|
events, err := FindPlanetOccultations(
|
||
|
|
start, end, OccultationSaturn, 104.52219613, 55.25401991, 0, OccultationSearchOptions{},
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("FindPlanetOccultations() error = %v", err)
|
||
|
|
}
|
||
|
|
if len(events) != 1 {
|
||
|
|
t.Fatalf("FindPlanetOccultations() returned %d events, want 1", len(events))
|
||
|
|
}
|
||
|
|
diagram := PlanetOccultationDiagram(events[0], PlanetOccultationDiagramOptions{})
|
||
|
|
if len(diagram.Frames) < 5 {
|
||
|
|
t.Fatalf("PlanetOccultationDiagram() returned %d frames, want at least 5", len(diagram.Frames))
|
||
|
|
}
|
||
|
|
|
||
|
|
frames := make(map[string]PlanetOccultationDiagramFrame)
|
||
|
|
for _, frame := range diagram.Frames {
|
||
|
|
for _, label := range frame.Labels {
|
||
|
|
frames[label] = frame
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, label := range []string{"C1", "C2", "Greatest", "C3", "C4"} {
|
||
|
|
if _, ok := frames[label]; !ok {
|
||
|
|
t.Fatalf("diagram is missing %s", label)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, label := range []string{"C1", "C4"} {
|
||
|
|
frame := frames[label]
|
||
|
|
residual := frame.SeparationArcsec - frame.MoonRadiusArcsec - frame.PlanetRadiusArcsec
|
||
|
|
if math.Abs(residual) > 0.1 {
|
||
|
|
t.Errorf("%s outer-contact residual = %.6f arcsec", label, residual)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, label := range []string{"C2", "C3"} {
|
||
|
|
frame := frames[label]
|
||
|
|
residual := frame.SeparationArcsec - frame.MoonRadiusArcsec + frame.PlanetRadiusArcsec
|
||
|
|
if math.Abs(residual) > 0.1 {
|
||
|
|
t.Errorf("%s inner-contact residual = %.6f arcsec", label, residual)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if !frames["Greatest"].FullyOcculted {
|
||
|
|
t.Fatal("greatest frame does not report a fully occulted Saturn disk")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPlanetOccultationDiagramRejectsIncompleteEvent(t *testing.T) {
|
||
|
|
result := PlanetOccultationDiagram(PlanetOccultationInfo{Planet: OccultationSaturn}, PlanetOccultationDiagramOptions{})
|
||
|
|
if len(result.Frames) != 0 {
|
||
|
|
t.Fatalf("invalid event returned %d frames, want none", len(result.Frames))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPlanetOccultationDiagramRejectsTargetGeometryMismatch(t *testing.T) {
|
||
|
|
location := time.FixedZone("UTC+8", 8*3600)
|
||
|
|
events, err := FindPlanetOccultations(
|
||
|
|
time.Date(2025, time.February, 1, 0, 0, 0, 0, location),
|
||
|
|
time.Date(2025, time.February, 2, 0, 0, 0, 0, location),
|
||
|
|
OccultationSaturn, 104.52219613, 55.25401991, 0, OccultationSearchOptions{},
|
||
|
|
)
|
||
|
|
if err != nil || len(events) != 1 {
|
||
|
|
t.Fatalf("FindPlanetOccultations() = %d events, %v; want one", len(events), err)
|
||
|
|
}
|
||
|
|
// TargetID 只是显示元数据,但改变建模行星必须 / TargetID is display metadata, but changing the modeled planet must
|
||
|
|
// 使事件几何失效,而不是静默绘制另一个天体 / invalidate the event geometry rather than silently drawing another body.
|
||
|
|
event := events[0]
|
||
|
|
event.Planet = OccultationVenus
|
||
|
|
event.TargetID = "Venus"
|
||
|
|
result := PlanetOccultationDiagram(event, PlanetOccultationDiagramOptions{})
|
||
|
|
if len(result.Frames) != 0 {
|
||
|
|
t.Fatalf("diagram accepted mismatched planet and returned %d frames", len(result.Frames))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPlanetOccultationDiagramPartialEventHasOnlyExternalStages(t *testing.T) {
|
||
|
|
start := time.Date(2024, time.August, 21, 1, 30, 0, 0, time.UTC)
|
||
|
|
end := time.Date(2024, time.August, 21, 4, 0, 0, 0, time.UTC)
|
||
|
|
events, err := FindPlanetOccultations(
|
||
|
|
start, end, OccultationSaturn, -30.072, -6.5, 0, OccultationSearchOptions{},
|
||
|
|
)
|
||
|
|
if err != nil || len(events) != 1 {
|
||
|
|
t.Fatalf("FindPlanetOccultations() = %d events, %v; want one", len(events), err)
|
||
|
|
}
|
||
|
|
if events[0].Type != OccultationPartial {
|
||
|
|
t.Fatalf("event type = %q, want partial", events[0].Type)
|
||
|
|
}
|
||
|
|
diagram := PlanetOccultationDiagram(events[0], PlanetOccultationDiagramOptions{})
|
||
|
|
labels := make(map[string]bool)
|
||
|
|
for _, frame := range diagram.Frames {
|
||
|
|
for _, label := range frame.Labels {
|
||
|
|
labels[label] = true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, label := range []string{"C1", "Greatest", "C4"} {
|
||
|
|
if !labels[label] {
|
||
|
|
t.Fatalf("partial diagram is missing %s", label)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if labels["C2"] || labels["C3"] {
|
||
|
|
t.Fatalf("partial diagram contains internal contacts: %+v", labels)
|
||
|
|
}
|
||
|
|
}
|