"""Gold-case tests for the deterministic engine. Each expected value is computed by hand in the docstring so a reviewer can audit the math without trusting the code. If a tax table changes, these break loudly — exactly what we want for a financial product. Run from the project root: python -m unittest discover -s tests """ import unittest from decimal import Decimal from src.engine import ( break_even_units, cash_runway_months, current_ratio, federal_income_tax, isr_provisional_monthly, iva_monthly, iva_on_amount, profit_margin, quarterly_estimated_tax, resico_eligible, resico_isr_monthly, retenciones_servicios_profesionales, schedule_c_net_profit, self_employment_tax, taxable_base, ) def dec(s): return Decimal(s) class TestResico(unittest.TestCase): def test_first_bracket(self): # $20,000 ≤ $25,000 → 1.00% → $200.00 self.assertEqual(resico_isr_monthly(20000).amount, dec("200.00")) def test_second_bracket(self): # $40,000 ≤ $50,000 → 1.10% → $440.00 self.assertEqual(resico_isr_monthly(40000).amount, dec("440.00")) def test_fourth_bracket(self): # $100,000 ≤ $208,333.33 → 2.00% → $2,000.00 self.assertEqual(resico_isr_monthly(100000).amount, dec("2000.00")) def test_zero_income(self): self.assertEqual(resico_isr_monthly(0).amount, dec("0.00")) def test_eligibility_cap(self): self.assertTrue(resico_eligible(3500000)) self.assertFalse(resico_eligible(3500001)) class TestIsrGeneral(unittest.TestCase): def test_base_20000(self): # Base 20,000 → bracket [15,487.72–31,236.49], cuota 1,640.18, 21.36% # excess = 4,512.28 ; 4,512.28 * 0.2136 = 963.823008 # tax = 1,640.18 + 963.823008 = 2,604.003008 → 2,604.00 self.assertEqual(isr_provisional_monthly(20000).amount, dec("2604.00")) def test_first_bracket(self): # Base 500 → bracket [0.01–746.04], 1.92% → 500 * 0.0192 = 9.60 self.assertEqual(isr_provisional_monthly(500).amount, dec("9.60")) def test_zero_and_negative(self): self.assertEqual(isr_provisional_monthly(0).amount, dec("0.00")) self.assertEqual(isr_provisional_monthly(-100).amount, dec("0.00")) def test_taxable_base_floor(self): self.assertEqual(taxable_base(30000, 12000), dec("18000")) self.assertEqual(taxable_base(10000, 12000), dec("0")) class TestRetenciones(unittest.TestCase): def test_professional_services(self): # $10,000 → ISR 10% = 1,000 ; IVA 10.6667% = 1,066.67 ; total 2,066.67 r = retenciones_servicios_profesionales(10000) self.assertEqual(r.amount, dec("2066.67")) class TestIva(unittest.TestCase): def test_iva_on_amount(self): self.assertEqual(iva_on_amount(1000).amount, dec("160.00")) def test_monthly_payable(self): # 1,600 collected − 600 paid → 1,000 a cargo self.assertEqual(iva_monthly(1600, 600).amount, dec("1000.00")) def test_monthly_credit(self): # 600 collected − 1,000 paid → −400 saldo a favor r = iva_monthly(600, 1000) self.assertEqual(r.amount, dec("-400.00")) self.assertIn("favor", r.label.lower()) def test_withholdings_reduce_payable(self): # 1,600 − 600 − 200 retained → 800 self.assertEqual(iva_monthly(1600, 600, 200).amount, dec("800.00")) class TestRatios(unittest.TestCase): def test_current_ratio(self): self.assertEqual(current_ratio(150000, 100000).amount, dec("1.50")) def test_current_ratio_no_liabilities(self): self.assertEqual(current_ratio(150000, 0).amount, dec("0")) def test_profit_margin(self): self.assertEqual(profit_margin(20000, 100000).amount, dec("0.2000")) def test_break_even(self): # FC 10,000 / (100 − 60) = 250 units self.assertEqual(break_even_units(10000, 100, 60).amount, dec("250.00")) def test_break_even_impossible(self): self.assertEqual(break_even_units(10000, 50, 60).amount, dec("0")) def test_runway(self): # 90,000 cash / 30,000 burn = 3.0 months self.assertEqual(cash_runway_months(90000, 30000).amount, dec("3.0")) class TestUsTax(unittest.TestCase): def test_schedule_c(self): self.assertEqual(schedule_c_net_profit(100000, 40000).amount, dec("60000.00")) def test_self_employment_tax(self): # 60,000 net → 55,410 net earnings # SS 55,410 * 0.124 = 6,870.84 ; Medicare 55,410 * 0.029 = 1,606.89 # total = 8,477.73 self.assertEqual(self_employment_tax(60000).amount, dec("8477.73")) def test_se_tax_below_minimum(self): self.assertEqual(self_employment_tax(400).amount, dec("0.00")) def test_federal_income_tax(self): # 50,000 → bracket [47,150–100,525], fixed 5,426, 22% # excess 2,850 * 0.22 = 627 ; tax = 6,053.00 self.assertEqual(federal_income_tax(50000).amount, dec("6053.00")) def test_quarterly_estimate(self): # (6,053 + 8,477.73) / 4 = 14,530.73 / 4 = 3,632.6825 → 3,632.68 r = quarterly_estimated_tax(dec("6053"), dec("8477.73")) self.assertEqual(r.amount, dec("3632.68")) class TestProvenance(unittest.TestCase): """Every result must carry its source — no number without a basis.""" def test_results_have_breakdown(self): for r in [ resico_isr_monthly(20000), isr_provisional_monthly(20000), iva_monthly(1600, 600), self_employment_tax(60000), ]: self.assertTrue(r.breakdown, f"{r.label} has no breakdown") self.assertIsNotNone(r.source, f"{r.label} has no source") if __name__ == "__main__": unittest.main()