An existing product called PG Orbit (a mobile PostgreSQL client) creates a naming conflict. pg_orrery — a database orrery built from Keplerian parameters and SQL instead of brass gears. Build system: control file, Makefile, Dockerfile, docker init script. C source: GUC prefix, PG_FUNCTION_INFO_V1 symbol, header guards, ereport prefixes, comments across ~30 files including vendored SGP4. SQL: all 5 install/migration scripts, function name pg_orrery_ephemeris_info. Tests: 9 SQL suites, 8 expected outputs, standalone DE reader test. Documentation: CLAUDE.md, README.md, DESIGN.md, Starlight site infra, 36 MDX pages, OG renderer, logo SVG, docker-compose, agent threads. All 13 regression suites pass. Docs site builds (37 pages).
129 lines
7.5 KiB
SQL
129 lines
7.5 KiB
SQL
-- de_ephemeris regression tests
|
|
--
|
|
-- Tests the _de() function variants and VSOP87 fallback behavior.
|
|
-- Since DE ephemeris files are not available in CI, these tests
|
|
-- verify that fallback behavior is correct and produces identical
|
|
-- results to the VSOP87 variants.
|
|
|
|
\set boulder '''40.015N 105.270W 1655m'''::observer
|
|
|
|
-- ============================================================
|
|
-- Test 1: pg_orrery_ephemeris_info() returns VSOP87 when no DE file
|
|
-- The provider should be 'VSOP87' since no ephemeris_path is set.
|
|
-- ============================================================
|
|
SELECT 'eph_info_vsop87' AS test,
|
|
(pg_orrery_ephemeris_info()).provider AS provider;
|
|
|
|
-- ============================================================
|
|
-- Test 2: planet_heliocentric_de falls back to VSOP87
|
|
-- Should produce identical results to planet_heliocentric()
|
|
-- when DE is unavailable.
|
|
-- ============================================================
|
|
SELECT 'helio_fallback' AS test,
|
|
round(helio_x(planet_heliocentric(3, '2024-06-21 12:00:00+00'))::numeric, 8) =
|
|
round(helio_x(planet_heliocentric_de(3, '2024-06-21 12:00:00+00'))::numeric, 8) AS x_match,
|
|
round(helio_y(planet_heliocentric(3, '2024-06-21 12:00:00+00'))::numeric, 8) =
|
|
round(helio_y(planet_heliocentric_de(3, '2024-06-21 12:00:00+00'))::numeric, 8) AS y_match,
|
|
round(helio_z(planet_heliocentric(3, '2024-06-21 12:00:00+00'))::numeric, 8) =
|
|
round(helio_z(planet_heliocentric_de(3, '2024-06-21 12:00:00+00'))::numeric, 8) AS z_match;
|
|
|
|
-- ============================================================
|
|
-- Test 3: planet_heliocentric_de Sun at origin
|
|
-- ============================================================
|
|
SELECT 'sun_origin_de' AS test,
|
|
round(helio_x(planet_heliocentric_de(0, '2024-06-21 12:00:00+00'))::numeric, 10) AS x,
|
|
round(helio_y(planet_heliocentric_de(0, '2024-06-21 12:00:00+00'))::numeric, 10) AS y,
|
|
round(helio_z(planet_heliocentric_de(0, '2024-06-21 12:00:00+00'))::numeric, 10) AS z;
|
|
|
|
-- ============================================================
|
|
-- Test 4: planet_observe_de falls back to VSOP87
|
|
-- Elevation and azimuth should match planet_observe().
|
|
-- ============================================================
|
|
SELECT 'observe_fallback' AS test,
|
|
round(topo_azimuth(planet_observe(5, :boulder, '2024-03-15 03:00:00+00'))::numeric, 4) =
|
|
round(topo_azimuth(planet_observe_de(5, :boulder, '2024-03-15 03:00:00+00'))::numeric, 4) AS az_match,
|
|
round(topo_elevation(planet_observe(5, :boulder, '2024-03-15 03:00:00+00'))::numeric, 4) =
|
|
round(topo_elevation(planet_observe_de(5, :boulder, '2024-03-15 03:00:00+00'))::numeric, 4) AS el_match;
|
|
|
|
-- ============================================================
|
|
-- Test 5: sun_observe_de falls back to VSOP87
|
|
-- ============================================================
|
|
SELECT 'sun_fallback' AS test,
|
|
round(topo_azimuth(sun_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 4) =
|
|
round(topo_azimuth(sun_observe_de(:boulder, '2024-06-21 18:00:00+00'))::numeric, 4) AS az_match,
|
|
round(topo_elevation(sun_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 4) =
|
|
round(topo_elevation(sun_observe_de(:boulder, '2024-06-21 18:00:00+00'))::numeric, 4) AS el_match;
|
|
|
|
-- ============================================================
|
|
-- Test 6: moon_observe_de falls back to ELP2000-82B
|
|
-- ============================================================
|
|
SELECT 'moon_fallback' AS test,
|
|
round(topo_azimuth(moon_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 4) =
|
|
round(topo_azimuth(moon_observe_de(:boulder, '2024-06-21 18:00:00+00'))::numeric, 4) AS az_match,
|
|
round(topo_range(moon_observe(:boulder, '2024-06-21 18:00:00+00'))::numeric, 0) =
|
|
round(topo_range(moon_observe_de(:boulder, '2024-06-21 18:00:00+00'))::numeric, 0) AS range_match;
|
|
|
|
-- ============================================================
|
|
-- Test 7: lambert_c3_de falls back to VSOP87
|
|
-- Earth-Mars 2024 window should match lambert_c3().
|
|
-- ============================================================
|
|
SELECT 'lambert_fallback' AS test,
|
|
round(lambert_c3(3, 4, '2024-05-01 00:00:00+00', '2025-02-01 00:00:00+00')::numeric, 2) =
|
|
round(lambert_c3_de(3, 4, '2024-05-01 00:00:00+00', '2025-02-01 00:00:00+00')::numeric, 2) AS c3_match;
|
|
|
|
-- ============================================================
|
|
-- Test 8: lambert_transfer_de falls back to VSOP87
|
|
-- Should produce identical departure C3.
|
|
-- ============================================================
|
|
SELECT 'transfer_fallback' AS test,
|
|
round((lambert_transfer(3, 4, '2024-05-01 00:00:00+00', '2025-02-01 00:00:00+00')).c3_departure::numeric, 2) =
|
|
round((lambert_transfer_de(3, 4, '2024-05-01 00:00:00+00', '2025-02-01 00:00:00+00')).c3_departure::numeric, 2) AS c3_match;
|
|
|
|
-- ============================================================
|
|
-- Test 9: galilean_observe_de falls back to VSOP87
|
|
-- ============================================================
|
|
SELECT 'galilean_fallback' AS test,
|
|
round(topo_elevation(galilean_observe(0, :boulder, '2024-03-15 03:00:00+00'))::numeric, 4) =
|
|
round(topo_elevation(galilean_observe_de(0, :boulder, '2024-03-15 03:00:00+00'))::numeric, 4) AS el_match;
|
|
|
|
-- ============================================================
|
|
-- Test 10: saturn_moon_observe_de falls back to VSOP87
|
|
-- ============================================================
|
|
SELECT 'saturn_moon_fallback' AS test,
|
|
round(topo_elevation(saturn_moon_observe(5, :boulder, '2024-06-15 04:00:00+00'))::numeric, 4) =
|
|
round(topo_elevation(saturn_moon_observe_de(5, :boulder, '2024-06-15 04:00:00+00'))::numeric, 4) AS el_match;
|
|
|
|
-- ============================================================
|
|
-- Test 11: uranus_moon_observe_de falls back to VSOP87
|
|
-- ============================================================
|
|
SELECT 'uranus_moon_fallback' AS test,
|
|
round(topo_elevation(uranus_moon_observe(3, :boulder, '2024-06-15 04:00:00+00'))::numeric, 4) =
|
|
round(topo_elevation(uranus_moon_observe_de(3, :boulder, '2024-06-15 04:00:00+00'))::numeric, 4) AS el_match;
|
|
|
|
-- ============================================================
|
|
-- Test 12: mars_moon_observe_de falls back to VSOP87
|
|
-- ============================================================
|
|
SELECT 'mars_moon_fallback' AS test,
|
|
round(topo_elevation(mars_moon_observe(0, :boulder, '2024-06-15 04:00:00+00'))::numeric, 4) =
|
|
round(topo_elevation(mars_moon_observe_de(0, :boulder, '2024-06-15 04:00:00+00'))::numeric, 4) AS el_match;
|
|
|
|
-- ============================================================
|
|
-- Test 13: All DE planet functions work (fallback mode)
|
|
-- Mercury through Neptune, all should return valid positions
|
|
-- matching their VSOP87 counterparts.
|
|
-- ============================================================
|
|
SELECT 'all_planets_de' AS test,
|
|
body_id,
|
|
round(helio_distance(planet_heliocentric_de(body_id, '2024-06-21 12:00:00+00'))::numeric, 2) AS dist_au
|
|
FROM generate_series(1, 8) AS body_id;
|
|
|
|
-- ============================================================
|
|
-- Test 14: Error handling - invalid body_id
|
|
-- ============================================================
|
|
SELECT 'invalid_body_de' AS test, planet_heliocentric_de(9, now());
|
|
|
|
-- ============================================================
|
|
-- Test 15: Error handling - cannot observe Earth from Earth
|
|
-- ============================================================
|
|
SELECT 'earth_error_de' AS test, planet_observe_de(3, :boulder, now());
|