Python 64.6%
TypeScript 33.7%
CSS 0.8%
1import math23import pytest45from app.tools.financial_calc import compute678def test_fv_lump() -> None:9 out = compute("fv_lump", {"rate": 0.06, "periods": 10, "amount": 1000})10 assert math.isclose(out["value"], 1790.847697, rel_tol=1e-6)111213def test_rate_as_percent_and_years() -> None:14 out = compute("pv_annuity", {"rate": 6, "years": 2, "periods_per_year": 12, "amount": 1})15 assert math.isclose(out["factor"], 22.562866, rel_tol=1e-5)161718def test_capital_recovery_is_reciprocal_of_pv_annuity() -> None:19 pv = compute("pv_annuity", {"rate": 0.08, "periods": 25})["factor"]20 frc = compute("capital_recovery", {"rate": 0.08, "periods": 25})["factor"]21 assert math.isclose(pv * frc, 1.0, rel_tol=1e-9)222324def test_sinking_fund_plus_rate_equals_frc() -> None:25 sf = compute("sinking_fund", {"rate": 0.07, "periods": 15})["factor"]26 frc = compute("capital_recovery", {"rate": 0.07, "periods": 15})["factor"]27 assert math.isclose(sf + 0.07, frc, rel_tol=1e-9)282930def test_age_life() -> None:31 out = compute("age_life", {"effective_age": 12, "economic_life": 60, "cost_new": 450000})32 assert out["depreciation"] == 9000033 assert out["remaining_life"] == 48343536def test_unit_cost_conversion() -> None:37 out = compute("unit_cost", {"area": 100, "unit": "m2", "cost_per_unit": 2000, "factors": [1.1]})38 assert math.isclose(out["cost_new"], 220000)39 assert math.isclose(out["area_other_unit"], 1076.39)404142def test_market_extraction() -> None:43 out = compute("market_extraction", {"sale_price": 400000, "land_value": 120000,44 "cost_new": 350000, "age": 20})45 assert out["depreciation"] == 7000046 assert math.isclose(out["annual_rate"], 0.01)474849def test_irr_and_npv() -> None:50 flows = [-1000, 300, 400, 500]51 irr = compute("irr", {"cash_flows": flows})["value"]52 npv = compute("npv", {"cash_flows": flows, "rate": irr})["value"]53 assert abs(npv) < 1e-6545556def test_missing_param_raises() -> None:57 with pytest.raises(KeyError):58 compute("age_life", {"effective_age": 5})59