mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
166b438f83
Aspekty: - engine/aspects.py: aspekty główne (conj/sex/sq/tri/opp) z orbami (bonus dla luminarzy), separacja z obsługą zawinięcia. Applying/sep na później. - build_chart zwraca listę aspektów; /chart/positions je udostępnia; widok Horoskop pokazuje tabelę aspektów. Bogatsze sygnifikatory: - trzecia faseta "w aspekcie": dla każdego aspektu głównego obiektu filtruje rekordy po tokenie aspektu + drugiej planety ([conj + [Mo). Cookbook komplet: znak + dom + aspekt. Dopieszczenie wyników: - ODSIEWANIE DUPLIKATÓW: duplikat = ten sam sygnifikator ORAZ ten sam opis (po normalizacji). Dedup wewnątrz fasety, działa też na wynikach z wielu baz. - _facet_samples przyjmuje wiele tokenów (AND); dedup + istniejące odsiewanie szumu. Zweryfikowano na realnym main_base.xlsx (30.04.1984): 16 aspektów zgodnych z astro.com (Sun conj Moon 9.59°, Sun opp Saturn 3.17°); faseta aspektu daje bogate trafienia (Sun koniunkcja z Moon 84, opozycja z Saturn 43); dedup obniżył duplikaty (Sun w znaku 46->44). 36 testów przechodzi. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
72 lines
3.3 KiB
Python
72 lines
3.3 KiB
Python
"""Testy mostu obliczenia → sygnifikatory → wyszukiwanie (bez efemeryd/HTTP)."""
|
|
from app.engine.models import DEFAULT_OBJECTS
|
|
from app.significators import PLANET_ABBR, _ordinal, build_report
|
|
|
|
|
|
class FakeData:
|
|
def __init__(self, rows_by_value: dict) -> None:
|
|
self.rows_by_value = rows_by_value
|
|
|
|
def search(self, key, value, exact, limit, fields=None) -> dict:
|
|
rows = self.rows_by_value.get(value, [])
|
|
return {"provider": "fake", "total": len(rows), "rows": rows}
|
|
|
|
|
|
def test_sign_and_house_facets():
|
|
positions = [{"name": "Sun", "sign": "Taurus", "direction": "D", "house": 11}]
|
|
data = FakeData({"[Su": [
|
|
{"significator": "[Su in [Tau", "actioneffect": "efekt znak"}, # faseta znak
|
|
{"significator": "[Su in 11th H.", "actioneffect": "efekt dom"}, # faseta dom
|
|
{"significator": "[Su in [Vir", "actioneffect": "inny"}, # żadna
|
|
{"significator": "[Su in [Tau", "actioneffect": "nan"}, # szum
|
|
]})
|
|
item = build_report(positions, data)["objects"][0]
|
|
assert item["object"] == "Sun" and item["house"] == 11
|
|
facets = {f["type"]: f for f in item["facets"]}
|
|
assert facets["sign"]["count"] == 1
|
|
assert facets["sign"]["samples"][0]["effect"] == "efekt znak"
|
|
assert facets["sign"]["samples"][0]["expanded"] == "Sun in Taurus" # rozwinięcie skrótu
|
|
assert facets["house"]["count"] == 1
|
|
assert facets["house"]["token"] == "11th H."
|
|
assert facets["house"]["samples"][0]["effect"] == "efekt dom"
|
|
|
|
|
|
def test_no_house_facet_when_house_missing():
|
|
positions = [{"name": "Mars", "sign": "Scorpio", "direction": "Rx"}]
|
|
data = FakeData({"[Ma": [{"significator": "[Ma in [Sco", "actioneffect": "eff"}]})
|
|
types = [f["type"] for f in build_report(positions, data)["objects"][0]["facets"]]
|
|
assert "sign" in types and "house" not in types
|
|
|
|
|
|
def test_dedup_by_significator_and_effect():
|
|
positions = [{"name": "Moon", "sign": "Taurus", "direction": "D", "house": 11}]
|
|
data = FakeData({"[Mo": [
|
|
{"significator": "[Mo in 11th H.", "actioneffect": "efekt"},
|
|
{"significator": "[Mo in 11th H.", "actioneffect": "efekt"}, # duplikat (sig+opis)
|
|
{"significator": "[Mo in 11th H.", "actioneffect": "inny efekt"}, # ten sam sig, inny opis
|
|
]})
|
|
facets = {f["type"]: f for f in build_report(positions, data)["objects"][0]["facets"]}
|
|
assert facets["house"]["count"] == 2 # duplikat odsiany, różny opis zostaje
|
|
|
|
|
|
def test_aspect_facet():
|
|
positions = [
|
|
{"name": "Sun", "sign": "Taurus", "direction": "D", "house": 11},
|
|
{"name": "Moon", "sign": "Taurus", "direction": "D", "house": 11},
|
|
]
|
|
aspects = [{"obj1": "Sun", "obj2": "Moon", "aspect": "conjunction", "orb": 2.0}]
|
|
data = FakeData({"[Su": [{"significator": "[Su [conj [Mo", "actioneffect": "złączeni"}]})
|
|
sun = build_report(positions, data, aspects=aspects)["objects"][0]
|
|
asp = [f for f in sun["facets"] if f["type"] == "aspect"]
|
|
assert asp and asp[0]["count"] == 1 and "Moon" in asp[0]["label"]
|
|
|
|
|
|
def test_ordinal():
|
|
assert _ordinal(1) == "1st" and _ordinal(2) == "2nd" and _ordinal(3) == "3rd"
|
|
assert _ordinal(4) == "4th" and _ordinal(11) == "11th" and _ordinal(12) == "12th"
|
|
|
|
|
|
def test_planet_abbr_covers_all_default_objects():
|
|
for o in DEFAULT_OBJECTS:
|
|
assert o in PLANET_ABBR
|