krz/moonrise

Night-sky companion for iPhone, Apple Watch and Vision Pro: what's up tonight, the Moon, planets, launches and missions, and a Library of the solar system. SwiftUI app with a Cloudflare Workers backend. astronomy cloudflare-workers ios night-sky space swiftui visionos watchos

Packages/MoonriseKit/Tests/SkyEngineTests/EventsTests.swift

6c4b28384d65e09486e0ad62f2ac9d10401cc80c
moonrise/Packages/MoonriseKit/Tests/SkyEngineTests/EventsTests.swift history · blame · raw

46 lines · 2493 bytes

 1import Foundation
 2import Testing
 3@testable import SkyEngine
 4
 5func utc(_ s: String) -> Date { try! Date(s, strategy: .iso8601) }
 6
 7@Test func august2027TotalEclipseIsTotalFromLuxor() throws {
 8    let luxor = Observer(latitude: 25.69, longitude: 32.64)
 9    let events = SkyEngine.events(from: utc("2027-07-01T00:00:00Z"), days: 60, observer: luxor)
10    let eclipse = try #require(events.first { $0.kind == .solarEclipse })
11    #expect(eclipse.title == "Total solar eclipse")
12    #expect(abs(eclipse.date.timeIntervalSince(utc("2027-08-02T10:07:00Z"))) < 3600)
13    #expect(eclipse.visibleHere == true)
14    #expect(eclipse.detail.contains("100%"))
15}
16
17@Test func august2026EclipseIsPartialFromChicagoOrNotVisible() throws {
18    let events = SkyEngine.events(from: utc("2026-08-01T00:00:00Z"), days: 30, observer: chicago)
19    let eclipse = try #require(events.first { $0.kind == .solarEclipse })
20    #expect(eclipse.title == "Total solar eclipse")
21    #expect(abs(eclipse.date.timeIntervalSince(utc("2026-08-12T17:46:00Z"))) < 3600)
22}
23
24@Test func saturnOpposition2026() throws {
25    let events = SkyEngine.events(from: utc("2026-09-01T00:00:00Z"), days: 60, observer: chicago)
26    let opp = try #require(events.first { $0.title == "Saturn at opposition" })
27    #expect(abs(opp.date.timeIntervalSince(utc("2026-10-04T12:00:00Z"))) < 2 * 86_400)
28}
29
30@Test func yearOfEventsIsSortedAndHasEachKind() {
31    let events = SkyEngine.events(from: utc("2026-10-18T00:00:00Z"), observer: chicago)
32    #expect(events == events.sorted { $0.date < $1.date })
33    let kinds = Set(events.map(\.kind))
34    #expect(kinds.isSuperset(of: [.moonPhase, .lunarEclipse, .solarEclipse, .opposition, .elongation, .season, .meteorShower]))
35}
36
37@Test func meteorShowerMoonIsForTheLocalNight() throws {
38    let events = SkyEngine.events(from: utc("2026-08-01T00:00:00Z"), days: 180, observer: chicago)
39    func detail(_ name: String) throws -> String { try #require(events.first { $0.title == "\(name) peak" }).detail }
40    // New moon on 12 August 2026.
41    #expect(try detail("Perseids").hasSuffix("Moon 0% lit, below the horizon during the dark hours."))
42    // 76% at 12:00 UTC on the 21st; 82% at Chicago midnight, setting about 03:00 CDT.
43    #expect(try detail("Orionids").hasSuffix("Moon 82% lit, sets during the dark hours."))
44    // 16% at 12:00 UTC on the 3rd; 11% at Chicago midnight, rising about 05:00 CST before dawn.
45    #expect(try detail("Quadrantids").hasSuffix("Moon 11% lit, rises during the dark hours."))
46}