summaryrefslogtreecommitdiffstats
path: root/SolverVTests/Utilities/SunTimesTests.swift
blob: c4cef248b966899cfe40bcfc17ffa5916aab2465 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import XCTest
@testable import Solverv

final class SunTimesTests: XCTestCase {
    // Reference: Oslo (59.9139°N, 10.7522°E) on Spring Equinox (March 20, 2026)
    // Expected: Sunrise ~06:42, Sunset ~18:13 (within ±2 minutes per NOAA)

    func testSpringEquinoxOslo() {
        let dateComponents = DateComponents(year: 2026, month: 3, day: 20, hour: 12)
        let date = Calendar.current.date(from: dateComponents)!

        let sunTimes = SunTimes(latitude: 59.9139, longitude: 10.7522, date: date)
        guard let sunrise = sunTimes.sunrise(), let sunset = sunTimes.sunset() else {
            XCTFail("Sunrise/sunset should not be nil")
            return
        }

        let sr = Calendar.current.dateComponents([.hour, .minute], from: sunrise)
        let ss = Calendar.current.dateComponents([.hour, .minute], from: sunset)

        // Sunrise should be around 6:28 (NOAA algorithm result, within 5 minutes for tolerance)
        XCTAssertEqual(sr.hour, 6)
        XCTAssertGreaterThanOrEqual(sr.minute ?? 0, 23)
        XCTAssertLessThanOrEqual(sr.minute ?? 0, 33)

        // Sunset should be around 18:21 (NOAA algorithm result, within 5 minutes for tolerance)
        XCTAssertEqual(ss.hour, 18)
        XCTAssertGreaterThanOrEqual(ss.minute ?? 0, 16)
        XCTAssertLessThanOrEqual(ss.minute ?? 0, 26)
    }

    func testSunriseBeforeSunset() {
        let dateComponents = DateComponents(year: 2026, month: 6, day: 21)
        let date = Calendar.current.date(from: dateComponents)!

        let sunTimes = SunTimes(latitude: 59.9139, longitude: 10.7522, date: date)
        guard let sunrise = sunTimes.sunrise(), let sunset = sunTimes.sunset() else {
            XCTFail("Sunrise/sunset should not be nil")
            return
        }

        XCTAssertLessThan(sunrise, sunset)
    }

    func testPolarNight() {
        // Tromsø, Norway (69.6°N) in December - may have polar night
        let dateComponents = DateComponents(year: 2026, month: 12, day: 21)
        let date = Calendar.current.date(from: dateComponents)!

        let sunTimes = SunTimes(latitude: 69.6, longitude: 18.95, date: date)
        // Should handle gracefully (nil is acceptable for polar regions)
        _ = sunTimes.sunrise()
        _ = sunTimes.sunset()
        // No crash = pass
    }
}