-- v0.11.0 feature tests: make_orbital_elements constructors + moon equatorial -- ============================================================ -- Test 1: make_orbital_elements() — radians input -- Round-trip: construct from radians, read back via accessors -- ============================================================ SELECT 'make_oe_rad' AS test, round(oe_epoch(oe)::numeric, 1) AS epoch, round(oe_perihelion(oe)::numeric, 6) AS q_au, round(oe_eccentricity(oe)::numeric, 6) AS ecc, round(oe_inclination(oe)::numeric, 4) AS inc_deg, round(oe_arg_perihelion(oe)::numeric, 4) AS omega_deg, round(oe_raan(oe)::numeric, 4) AS node_deg, round(oe_h_mag(oe)::numeric, 1) AS h_mag FROM (SELECT make_orbital_elements( 2460400.5, -- epoch JD 0.587100, -- q AU 0.967277, -- e radians(162.2269), -- inc radians(111.8657), -- omega radians(58.1455), -- Omega 2460450.123, -- tp JD 5.5, -- H 4.0 -- G ) AS oe) sub; -- ============================================================ -- Test 2: make_orbital_elements_deg() — degree input -- Same elements but angles in degrees; should produce identical output -- ============================================================ SELECT 'make_oe_deg' AS test, round(oe_epoch(oe)::numeric, 1) AS epoch, round(oe_perihelion(oe)::numeric, 6) AS q_au, round(oe_eccentricity(oe)::numeric, 6) AS ecc, round(oe_inclination(oe)::numeric, 4) AS inc_deg, round(oe_arg_perihelion(oe)::numeric, 4) AS omega_deg, round(oe_raan(oe)::numeric, 4) AS node_deg, round(oe_h_mag(oe)::numeric, 1) AS h_mag FROM (SELECT make_orbital_elements_deg( 2460400.5, -- epoch JD 0.587100, -- q AU 0.967277, -- e 162.2269, -- inc degrees 111.8657, -- omega degrees 58.1455, -- Omega degrees 2460450.123, -- tp JD 5.5, -- H 4.0 -- G ) AS oe) sub; -- ============================================================ -- Test 3: constructors produce identical results to text I/O -- The text format uses degrees, so make_orbital_elements_deg should match -- ============================================================ SELECT 'oe_roundtrip' AS test, make_orbital_elements_deg( 2460400.5, 0.587100, 0.967277, 162.2269, 111.8657, 58.1455, 2460450.123, 5.5, 4.0 )::text = '(2460400.500000,0.5871000000,0.9672770000,162.226900,111.865700,58.145500,2460450.123000,5.50,4.00)'::orbital_elements::text AS matches; -- ============================================================ -- Test 4: make_orbital_elements() validation — negative q -- ============================================================ DO $$ BEGIN PERFORM make_orbital_elements(2460400.5, -0.1, 0.5, 0, 0, 0, 2460400.5, 0, 0); RAISE EXCEPTION 'should have failed'; EXCEPTION WHEN numeric_value_out_of_range THEN RAISE NOTICE 'make_oe_neg_q: correctly rejected'; END; $$; -- ============================================================ -- Test 5: make_orbital_elements() validation — negative eccentricity -- ============================================================ DO $$ BEGIN PERFORM make_orbital_elements(2460400.5, 1.0, -0.1, 0, 0, 0, 2460400.5, 0, 0); RAISE EXCEPTION 'should have failed'; EXCEPTION WHEN numeric_value_out_of_range THEN RAISE NOTICE 'make_oe_neg_e: correctly rejected'; END; $$; -- ============================================================ -- Test 6: make_orbital_elements used in small_body_equatorial() -- Verify the constructor output works in the observation pipeline -- ============================================================ SELECT 'oe_pipeline' AS test, round(eq_ra(eq)::numeric, 2) AS ra_hours, round(eq_dec(eq)::numeric, 2) AS dec_deg, eq_ra(eq) BETWEEN 0 AND 24 AS ra_valid, eq_dec(eq) BETWEEN -90 AND 90 AS dec_valid FROM (SELECT small_body_equatorial( make_orbital_elements_deg( 2460400.5, 0.587100, 0.967277, 162.2269, 111.8657, 58.1455, 2460450.123, 5.5, 4.0 ), '2024-06-15 12:00:00+00'::timestamptz ) AS eq) sub; -- ============================================================ -- Test 7: galilean_equatorial — all 4 moons -- Io, Europa, Ganymede, Callisto should all return valid RA/Dec -- near Jupiter's position -- ============================================================ SELECT 'galilean_eq' AS test, moon_id, round(eq_ra(eq)::numeric, 4) AS ra_hours, round(eq_dec(eq)::numeric, 4) AS dec_deg, eq_ra(eq) BETWEEN 0 AND 24 AS ra_valid, eq_dec(eq) BETWEEN -90 AND 90 AS dec_valid FROM generate_series(0, 3) AS moon_id, LATERAL galilean_equatorial(moon_id, '2024-06-15 12:00:00+00'::timestamptz) AS eq ORDER BY moon_id; -- ============================================================ -- Test 8: galilean moons should be near Jupiter -- All 4 Galilean moons within 0.5 degrees of Jupiter -- ============================================================ SELECT 'galilean_near_jupiter' AS test, moon_id, round((galilean_equatorial(moon_id, '2024-06-15 12:00:00+00') <-> planet_equatorial_apparent(5, '2024-06-15 12:00:00+00'))::numeric, 4) AS sep_deg, (galilean_equatorial(moon_id, '2024-06-15 12:00:00+00') <-> planet_equatorial_apparent(5, '2024-06-15 12:00:00+00')) < 0.5 AS within_half_deg FROM generate_series(0, 3) AS moon_id ORDER BY moon_id; -- ============================================================ -- Test 9: saturn_moon_equatorial — Titan (id=5) -- Should be near Saturn, within ~0.5 degrees -- ============================================================ SELECT 'saturn_titan_eq' AS test, round(eq_ra(eq)::numeric, 4) AS ra_hours, round(eq_dec(eq)::numeric, 4) AS dec_deg, round((eq <-> planet_equatorial_apparent(6, '2024-06-15 12:00:00+00'))::numeric, 4) AS sep_from_saturn, (eq <-> planet_equatorial_apparent(6, '2024-06-15 12:00:00+00')) < 0.5 AS near_saturn FROM saturn_moon_equatorial(5, '2024-06-15 12:00:00+00'::timestamptz) AS eq; -- ============================================================ -- Test 10: uranus_moon_equatorial — Titania (id=3) -- ============================================================ SELECT 'uranus_titania_eq' AS test, round(eq_ra(eq)::numeric, 4) AS ra_hours, round(eq_dec(eq)::numeric, 4) AS dec_deg, eq_ra(eq) BETWEEN 0 AND 24 AS ra_valid, eq_dec(eq) BETWEEN -90 AND 90 AS dec_valid FROM uranus_moon_equatorial(3, '2024-06-15 12:00:00+00'::timestamptz) AS eq; -- ============================================================ -- Test 11: mars_moon_equatorial — Phobos and Deimos -- Both should be near Mars, within ~0.02 degrees (very close moons) -- ============================================================ SELECT 'mars_moons_eq' AS test, moon_id, round(eq_ra(eq)::numeric, 4) AS ra_hours, round(eq_dec(eq)::numeric, 4) AS dec_deg, round((eq <-> planet_equatorial_apparent(4, '2024-06-15 12:00:00+00'))::numeric, 4) AS sep_from_mars FROM generate_series(0, 1) AS moon_id, LATERAL mars_moon_equatorial(moon_id, '2024-06-15 12:00:00+00'::timestamptz) AS eq ORDER BY moon_id; -- ============================================================ -- Test 12: galilean_equatorial error — invalid body_id -- ============================================================ DO $$ BEGIN PERFORM galilean_equatorial(5, '2024-06-15 12:00:00+00'); RAISE EXCEPTION 'should have failed'; EXCEPTION WHEN numeric_value_out_of_range THEN RAISE NOTICE 'galilean_eq_invalid: correctly rejected'; END; $$;