Complete v6.9.14 precision modules
This commit is contained in:
+2
-2
@@ -272,7 +272,7 @@ def t50():
|
||||
assert '<svg' in svg and '</svg>' in svg
|
||||
|
||||
# ========================================================================
|
||||
# v6.9.6: 扩展测试 — 50→200+ 覆盖核心计算模块
|
||||
# v6.9.14: 扩展测试 — 50→475+ 覆盖核心计算模块
|
||||
# ========================================================================
|
||||
|
||||
# ── Shadbala precision tests ──
|
||||
@@ -684,7 +684,7 @@ def t99():
|
||||
@test("Package version is consistent")
|
||||
def t100():
|
||||
from jyotish_vedic import __version__
|
||||
assert __version__ == '6.9.6'
|
||||
assert __version__ == '6.9.14'
|
||||
|
||||
# ── v6.9.11 Precision gate tests ──
|
||||
@test("Transit uses Swiss Ephemeris")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from ashtakavarga import ALL_SOURCES, BAV_TOTALS, EXPECTED_SAV_TOTAL, SEVEN_PLANETS, SIGNS, calc_ashtakavarga
|
||||
from hypothesis import given
|
||||
from hypothesis import given, settings
|
||||
from hypothesis import strategies as st
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ def planet_signs(draw: st.DrawFn) -> dict[str, dict[str, str]]:
|
||||
return {planet: {"sign": draw(st.sampled_from(SIGNS))} for planet in SEVEN_PLANETS}
|
||||
|
||||
|
||||
@settings(deadline=None)
|
||||
@given(planet_signs(), st.integers(min_value=0, max_value=11))
|
||||
def test_ashtakavarga_totals_are_position_independent(planets: dict[str, dict[str, str]], asc_sign_idx: int) -> None:
|
||||
result = calc_ashtakavarga(planets, asc_sign_idx)
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Tests for bhava_chalit.py — unequal house boundaries and Rashi vs Bhava shifts."""
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
|
||||
SCRIPTS = os.path.join(os.path.dirname(__file__), '..', 'scripts')
|
||||
if SCRIPTS not in sys.path:
|
||||
sys.path.insert(0, SCRIPTS)
|
||||
|
||||
from bhava_chalit import BhavaChalitCalculator
|
||||
|
||||
|
||||
def test_equal_house_cusps_are_30_degrees_apart():
|
||||
calc = BhavaChalitCalculator()
|
||||
cusps = calc.calculate_cusps(asc_lon=12.5, mc_lon=280.0, house_system='equal')
|
||||
assert len(cusps) == 12
|
||||
assert cusps[0] == 12.5
|
||||
assert cusps[1] == 42.5
|
||||
assert cusps[11] == 342.5
|
||||
|
||||
|
||||
def test_whole_sign_cusps_use_sign_midpoints():
|
||||
calc = BhavaChalitCalculator()
|
||||
cusps = calc.calculate_cusps(asc_lon=28.0, mc_lon=270.0, house_system='whole_sign')
|
||||
assert cusps[:3] == [15, 45, 75]
|
||||
|
||||
|
||||
def test_sandhis_for_equal_house_wrap_correctly():
|
||||
calc = BhavaChalitCalculator()
|
||||
cusps = calc.calculate_cusps(asc_lon=15.0, mc_lon=270.0, house_system='equal')
|
||||
sandhis = calc.calculate_sandhis(cusps)
|
||||
assert len(sandhis) == 12
|
||||
assert sandhis[0] == 0.0
|
||||
assert sandhis[1] == 30.0
|
||||
assert sandhis[11] == 330.0
|
||||
|
||||
|
||||
def test_planet_bhava_assignment_equal_house():
|
||||
calc = BhavaChalitCalculator()
|
||||
cusps = calc.calculate_cusps(asc_lon=15.0, mc_lon=270.0, house_system='equal')
|
||||
sandhis = calc.calculate_sandhis(cusps)
|
||||
assert calc._planet_bhava(1.0, sandhis) == 1
|
||||
assert calc._planet_bhava(31.0, sandhis) == 2
|
||||
assert calc._planet_bhava(359.0, sandhis) == 12
|
||||
|
||||
|
||||
def test_bhava_chart_reports_shifted_planets():
|
||||
calc = BhavaChalitCalculator()
|
||||
planet_lons = {'Sun': 29.0, 'Moon': 31.0, 'Mars': 359.0}
|
||||
chart = calc.get_bhava_chalit_chart(
|
||||
planet_lons=planet_lons,
|
||||
asc_lon=15.0,
|
||||
mc_lon=270.0,
|
||||
house_system='equal',
|
||||
)
|
||||
assert chart['summary']['total_planets'] == 3
|
||||
assert chart['planets']['Sun']['rashi_house'] == 1
|
||||
assert chart['planets']['Sun']['bhava_house'] == 1
|
||||
assert chart['planets']['Moon']['bhava_house'] == 2
|
||||
assert chart['planets']['Mars']['bhava_house'] == 12
|
||||
|
||||
|
||||
def test_compare_rashi_vs_bhava_contains_boundaries_and_shifts():
|
||||
calc = BhavaChalitCalculator()
|
||||
result = calc.compare_rashi_vs_bhava(
|
||||
{'Sun': 29.0, 'Moon': 31.0},
|
||||
asc_lon=15.0,
|
||||
mc_lon=270.0,
|
||||
house_system='equal',
|
||||
)
|
||||
assert result['house_system'] == 'equal'
|
||||
assert 'boundaries' in result
|
||||
assert 'rashi_chart' in result
|
||||
assert 'bhava_chart' in result
|
||||
assert isinstance(result['shifts'], list)
|
||||
|
||||
|
||||
def test_porophyry_like_system_returns_12_cusps_and_houses():
|
||||
calc = BhavaChalitCalculator()
|
||||
boundaries = calc.calculate_bhava_boundaries(
|
||||
asc_lon=100.0,
|
||||
mc_lon=20.0,
|
||||
house_system='sripati',
|
||||
)
|
||||
assert len(boundaries['cusps']) == 12
|
||||
assert len(boundaries['sandhis']) == 12
|
||||
assert len(boundaries['houses']) == 12
|
||||
assert all(0 <= h['span_degrees'] <= 360 for h in boundaries['houses'])
|
||||
|
||||
|
||||
def test_invalid_house_system_raises():
|
||||
calc = BhavaChalitCalculator()
|
||||
try:
|
||||
calc.calculate_cusps(asc_lon=0, mc_lon=90, house_system='invalid')
|
||||
except ValueError as exc:
|
||||
assert '不支持的宫位制' in str(exc)
|
||||
else:
|
||||
raise AssertionError('expected ValueError')
|
||||
@@ -35,8 +35,8 @@ class TestFindNakshatra:
|
||||
|
||||
@pytest.mark.parametrize("lon,expected_idx", [
|
||||
(0.0, 0), (6.0, 0), (13.34, 1),
|
||||
(26.67, 1), (26.68, 2),
|
||||
(40.0, 2), (53.34, 3),
|
||||
(26.66, 1), (26.67, 2),
|
||||
(39.99, 2), (40.0, 3), (53.33, 3), (53.34, 4),
|
||||
(180.0, 13), (240.0, 18), (320.0, 24), (346.67, 26),
|
||||
])
|
||||
def test_nakshatra_indices(self, lon, expected_idx):
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Tests for sudarshana_chakra.py — three reference charts and convergence analysis."""
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
|
||||
SCRIPTS = os.path.join(os.path.dirname(__file__), '..', 'scripts')
|
||||
if SCRIPTS not in sys.path:
|
||||
sys.path.insert(0, SCRIPTS)
|
||||
|
||||
from sudarshana_chakra import SudarshanaChakraAnalyzer, calc_sudarshana_chakra, generate_sudarshana_report
|
||||
|
||||
|
||||
def sample_planets():
|
||||
return {
|
||||
'Sun': 65.0, # Gemini
|
||||
'Moon': 125.0, # Leo
|
||||
'Mars': 280.0, # Capricorn
|
||||
'Mercury': 75.0, # Gemini
|
||||
'Jupiter': 100.0, # Cancer
|
||||
'Venus': 340.0, # Pisces
|
||||
'Saturn': 310.0, # Aquarius
|
||||
'Rahu': 210.0, # Scorpio
|
||||
'Ketu': 30.0, # Taurus
|
||||
}
|
||||
|
||||
|
||||
def test_generate_three_charts_has_all_reference_points():
|
||||
analyzer = SudarshanaChakraAnalyzer()
|
||||
charts = analyzer.generate_three_charts(sample_planets(), asc_lon=10.0)
|
||||
assert set(charts) == {'ascendant_lagna', 'moon_lagna', 'sun_lagna'}
|
||||
for chart in charts.values():
|
||||
assert 'Sun' in chart
|
||||
assert 'Moon' in chart
|
||||
assert 1 <= chart['Sun']['house'] <= 12
|
||||
assert 0 <= chart['Sun']['sign_idx'] <= 11
|
||||
|
||||
|
||||
def test_house_from_refs_wraps_one_to_twelve():
|
||||
assert SudarshanaChakraAnalyzer._house_from_refs(0, 0) == 1
|
||||
assert SudarshanaChakraAnalyzer._house_from_refs(1, 0) == 2
|
||||
assert SudarshanaChakraAnalyzer._house_from_refs(11, 0) == 12
|
||||
assert SudarshanaChakraAnalyzer._house_from_refs(0, 11) == 2
|
||||
|
||||
|
||||
def test_composite_analysis_scores_range():
|
||||
analyzer = SudarshanaChakraAnalyzer()
|
||||
result = analyzer.composite_analysis(sample_planets(), asc_lon=10.0)
|
||||
assert set(result).issuperset({'Sun', 'Moon', 'Mars'})
|
||||
for pdata in result.values():
|
||||
assert 0 <= pdata['composite_score'] <= 1
|
||||
assert pdata['favorable_count'] + pdata['unfavorable_count'] == 3
|
||||
assert 'interpretation' in pdata
|
||||
|
||||
|
||||
def test_house_analysis_specific_house():
|
||||
analyzer = SudarshanaChakraAnalyzer()
|
||||
result = analyzer.house_analysis(sample_planets(), asc_lon=10.0, house_number=10)
|
||||
assert result['house'] == 10
|
||||
assert 'asc_lagna' in result
|
||||
assert 'moon_lagna' in result
|
||||
assert 'sun_lagna' in result
|
||||
assert 'interpretation' in result
|
||||
|
||||
|
||||
def test_house_analysis_rejects_invalid_house():
|
||||
analyzer = SudarshanaChakraAnalyzer()
|
||||
result = analyzer.house_analysis(sample_planets(), asc_lon=10.0, house_number=13)
|
||||
assert 'error' in result
|
||||
|
||||
|
||||
def test_life_area_analysis_has_core_areas():
|
||||
analyzer = SudarshanaChakraAnalyzer()
|
||||
result = analyzer.life_area_analysis(sample_planets(), asc_lon=10.0)
|
||||
for key in ('自我/健康', '财富/家庭', '婚姻/伴侣/合作', '事业/地位/名声', '收益/愿望/朋友圈'):
|
||||
assert key in result
|
||||
assert 'composite_strength' in result[key]
|
||||
|
||||
|
||||
def test_full_sudarshana_result_structure():
|
||||
result = calc_sudarshana_chakra(sample_planets(), asc_lon=10.0, house=7)
|
||||
assert result['version'] == '2.0'
|
||||
assert 'reference_points' in result
|
||||
assert 'three_charts' in result
|
||||
assert 'composite_analysis' in result
|
||||
assert 'life_area_analysis' in result
|
||||
assert 'specific_house' in result
|
||||
assert 'convergence' in result
|
||||
assert 'overall_assessment' in result
|
||||
|
||||
|
||||
def test_text_report_contains_title():
|
||||
report = generate_sudarshana_report(sample_planets(), asc_lon=10.0)
|
||||
assert isinstance(report, str)
|
||||
assert 'Sudarshana' in report or '苏达沙那' in report
|
||||
Reference in New Issue
Block a user