import math import pytest from app.tools.financial_calc import compute def test_fv_lump() -> None: out = compute("fv_lump", {"rate": 0.06, "periods": 10, "amount": 1000}) assert math.isclose(out["value"], 1790.847697, rel_tol=1e-6) def test_rate_as_percent_and_years() -> None: out = compute("pv_annuity", {"rate": 6, "years": 2, "periods_per_year": 12, "amount": 1}) assert math.isclose(out["factor"], 22.562866, rel_tol=1e-5) def test_capital_recovery_is_reciprocal_of_pv_annuity() -> None: pv = compute("pv_annuity", {"rate": 0.08, "periods": 25})["factor"] frc = compute("capital_recovery", {"rate": 0.08, "periods": 25})["factor"] assert math.isclose(pv * frc, 1.0, rel_tol=1e-9) def test_sinking_fund_plus_rate_equals_frc() -> None: sf = compute("sinking_fund", {"rate": 0.07, "periods": 15})["factor"] frc = compute("capital_recovery", {"rate": 0.07, "periods": 15})["factor"] assert math.isclose(sf + 0.07, frc, rel_tol=1e-9) def test_age_life() -> None: out = compute("age_life", {"effective_age": 12, "economic_life": 60, "cost_new": 450000}) assert out["depreciation"] == 90000 assert out["remaining_life"] == 48 def test_unit_cost_conversion() -> None: out = compute("unit_cost", {"area": 100, "unit": "m2", "cost_per_unit": 2000, "factors": [1.1]}) assert math.isclose(out["cost_new"], 220000) assert math.isclose(out["area_other_unit"], 1076.39) def test_market_extraction() -> None: out = compute("market_extraction", {"sale_price": 400000, "land_value": 120000, "cost_new": 350000, "age": 20}) assert out["depreciation"] == 70000 assert math.isclose(out["annual_rate"], 0.01) def test_irr_and_npv() -> None: flows = [-1000, 300, 400, 500] irr = compute("irr", {"cash_flows": flows})["value"] npv = compute("npv", {"cash_flows": flows, "rate": irr})["value"] assert abs(npv) < 1e-6 def test_missing_param_raises() -> None: with pytest.raises(KeyError): compute("age_life", {"effective_age": 5})