From c6877caafd45f40da638b067b886dc98a903a7d6 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Thu, 12 Nov 2026 00:08:10 -0500 Subject: [PATCH 1/3] Fix LIHEAP and Louisiana credits in mixed simulations Co-Authored-By: Claude Opus 5.5 --- ...iheap-la-credit-mixed-simulations.fixed.md | 1 + .../dc/doee/liheap/dc_liheap_payment.yaml | 48 +++++ .../gov/states/il/dceo/liheap/il_liheap.yaml | 38 ++++ .../payment/il_liheap_base_payment.yaml | 63 ++++++ .../la_school_readiness_tax_credit.yaml | 202 ++++++++++++++++++ .../dc/doee/liheap/dc_liheap_payment.py | 2 +- .../liheap/payment/il_liheap_base_payment.py | 2 +- .../la_school_readiness_tax_credit.py | 4 +- 8 files changed, 357 insertions(+), 3 deletions(-) create mode 100644 changelog.d/liheap-la-credit-mixed-simulations.fixed.md create mode 100644 policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/il_liheap.yaml diff --git a/changelog.d/liheap-la-credit-mixed-simulations.fixed.md b/changelog.d/liheap-la-credit-mixed-simulations.fixed.md new file mode 100644 index 00000000000..51cecd04a8b --- /dev/null +++ b/changelog.d/liheap-la-credit-mixed-simulations.fixed.md @@ -0,0 +1 @@ +Fixed DC and Illinois LIHEAP payments and Louisiana's school readiness credit in simulations with multiple states or tax units. diff --git a/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml b/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml index 3eea7f9ce34..eeb59d296a6 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml @@ -337,3 +337,51 @@ # canonical heating_type (gas bill 1_400): min(1_500, 1_400) = 1_400 dc_liheap_heating_type: OIL dc_liheap_payment: 1_400 + +- name: A DC household receives its payment alone. + period: 2026 + input: + state_code: DC + age: 40 + irs_gross_income: 0 + heating_expense_person: 2_000 + output: + # Multi-family electricity, level 1, size 1: min(904, 2_000) = 904. + dc_liheap_income_level: 1 + dc_liheap_payment: 904 + +- name: Two DC households each retain their payment. + period: 2026 + input: + state_code: [DC, DC] + age: [40, 40] + irs_gross_income: [0, 0] + heating_expense_person: [2_000, 2_000] + output: + # Each household receives min(904, 2_000) = 904, as it does alone. + dc_liheap_payment: [904, 904] + +- name: A DC household retains its payment beside households in other states. + period: 2026 + input: + state_code: [DC, NY, IL] + age: [40, 40, 40] + irs_gross_income: [0, 0, 0] + heating_expense_person: [2_000, 2_000, 2_000] + output: + # DC receives min(904, 2_000) = 904; the state mask zeroes NY and IL. + dc_liheap_income_level: [1, 0, 0] + dc_liheap_payment: [904, 0, 0] + +- name: DC bounds matrix keys and preserves both endpoint rows. + period: 2026 + input: + state_code: [DC, DC, DC, DC] + dc_liheap_eligible: [true, true, true, true] + dc_liheap_income_level: [0, 1, 10, 11] + dc_liheap_housing_type: [SINGLE_FAMILY, SINGLE_FAMILY, SINGLE_FAMILY, SINGLE_FAMILY] + heating_expense_person: [2_000, 2_000, 2_000, 2_000] + output: + # Clip levels to [1, 1, 10, 10]; single-family electricity pays + # min(1_265, 2_000) = 1_265 at level 1 and min(200, 2_000) = 200 at 10. + dc_liheap_payment: [1_265, 1_265, 200, 200] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/il_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/il_liheap.yaml new file mode 100644 index 00000000000..48610f18254 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/il_liheap.yaml @@ -0,0 +1,38 @@ +- name: An Illinois LIHEAP recipient qualifies for IHWAP when simulated alone. + period: 2026 + input: + state_code: IL + age: 40 + irs_gross_income: 0 + heating_expense_person: 2_000 + ssi: 0 + receives_ssi: false + il_tanf: 0 + il_aabd: 0 + housing_assistance: 0 + output: + # All-electric, bracket 1, size 1: min(910, 2_000) = 910. + # With no crisis payment, LIHEAP totals 910 and establishes IHWAP + # categorical eligibility; zero income also passes its income test. + il_liheap: 910 + il_ihwap_categorically_eligible: true + il_ihwap_eligible: true + +- name: An Illinois LIHEAP recipient retains payment and IHWAP eligibility beside other states. + period: 2026 + input: + state_code: [IL, NY, DC] + age: [40, 40, 40] + irs_gross_income: [0, 0, 0] + heating_expense_person: [2_000, 2_000, 2_000] + ssi: [0, 0, 0] + receives_ssi: [false, false, false] + il_tanf: [0, 0, 0] + il_aabd: [0, 0, 0] + housing_assistance: [0, 0, 0] + output: + # Illinois retains 910 + 0 = 910 and both eligibility flags. + # Illinois's state masks zero the payment and flags for NY and DC. + il_liheap: [910, 0, 0] + il_ihwap_categorically_eligible: [true, false, false] + il_ihwap_eligible: [true, false, false] diff --git a/policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.yaml b/policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.yaml index 1f071089b80..ebbc3c9d374 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.yaml @@ -488,3 +488,66 @@ # the canonical heating_type (gas bill 2_000): min(840, 2_000) = 840 il_liheap_heating_type: ALL_ELECTRIC il_liheap_base_payment: 840 + +- name: An Illinois household receives its base payment alone. + period: 2026 + input: + state_code: IL + age: 40 + irs_gross_income: 0 + heating_expense_person: 2_000 + output: + # All-electric, bracket 1, size 1: min(910, 2_000) = 910. + il_liheap_income_bracket: 1 + il_liheap_base_payment: 910 + +- name: An Illinois household retains its base payment beside households in other states. + period: 2026 + input: + state_code: [IL, NY, DC] + age: [40, 40, 40] + irs_gross_income: [0, 0, 0] + heating_expense_person: [2_000, 2_000, 2_000] + output: + # Illinois receives min(910, 2_000) = 910; the state mask zeroes NY and DC. + il_liheap_income_bracket: [1, 0, 0] + il_liheap_base_payment: [910, 0, 0] + +- name: An over-income Illinois household retains its base amount alone. + period: 2026 + input: + state_code: IL + age: 40 + irs_gross_income: 100_000 + heating_expense_person: 2_000 + output: + # The base formula has no income eligibility mask: bracket 4, size 1 + # gives min(325, 2_000) = 325, while the total benefit remains zero. + il_liheap_income_bracket: 4 + il_liheap_base_payment: 325 + il_liheap: 0 + +- name: An over-income Illinois household retains its base amount beside a New York household. + period: 2026 + input: + state_code: [IL, NY] + age: [40, 40] + irs_gross_income: [100_000, 0] + heating_expense_person: [2_000, 2_000] + output: + # Illinois retains min(325, 2_000) = 325; NY receives zero. + # Neither household qualifies for the Illinois total benefit. + il_liheap_income_bracket: [4, 0] + il_liheap_base_payment: [325, 0] + il_liheap: [0, 0] + +- name: Illinois bounds matrix keys and preserves both endpoint rows. + period: 2026 + input: + state_code: [IL, IL, IL, IL] + il_liheap_income_bracket: [0, 1, 4, 5] + heating_expense_person: [2_000, 2_000, 2_000, 2_000] + output: + # Clip brackets to [1, 1, 4, 4]; all-electric, size 1 pays + # min(910, 2_000) = 910 at bracket 1 and min(325, 2_000) = 325 at 4. + il_liheap_base_payment: [910, 910, 325, 325] diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml index 55bdd603a94..1d594881180 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml @@ -137,3 +137,205 @@ output: #0 la_school_readiness_credit: 0 + +- name: A Louisiana parent claims the credit for one child attending a five-star facility + period: 2026 + input: + people: + parent: + la_school_readiness_credit_eligible_child: false + child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 5 + tax_units: + family: + members: [parent, child] + la_refundable_cdcc: 50 + la_non_refundable_cdcc: 0 + la_school_readiness_credit_refundable_eligible: true + households: + family_home: + members: [parent, child] + state_code: LA + output: + # The five-star rate gives the parent $50 * 2 = $100. + la_school_readiness_credit: 100 + la_school_readiness_credit_refundable: 100 + la_school_readiness_credit_non_refundable: 0 + +- name: A Louisiana parent claims the credit for one child attending a four-star facility + period: 2026 + input: + people: + parent: + la_school_readiness_credit_eligible_child: false + child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 4 + tax_units: + family: + members: [parent, child] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 80 + la_school_readiness_credit_refundable_eligible: false + households: + family_home: + members: [parent, child] + state_code: LA + output: + # The four-star rate gives the parent $80 * 1.5 = $120. + la_school_readiness_credit: 120 + la_school_readiness_credit_refundable: 0 + la_school_readiness_credit_non_refundable: 120 + +- name: A Louisiana family keeps its credit beside a New York adult + period: 2026 + input: + people: + parent: + la_school_readiness_credit_eligible_child: false + child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 5 + other_adult: + la_school_readiness_credit_eligible_child: false + tax_units: + family: + members: [parent, child] + la_refundable_cdcc: 50 + la_non_refundable_cdcc: 0 + la_school_readiness_credit_refundable_eligible: true + other_tax_unit: + members: [other_adult] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 0 + households: + family_home: + members: [parent, child] + state_code: LA + other_home: + members: [other_adult] + state_code: NY + output: + # The Louisiana parent keeps $50 * 2 = $100; the New York adult gets $0. + la_school_readiness_credit: [100, 0] + la_school_readiness_credit_refundable: [100, 0] + la_school_readiness_credit_non_refundable: [0, 0] + +- name: Two Louisiana families keep their own child care credit and facility rate + period: 2026 + input: + people: + first_parent: + la_school_readiness_credit_eligible_child: false + first_child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 5 + second_parent: + la_school_readiness_credit_eligible_child: false + second_child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 4 + tax_units: + first_family: + members: [first_parent, first_child] + la_refundable_cdcc: 50 + la_non_refundable_cdcc: 0 + la_school_readiness_credit_refundable_eligible: true + second_family: + members: [second_parent, second_child] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 80 + la_school_readiness_credit_refundable_eligible: false + households: + first_home: + members: [first_parent, first_child] + state_code: LA + second_home: + members: [second_parent, second_child] + state_code: LA + output: + # The parents keep $50 * 2 = $100 and $80 * 1.5 = $120, respectively. + la_school_readiness_credit: [100, 120] + la_school_readiness_credit_refundable: [100, 0] + la_school_readiness_credit_non_refundable: [0, 120] + +- name: Two Louisiana families keep their credits beside a New York adult + period: 2026 + input: + people: + first_parent: + la_school_readiness_credit_eligible_child: false + first_child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 5 + other_adult: + la_school_readiness_credit_eligible_child: false + second_parent: + la_school_readiness_credit_eligible_child: false + second_child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 4 + tax_units: + first_family: + members: [first_parent, first_child] + la_refundable_cdcc: 50 + la_non_refundable_cdcc: 0 + la_school_readiness_credit_refundable_eligible: true + other_tax_unit: + members: [other_adult] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 0 + second_family: + members: [second_parent, second_child] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 80 + la_school_readiness_credit_refundable_eligible: false + households: + first_home: + members: [first_parent, first_child] + state_code: LA + other_home: + members: [other_adult] + state_code: NY + second_home: + members: [second_parent, second_child] + state_code: LA + output: + # The parents keep $50 * 2 = $100 and $80 * 1.5 = $120; the adult gets $0. + la_school_readiness_credit: [100, 0, 120] + la_school_readiness_credit_refundable: [100, 0, 0] + la_school_readiness_credit_non_refundable: [0, 0, 120] + +- name: A Louisiana family keeps its credit beside a second tax unit in its household + period: 2026 + input: + people: + parent: + la_school_readiness_credit_eligible_child: false + child: + la_school_readiness_credit_eligible_child: true + la_quality_rating_of_child_care_facility: 5 + other_adult: + la_school_readiness_credit_eligible_child: false + la_quality_rating_of_child_care_facility: 4 + tax_units: + family: + members: [parent, child] + la_refundable_cdcc: 50 + la_non_refundable_cdcc: 0 + la_school_readiness_credit_refundable_eligible: true + other_tax_unit: + members: [other_adult] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 80 + la_school_readiness_credit_refundable_eligible: false + households: + shared_home: + members: [parent, child, other_adult] + state_code: LA + output: + # The parent keeps $50 * 2 = $100; the adult has no eligible child and gets $0. + la_school_readiness_credit: [100, 0] + la_school_readiness_credit_refundable: [100, 0] + la_school_readiness_credit_non_refundable: [0, 0] diff --git a/policyengine_us/variables/gov/states/dc/doee/liheap/dc_liheap_payment.py b/policyengine_us/variables/gov/states/dc/doee/liheap/dc_liheap_payment.py index d032fb8c39f..7464a67ab97 100644 --- a/policyengine_us/variables/gov/states/dc/doee/liheap/dc_liheap_payment.py +++ b/policyengine_us/variables/gov/states/dc/doee/liheap/dc_liheap_payment.py @@ -14,7 +14,7 @@ def formula(spm_unit, period, parameters): p = parameters(period).gov.states.dc.doee.liheap.payment housing_type = spm_unit("dc_liheap_housing_type", period) heating_type = spm_unit("dc_liheap_heating_type", period) - income_level = spm_unit("dc_liheap_income_level", period) + income_level = clip(spm_unit("dc_liheap_income_level", period), 1, 10) capped_size = clip(spm_unit("spm_unit_size", period), 1, 4) types = heating_type.possible_values diff --git a/policyengine_us/variables/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.py b/policyengine_us/variables/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.py index 7373fed85ed..65bc0ad4bcd 100644 --- a/policyengine_us/variables/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.py +++ b/policyengine_us/variables/gov/states/il/dceo/liheap/payment/il_liheap_base_payment.py @@ -13,7 +13,7 @@ class il_liheap_base_payment(Variable): def formula(spm_unit, period, parameters): p = parameters(period).gov.states.il.dceo.liheap.payment.matrix fuel_type = spm_unit("il_liheap_heating_type", period) - income_bracket = spm_unit("il_liheap_income_bracket", period) + income_bracket = clip(spm_unit("il_liheap_income_bracket", period), 1, 4) size = spm_unit("spm_unit_size", period) capped_size = clip(size, 1, 6) diff --git a/policyengine_us/variables/gov/states/la/tax/income/credits/school_readiness/la_school_readiness_tax_credit.py b/policyengine_us/variables/gov/states/la/tax/income/credits/school_readiness/la_school_readiness_tax_credit.py index 96f777b7645..aa0c5744215 100644 --- a/policyengine_us/variables/gov/states/la/tax/income/credits/school_readiness/la_school_readiness_tax_credit.py +++ b/policyengine_us/variables/gov/states/la/tax/income/credits/school_readiness/la_school_readiness_tax_credit.py @@ -19,7 +19,9 @@ def formula(tax_unit, period, parameters): ) eligible_child = person("la_school_readiness_credit_eligible_child", period) quality_rating = person("la_quality_rating_of_child_care_facility", period) - child_credit_percent = child_care_credit * p.rate.calc(quality_rating) + child_credit_percent = tax_unit.project(child_care_credit) * p.rate.calc( + quality_rating + ) # la_cdcc times the percentage amount = eligible_child * child_credit_percent From 7092fda415b852f379eb6a4ad5a9654309547ce7 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Thu, 12 Nov 2026 00:09:09 -0500 Subject: [PATCH 2/3] Test household independence in mixed state simulations Co-Authored-By: Claude Opus 5.5 --- ...test_liheap_la_credit_mixed_simulations.py | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 policyengine_us/tests/core/test_liheap_la_credit_mixed_simulations.py diff --git a/policyengine_us/tests/core/test_liheap_la_credit_mixed_simulations.py b/policyengine_us/tests/core/test_liheap_la_credit_mixed_simulations.py new file mode 100644 index 00000000000..879e9903bab --- /dev/null +++ b/policyengine_us/tests/core/test_liheap_la_credit_mixed_simulations.py @@ -0,0 +1,107 @@ +"""Check population independence through Core's masks and entity projectors. + +YAML covers payment amounts. Hypothesis varies states, household membership, +tax units, income, bills and child care ratings, then compares each household +with its results in isolation. Fresh simulations share the default US system; +they keep their own inputs and calculation caches. This file runs in the +existing rest-python core group. +""" + +import numpy as np +from hypothesis import example, given, settings, strategies as st + +from policyengine_us import Simulation +from policyengine_us.variables.household.demographic.geographic.state_code import ( + StateCode, +) + +YEAR = 2026 +STATES = tuple(state.name for state in StateCode)[:51] +OUTPUTS = ( + "dc_liheap_payment", + "il_liheap_base_payment", + "il_liheap", + "il_ihwap_categorically_eligible", + "il_ihwap_eligible", + "la_school_readiness_credit", + "la_school_readiness_credit_non_refundable", + "la_school_readiness_credit_refundable", +) + + +@st.composite +def households(draw): + return ( + draw(st.sampled_from(STATES)), + draw( + st.lists( + st.tuples( + st.integers(0, 2), # children per tax unit + st.integers(0, 100_000), # adult earnings + st.integers(0, 5_000), # heating bill + st.integers(0, 500), # child care credit + st.integers(1, 5), # facility rating + ), + min_size=1, + max_size=2, + ) + ), + ) + + +def _calculate(households): + situation = { + group: {} + for group in ( + "people", + "marital_units", + "tax_units", + "families", + "spm_units", + "households", + ) + } + for i, (state, tax_units) in enumerate(households): + household_members = [] + for j, (children, earnings, bill, credit, rating) in enumerate(tax_units): + adult = f"adult_{i}_{j}" + members = [adult] + [f"child_{i}_{j}_{k}" for k in range(children)] + household_members.extend(members) + for member in members: + situation["people"][member] = { + "age": {YEAR: 40 if member == adult else 3}, + "employment_income": {YEAR: earnings if member == adult else 0}, + "heating_expense_person": {YEAR: bill if member == adult else 0}, + "la_quality_rating_of_child_care_facility": {YEAR: rating}, + } + situation["marital_units"][member] = {"members": [member]} + situation["tax_units"][f"tax_unit_{i}_{j}"] = { + "members": members, + "la_refundable_cdcc": {YEAR: credit}, + "la_non_refundable_cdcc": {YEAR: 0}, + } + for group in ("families", "spm_units", "households"): + situation[group][f"{group}_{i}"] = {"members": household_members} + situation["households"][f"households_{i}"]["state_code"] = {YEAR: state} + simulation = Simulation(situation=situation) + return {name: simulation.calculate(name, YEAR).copy() for name in OUTPUTS} + + +@settings(max_examples=8, deadline=None, derandomize=True, database=None) +@example(population=[(state, [(1, 0, 2_000, 50, 5)]) for state in STATES]) +@example( + population=[ + ("DC", [(0, 0, 2_000, 0, 1)]), + ("IL", [(0, 0, 2_000, 0, 1)]), + ("LA", [(1, 0, 0, 50, 5), (0, 40_000, 0, 120, 4)]), + ("LA", [(2, 30_000, 0, 75, 3)]), + ("NY", [(0, 0, 0, 0, 1)]), + ] +) +@given(population=st.lists(households(), min_size=1, max_size=5)) +def test_households_keep_their_results_in_any_state_mix(population): + combined = _calculate(population) + isolated = [_calculate([household]) for household in population] + for name in OUTPUTS: + expected = np.concatenate([result[name] for result in isolated]) + np.testing.assert_array_equal(combined[name], expected, err_msg=name) From 1ea29b9b0a1e52214fa57b934722098daf88ea7b Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Thu, 12 Nov 2026 00:50:47 -0500 Subject: [PATCH 3/3] Cover zero payments in mixed state simulations Co-Authored-By: Claude Opus 5.5 --- .../dc/doee/liheap/dc_liheap_payment.yaml | 26 ++++++++ .../la_school_readiness_tax_credit.yaml | 60 +++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml b/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml index eeb59d296a6..281edd93865 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/dc/doee/liheap/dc_liheap_payment.yaml @@ -385,3 +385,29 @@ # Clip levels to [1, 1, 10, 10]; single-family electricity pays # min(1_265, 2_000) = 1_265 at level 1 and min(200, 2_000) = 200 at 10. dc_liheap_payment: [1_265, 1_265, 200, 200] + +- name: An over-income DC household receives no payment alone. + period: 2026 + input: + state_code: DC + age: 40 + irs_gross_income: 100_000 + heating_expense_person: 2_000 + output: + # The eligibility mask zeroes the payment despite the level 10 matrix row. + dc_liheap_income_level: 10 + dc_liheap_eligible: false + dc_liheap_payment: 0 + +- name: An over-income DC household receives no payment beside a New York household. + period: 2026 + input: + state_code: [DC, NY] + age: [40, 40] + irs_gross_income: [100_000, 0] + heating_expense_person: [2_000, 2_000] + output: + # Neither household qualifies for DC LIHEAP, so both payments remain zero. + dc_liheap_income_level: [10, 0] + dc_liheap_eligible: [false, false] + dc_liheap_payment: [0, 0] diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml index 1d594881180..46a9b1ec928 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/la/tax/income/credits/child_care_expense_credit/la_school_readiness_tax_credit.yaml @@ -339,3 +339,63 @@ la_school_readiness_credit: [100, 0] la_school_readiness_credit_refundable: [100, 0] la_school_readiness_credit_non_refundable: [0, 0] + +- name: A Louisiana adult without an eligible child gets no credit alone + period: 2026 + input: + state_code: LA + age: 40 + la_quality_rating_of_child_care_facility: 5 + la_refundable_cdcc: 50 + la_non_refundable_cdcc: 0 + la_school_readiness_credit_refundable_eligible: true + output: + # With no eligible child, $50 * 2 * 0 = $0. + la_school_readiness_credit: 0 + la_school_readiness_credit_refundable: 0 + la_school_readiness_credit_non_refundable: 0 + +- name: Two Louisiana adults without eligible children keep zero credits beside a New York adult + period: 2026 + input: + people: + first_adult: + age: 40 + la_quality_rating_of_child_care_facility: 5 + second_adult: + age: 40 + la_quality_rating_of_child_care_facility: 4 + other_adult: + age: 40 + la_quality_rating_of_child_care_facility: 3 + tax_units: + first_tax_unit: + members: [first_adult] + la_refundable_cdcc: 50 + la_non_refundable_cdcc: 0 + la_school_readiness_credit_refundable_eligible: true + second_tax_unit: + members: [second_adult] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 80 + la_school_readiness_credit_refundable_eligible: false + other_tax_unit: + members: [other_adult] + la_refundable_cdcc: 0 + la_non_refundable_cdcc: 120 + la_school_readiness_credit_refundable_eligible: false + households: + first_home: + members: [first_adult] + state_code: LA + second_home: + members: [second_adult] + state_code: LA + other_home: + members: [other_adult] + state_code: NY + output: + # Without eligible children, $50 * 2 * 0 and $80 * 1.5 * 0 both give $0. + la_school_readiness_credit: [0, 0, 0] + la_school_readiness_credit_refundable: [0, 0, 0] + la_school_readiness_credit_non_refundable: [0, 0, 0]