From 3f0b4aeeea8d0a92d293aa4dee09e7cce56001e3 Mon Sep 17 00:00:00 2001 From: Matysh Date: Wed, 9 Sep 2026 03:37:17 +0300 Subject: [PATCH] test: cover radar radial calibration guard Issue: #485 User-Visible: no --- test/radar-geometry.test.mjs | 9 +++++++++ tests_backend/test_radar_geometry.py | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/test/radar-geometry.test.mjs b/test/radar-geometry.test.mjs index 0d9e578f..a98a813c 100644 --- a/test/radar-geometry.test.mjs +++ b/test/radar-geometry.test.mjs @@ -58,6 +58,15 @@ test('two-point calibration exposes an ambiguous mirror instead of choosing sile ], 5), /ambiguous_sources/); }); +test('two-point calibration rejects a reference with a hidden radial mismatch', () => { + const mount = [.5, .5]; + const plan = (x, y) => [.5 + x / 1200, .5 - y / 1200]; + assert.throws(() => solveRadarTwoPoint(mount, [[100, 0], [0, 100]], [ + plan(125, 0), plan(0, 100), + ], 5), /invalid_selection/, + 'a 25 cm radial mismatch must fail even though RMS and per-reference error limits pass'); +}); + test('capture median rejects one sample more than 15cm away', () => { assert.deepEqual(radarMedianSample([[100, 200], [102, 198], [101, 201]]), [101, 200]); assert.throws(() => radarMedianSample([[100, 200], [101, 199], [140, 240]]), /bad_fit/); diff --git a/tests_backend/test_radar_geometry.py b/tests_backend/test_radar_geometry.py index 879294ea..d2d61044 100644 --- a/tests_backend/test_radar_geometry.py +++ b/tests_backend/test_radar_geometry.py @@ -105,6 +105,19 @@ def test_two_point_fit_rejects_ambiguous_mirror_candidates(): [plan(0, 80), plan(0, 80)], 5) +def test_two_point_fit_rejects_hidden_radial_mismatch(): + mount = (.5, .5) + + def plan(x, y): + return .5 + x / 1200, .5 - y / 1200 + + # The 25 cm error passes RMS (17.68 cm) and per-reference (30 cm) + # thresholds. The independent radial-consistency guard must reject it. + with pytest.raises(ValueError, match="invalid_selection"): + solve_two_point(mount, [(100, 0), (0, 100)], + [plan(125, 0), plan(0, 100)], 5) + + def test_projection_rejects_nonfinite_and_over_100m(): mount = {"x": .5, "y": .5, "heading_deg": 0} calibration = {"cell_cm": 5, "mirror": False}