"""Pure-helper regression tests for the 2026-09-26 offline rectification research. Fictional inputs only. These cover the research helpers, not production code. """ from __future__ import annotations from datetime import date, timedelta from scripts.research.offline_research_20260926_lib import ( NAKSHATRA_SPAN, answerable_indices, exhaustive_flip_sets, flipped_answers, nakshatra_lord, sample_flip_sets, shift_days_per_minute, zip_misaligned, ) from scripts.research.representative_pairs_probe import strict_boundary_windows from scripts.research.varga_sensitivity_rerun import V1N_FACTORS, factor_table MEAN_MOON_DEG_PER_DAY = 13.176 def test_shift_per_minute_is_about_one_year_per_degree_not_122_days() -> None: venus = shift_days_per_minute(NAKSHATRA_SPAN * 1 + 1.0, MEAN_MOON_DEG_PER_DAY) sun = shift_days_per_minute(NAKSHATRA_SPAN * 2 + 1.0, MEAN_MOON_DEG_PER_DAY) assert nakshatra_lord(NAKSHATRA_SPAN * 1 + 1.0) == "Venus" assert nakshatra_lord(NAKSHATRA_SPAN * 2 + 1.0) == "Sun" assert 4.9 < venus < 5.1 assert 1.45 < sun < 1.55 # The 2026-09-14 figure (1.1 days) is below the slowest lord at mean speed. assert sun > 1.1 def test_flip_sets_are_seeded_and_only_touch_answered_questions() -> None: answers = ["yes", None, "no", "yes", None, "no"] assert answerable_indices(answers) == [0, 2, 3, 5] first = sample_flip_sets(answers, 2, 5, case_id="fictional", radius=10) again = sample_flip_sets(answers, 2, 5, case_id="fictional", radius=10) assert first == again assert all(len(item) == 2 and set(item) <= {0, 2, 3, 5} for item in first) assert sample_flip_sets(answers, 5, 3, case_id="fictional", radius=10) == [] assert len(exhaustive_flip_sets(answers, 2)) == 6 assert flipped_answers(answers, (0, 2)) == ["no", None, "yes", "yes", None, "no"] # Unequal spacing, like real dasha periods (equal spacing would make an # off-by-one zip look like a constant shift). OFFSETS = (0, 300, 1000, 1200, 2500, 2600) def test_zip_misalignment_detects_off_by_one_lists() -> None: base = [date(2000, 1, 10) + timedelta(days=days) for days in OFFSETS] shifted = [item + timedelta(days=20) for item in base] assert not zip_misaligned(base, shifted) assert zip_misaligned(base[1:], shifted) def test_strict_gate_drops_year_straddle_and_realigns() -> None: left = [date(1999, 12, 28), date(2003, 5, 1)] right = [date(2000, 1, 4), date(2003, 5, 8)] assert strict_boundary_windows(left, right, min_days=45) == [] base = [date(2000, 3, 1) + timedelta(days=days) for days in OFFSETS] later = [item + timedelta(days=10) for item in base] assert strict_boundary_windows(base, later[1:], min_days=45) == [] far = [item + timedelta(days=60) for item in base] assert len(strict_boundary_windows(base, far, min_days=45)) == 2 * len(OFFSETS) def test_v1_saturates_on_wide_windows_and_v1n_keeps_mean_one() -> None: table = factor_table() assert set(table["30"].values()) == {1.0} assert set(table["60"].values()) == {1.0} assert table["10"]["D2"] < 1.0 assert abs(sum(V1N_FACTORS.values()) / len(V1N_FACTORS) - 1.0) < 1e-4 assert V1N_FACTORS["D30"] > V1N_FACTORS["D2"]