|
| 1 | +"""Unit tests for the rent/mortgage rescale factor helper in income.py. |
| 2 | +
|
| 3 | +Guards the zero-division bug reported in the bug hunt (finding U3): |
| 4 | +`impute_over_incomes` computed ``new_income_total / original_income_total`` |
| 5 | +with no check for the degenerate case where the seed dataset had zero in |
| 6 | +every imputation column — which is exactly the shape of the |
| 7 | +`zero_weight_copy` branch inside `impute_income`. |
| 8 | +""" |
| 9 | + |
| 10 | +from __future__ import annotations |
| 11 | + |
| 12 | +import math |
| 13 | + |
| 14 | +import pytest |
| 15 | + |
| 16 | + |
| 17 | +def test_safe_rescale_factor_with_zero_original_returns_one(): |
| 18 | + from policyengine_uk_data.datasets.imputations.income import ( |
| 19 | + _safe_rescale_factor, |
| 20 | + ) |
| 21 | + |
| 22 | + # The bug: dividing by zero raised ZeroDivisionError (or produced inf). |
| 23 | + # The fix: leave housing costs untouched when we have no baseline. |
| 24 | + assert _safe_rescale_factor(0, 123_456) == 1.0 |
| 25 | + assert _safe_rescale_factor(0.0, 0.0) == 1.0 |
| 26 | + |
| 27 | + |
| 28 | +def test_safe_rescale_factor_with_nonzero_original_returns_ratio(): |
| 29 | + from policyengine_uk_data.datasets.imputations.income import ( |
| 30 | + _safe_rescale_factor, |
| 31 | + ) |
| 32 | + |
| 33 | + assert _safe_rescale_factor(1_000.0, 2_500.0) == pytest.approx(2.5) |
| 34 | + assert _safe_rescale_factor(42.0, 42.0) == pytest.approx(1.0) |
| 35 | + |
| 36 | + |
| 37 | +def test_safe_rescale_factor_preserves_finiteness(): |
| 38 | + from policyengine_uk_data.datasets.imputations.income import ( |
| 39 | + _safe_rescale_factor, |
| 40 | + ) |
| 41 | + |
| 42 | + # Non-zero inputs must still return finite floats. |
| 43 | + for original, new in [(1e9, 2e9), (1e-6, 1e-9), (100.0, 0.0)]: |
| 44 | + factor = _safe_rescale_factor(original, new) |
| 45 | + assert math.isfinite(factor), (original, new, factor) |
0 commit comments