-- planet_observe regression tests -- -- Tests VSOP87 planetary positions, Sun and Moon observation, -- and the planet_heliocentric function. -- Reference values cross-checked against JPL Horizons. \set boulder '''40.015N 105.270W 1655m'''::observer -- ============================================================ -- Test 1: Sun at heliocentric origin -- planet_heliocentric(0, t) should always return (0, 0, 0) -- because the Sun IS the origin of heliocentric coordinates. -- ============================================================ SELECT 'sun_origin' AS test, round(helio_x(planet_heliocentric(0, '2024-06-21 12:00:00+00'))::numeric, 10) AS x, round(helio_y(planet_heliocentric(0, '2024-06-21 12:00:00+00'))::numeric, 10) AS y, round(helio_z(planet_heliocentric(0, '2024-06-21 12:00:00+00'))::numeric, 10) AS z; test | x | y | z ------------+--------------+--------------+-------------- sun_origin | 0.0000000000 | 0.0000000000 | 0.0000000000 (1 row) -- ============================================================ -- Test 2: Earth heliocentric distance ~ 1 AU -- Earth (body_id=3) should be ~0.983-1.017 AU from the Sun -- throughout the year (eccentricity ~0.017). -- ============================================================ SELECT 'earth_distance' AS test, round(helio_distance(planet_heliocentric(3, '2024-01-03 12:00:00+00'))::numeric, 3) AS perihelion, round(helio_distance(planet_heliocentric(3, '2024-07-05 12:00:00+00'))::numeric, 3) AS aphelion; test | perihelion | aphelion ----------------+------------+---------- earth_distance | 0.983 | 1.017 (1 row) -- ============================================================ -- Test 3: Mars heliocentric distance ~ 1.38-1.67 AU -- Mars (body_id=4) average distance is ~1.524 AU. -- ============================================================ SELECT 'mars_distance' AS test, round(helio_distance(planet_heliocentric(4, '2024-06-21 12:00:00+00'))::numeric, 2) AS dist_au; test | dist_au ---------------+--------- mars_distance | 1.40 (1 row) -- ============================================================ -- Test 4: Jupiter heliocentric distance ~ 4.95-5.46 AU -- Jupiter (body_id=5) average distance is ~5.203 AU. -- ============================================================ SELECT 'jupiter_distance' AS test, round(helio_distance(planet_heliocentric(5, '2024-06-21 12:00:00+00'))::numeric, 1) AS dist_au; test | dist_au ------------------+--------- jupiter_distance | 5.0 (1 row) -- ============================================================ -- Test 5: planet_observe for Jupiter from Boulder -- Jupiter should be observable (check we get a valid result, -- not an error). Elevation will vary by time. -- ============================================================ SELECT 'jupiter_observe' AS test, round(topo_azimuth(planet_observe(5, :boulder, '2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg, round(topo_elevation(planet_observe(5, :boulder, '2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg; test | az_deg | el_deg -----------------+--------+-------- jupiter_observe | 270 | 24 (1 row) -- ============================================================ -- Test 6: planet_observe for Venus from Boulder -- Venus (body_id=2) should return valid az/el. -- ============================================================ SELECT 'venus_observe' AS test, round(topo_azimuth(planet_observe(2, :boulder, '2024-06-15 02:00:00+00'))::numeric, 0) AS az_deg, round(topo_elevation(planet_observe(2, :boulder, '2024-06-15 02:00:00+00'))::numeric, 0) AS el_deg; test | az_deg | el_deg ---------------+--------+-------- venus_observe | 295 | 7 (1 row) -- ============================================================ -- Test 7: sun_observe from Boulder at local noon (~18:00 UTC) -- At summer solstice noon in Boulder (MDT = UTC-6), -- Sun should be high in the south (az ~180, el ~73 deg). -- ============================================================ SELECT 'sun_noon' AS test, round(topo_azimuth(sun_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 0) AS az_deg, round(topo_elevation(sun_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 0) AS el_deg; test | az_deg | el_deg ----------+--------+-------- sun_noon | 137 | 69 (1 row) -- ============================================================ -- Test 8: sun_observe range should be ~1 AU = 149,597,871 km -- ============================================================ SELECT 'sun_range' AS test, round(topo_range(sun_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, -4) AS range_km; test | range_km -----------+----------- sun_range | 152030000 (1 row) -- ============================================================ -- Test 9: moon_observe from Boulder -- Should return valid az/el with range ~ 356,000-407,000 km. -- ============================================================ SELECT 'moon_observe' AS test, round(topo_azimuth(moon_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 0) AS az_deg, round(topo_elevation(moon_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 0) AS el_deg, round(topo_range(moon_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, -3) AS range_km; test | az_deg | el_deg | range_km --------------+--------+--------+---------- moon_observe | 317 | -75 | 381000 (1 row) -- ============================================================ -- Test 10: Moon range sanity (should be 356k-407k km) -- ============================================================ SELECT 'moon_range_check' AS test, topo_range(moon_observe(:boulder, '2024-06-21 18:00:00+00')) BETWEEN 350000 AND 410000 AS in_range; test | in_range ------------------+---------- moon_range_check | t (1 row) -- ============================================================ -- Test 11: Error handling - cannot observe Earth from Earth -- ============================================================ SELECT 'earth_error' AS test, planet_observe(3, :boulder, now()); ERROR: cannot observe Earth from Earth -- ============================================================ -- Test 12: Error handling - invalid body_id -- ============================================================ SELECT 'invalid_body' AS test, planet_heliocentric(9, now()); ERROR: invalid body_id 9: must be 0 (Sun) or 1-8 (Mercury-Neptune) -- ============================================================ -- Test 13: All planets return valid heliocentric positions -- Mercury through Neptune, none should error. -- ============================================================ SELECT 'all_planets' AS test, body_id, round(helio_distance(planet_heliocentric(body_id, '2024-06-21 12:00:00+00'))::numeric, 2) AS dist_au FROM generate_series(1, 8) AS body_id; test | body_id | dist_au -------------+---------+--------- all_planets | 1 | 0.33 all_planets | 2 | 0.72 all_planets | 3 | 1.02 all_planets | 4 | 1.40 all_planets | 5 | 5.02 all_planets | 6 | 9.69 all_planets | 7 | 19.59 all_planets | 8 | 29.90 (8 rows)