import json from pathlib import Path import pytest from app.calculator.core import calculate_saju from app.calculator.analysis import perform_full_analysis from app.calculator.fortune_scores import calculate_fortune_scores def _saju_for(year, month, day, hour, gender): saju = calculate_saju(year, month, day, hour, gender) analysis = perform_full_analysis(saju, 2026) return saju, analysis def test_scores_in_valid_range(): saju, analysis = _saju_for(1990, 5, 15, 14, "male") result = calculate_fortune_scores(saju, analysis, 2026) for key in ("wealth", "romance", "social", "career", "overall"): assert key in result, f"missing key: {key}" assert 0 <= result[key] <= 100, f"{key}={result[key]} out of range" def test_overall_weighted_average(): saju, analysis = _saju_for(1990, 5, 15, 14, "male") r = calculate_fortune_scores(saju, analysis, 2026) expected = round( r["wealth"] * 0.3 + r["career"] * 0.3 + r["romance"] * 0.2 + r["social"] * 0.2 ) assert abs(r["overall"] - expected) <= 1, f"overall mismatch: {r['overall']} vs {expected}" def test_clamping_lower_bound(): saju, analysis = _saju_for(2000, 2, 29, 12, "male") r = calculate_fortune_scores(saju, analysis, 2026) assert all(v >= 0 for v in r.values()) def test_clamping_upper_bound(): saju, analysis = _saju_for(1985, 1, 1, 0, "female") r = calculate_fortune_scores(saju, analysis, 2026) assert all(v <= 100 for v in r.values()) def test_different_inputs_different_scores(): s1, a1 = _saju_for(1990, 5, 15, 14, "male") s2, a2 = _saju_for(1985, 1, 1, 0, "female") r1 = calculate_fortune_scores(s1, a1, 2026) r2 = calculate_fortune_scores(s2, a2, 2026) assert r1 != r2, "scores should differ for different sajus" def test_handles_missing_hour(): saju, analysis = _saju_for(1990, 5, 15, None, "male") r = calculate_fortune_scores(saju, analysis, 2026) assert all(0 <= v <= 100 for v in r.values())