mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
2dbd3410e9
engine/timeline.py: scala w jedną posortowaną oś czasu (technique | significator | start | exact | end): - profekcje roczne (LOG-10) — Władca Roku per rok życia, - Solar Return (LOG-12) — moment powrotu Słońca, - dyrekcje solar-arc — daty dokładnych aspektów kierowanych planet do punktów natalnych (klucz Naiboda 0°59'08"/rok, konfigurowalny; okno orbowe ±1 rok). Endpoint /chart/timeline (zakres from_date..to_date, wybór technik). Walidacja: - profekcje spójne z tabelą notes3; dyrekcja Sun koniunkcja MC (łuk 312°) słusznie poza życiem; oś posortowana po dacie dokładnej; wiek = łuk/klucz spójny z datą. - E2E: dla 2025-2026 zwraca 19 zdarzeń (m.in. Władca Roku 42 Saturn 30.04.2026, Solar Return, dyr. Venus koniunkcja North Node 27.05.2025). 66 testów przechodzi. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
"""Zbiorcza oś czasu z technik (LOG-14)."""
|
|
import datetime as dt
|
|
|
|
from app.engine.timeline import (
|
|
NAIBOD_KEY,
|
|
build_timeline,
|
|
profection_events,
|
|
solar_arc_directions,
|
|
)
|
|
|
|
BIRTH = dt.datetime(1984, 4, 30, 7, 35, tzinfo=dt.timezone.utc)
|
|
# natalne długości (z horoskopu referencyjnego)
|
|
NATAL = {
|
|
"Asc": 112.18, "MC": 352.59, "Sun": 40.14, "Moon": 30.55, "Mercury": 27.38,
|
|
"Venus": 27.68, "Mars": 234.54, "Jupiter": 282.96, "Saturn": 223.31,
|
|
"Uranus": 252.81, "Neptune": 271.22, "Pluto": 210.48,
|
|
}
|
|
|
|
|
|
def _win(y0, y1):
|
|
return (dt.datetime(y0, 1, 1, tzinfo=dt.timezone.utc),
|
|
dt.datetime(y1, 12, 31, tzinfo=dt.timezone.utc))
|
|
|
|
|
|
def test_profection_events_in_window():
|
|
lo, hi = _win(2024, 2026)
|
|
rows = profection_events(NATAL["Asc"], BIRTH, lo, hi)
|
|
# rok profekcyjny wiek 42 zaczyna się 30.04.2026 -> Asc Capricorn
|
|
ages = [r["significator"] for r in rows]
|
|
assert any("Asc Capricorn" in a and "wiek 42" in a for a in ages)
|
|
|
|
|
|
def test_solar_arc_exact_matches_arc_over_key():
|
|
lo, hi = _win(2020, 2030)
|
|
rows = solar_arc_directions(NATAL, BIRTH, lo, hi, key=NAIBOD_KEY)
|
|
assert rows, "brak dyrekcji w oknie"
|
|
# dla każdej dyrekcji: łuk = (wiek * klucz), a data = urodziny + wiek -> spójne
|
|
for r in rows[:5]:
|
|
exact = dt.date.fromisoformat(r["exact"])
|
|
age_years = (dt.datetime(exact.year, exact.month, exact.day, tzinfo=dt.timezone.utc)
|
|
- BIRTH).days / 365.2422
|
|
assert 36 <= age_years <= 47 # okno 2020-2030 = wiek ~36-46
|
|
assert r["technique"] == "solar_arc" and "dyr." in r["significator"]
|
|
|
|
|
|
def test_directed_sun_conjunct_natal_mc_date():
|
|
# Sun natal 40.14 -> MC natal 352.59: łuk koniunkcji = (352.59-40.14)%360 = 312.45
|
|
# to > lifespan przy Naibod (~317 lat) -> NIE powinno być w oknie życia
|
|
lo, hi = _win(1984, 2084)
|
|
rows = solar_arc_directions(NATAL, BIRTH, lo, hi)
|
|
sun_mc = [r for r in rows if r["significator"] == "dyr. Sun koniunkcja MC"]
|
|
assert not sun_mc # łuk 312° = poza życiem
|
|
|
|
|
|
def test_build_timeline_sorted_and_merged():
|
|
events = build_timeline(_FakeEngine(), _FakeNatal(), NATAL,
|
|
"2025-01-01", "2027-01-01",
|
|
techniques=["profection", "solar_arc"])
|
|
assert events
|
|
dates = [e["exact"] for e in events]
|
|
assert dates == sorted(dates) # posortowane po dacie dokładnej
|
|
techs = {e["technique"] for e in events}
|
|
assert "profection" in techs and "solar_arc" in techs
|
|
|
|
|
|
class _FakeNatal:
|
|
when_utc = BIRTH
|
|
|
|
|
|
class _FakeEngine:
|
|
"""Silnik-atrapa — build_timeline z solar_return by go użył, tu go pomijamy."""
|