From 9e3c1fdcc48645a6a0694fb41ad8e70e52b60ae5 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:13:59 +0200 Subject: [PATCH 01/22] Extract tax-benefit system to fixture in test countries --- conftest.py | 4 + setup.py | 2 - tests/__init__.py | 0 tests/core/test_countries.py | 178 +++++++++++++++------------- tests/fixtures/__init__.py | 0 tests/fixtures/simulations.py | 8 ++ tests/fixtures/taxbenefitsystems.py | 13 ++ 7 files changed, 118 insertions(+), 87 deletions(-) create mode 100644 conftest.py create mode 100644 tests/__init__.py create mode 100644 tests/fixtures/__init__.py create mode 100644 tests/fixtures/simulations.py create mode 100644 tests/fixtures/taxbenefitsystems.py diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000000..6144b5a847 --- /dev/null +++ b/conftest.py @@ -0,0 +1,4 @@ +pytest_plugins = [ + "tests.fixtures.simulations", + "tests.fixtures.taxbenefitsystems", + ] diff --git a/setup.py b/setup.py index fb8ccf5622..170aefe700 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,4 @@ #! /usr/bin/env python -# -*- coding: utf-8 -*- - from setuptools import setup, find_packages diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/core/test_countries.py b/tests/core/test_countries.py index e7e8ec0ee1..1b143b178a 100644 --- a/tests/core/test_countries.py +++ b/tests/core/test_countries.py @@ -1,137 +1,145 @@ -# -*- coding: utf-8 -*- - -from pytest import fixture, raises +import pytest +from openfisca_core import periods, populations, tools +from openfisca_core.errors import VariableNameConflictError, VariableNotFoundError from openfisca_core.variables import Variable -from openfisca_core.periods import MONTH -from openfisca_core.simulation_builder import SimulationBuilder -from openfisca_core.taxbenefitsystems import VariableNameConflict, VariableNotFound -from openfisca_core import periods -from openfisca_core.populations import DIVIDE -from openfisca_country_template import CountryTaxBenefitSystem -from openfisca_core.tools import assert_near + +PERIOD = periods.period("2016-01") -tax_benefit_system = CountryTaxBenefitSystem() +@pytest.fixture +def simulation(simulation_builder, tax_benefit_system, request): + variables, period = request.param + simulation_builder.set_default_period(period) + simulation = \ + simulation_builder \ + .build_from_variables(tax_benefit_system, variables) + return simulation -@fixture -def period(): - return "2016-01" +@pytest.mark.parametrize("simulation", [({"salary": 2000}, PERIOD)], indirect = True) +def test_input_variable(simulation): + result = simulation.calculate("salary", PERIOD) + tools.assert_near(result, [2000], absolute_error_margin = 0.01) -@fixture -def make_simulation(period): - def _make_simulation(data): - builder = SimulationBuilder() - builder.default_period = period - return builder.build_from_variables(tax_benefit_system, data) - return _make_simulation +@pytest.mark.parametrize("simulation", [({"salary": 2000}, PERIOD)], indirect = True) +def test_basic_calculation(simulation): + result = simulation.calculate("income_tax", PERIOD) + tools.assert_near(result, [300], absolute_error_margin = 0.01) -@fixture -def make_isolated_simulation(period): - def _make_simulation(tbs, data): - builder = SimulationBuilder() - builder.default_period = period - return builder.build_from_variables(tbs, data) - return _make_simulation +@pytest.mark.parametrize("simulation", [({"salary": 24000}, PERIOD)], indirect = True) +def test_calculate_add(simulation): + result = simulation.calculate_add("income_tax", PERIOD) + tools.assert_near(result, [3600], absolute_error_margin = 0.01) -def test_input_variable(make_simulation, period): - simulation = make_simulation({'salary': 2000}) - assert_near(simulation.calculate('salary', period), [2000], absolute_error_margin = 0.01) +@pytest.mark.parametrize( + "simulation", + [({"accommodation_size": 100, "housing_occupancy_status": "tenant"}, PERIOD)], + indirect = True, + ) +def test_calculate_divide(simulation): + result = simulation.calculate_divide("housing_tax", PERIOD) + tools.assert_near(result, [1000 / 12.], absolute_error_margin = 0.01) -def test_basic_calculation(make_simulation, period): - simulation = make_simulation({'salary': 2000}) - assert_near(simulation.calculate('income_tax', period), [300], absolute_error_margin = 0.01) +@pytest.mark.parametrize("simulation", [({"salary": 20000}, PERIOD)], indirect = True) +def test_bareme(simulation): + result = simulation.calculate("social_security_contribution", PERIOD) + expected = [0.02 * 6000 + 0.06 * 6400 + 0.12 * 7600] + tools.assert_near(result, expected, absolute_error_margin = 0.01) -def test_calculate_add(make_simulation, period): - simulation = make_simulation({'salary': 24000}) - assert_near(simulation.calculate_add('income_tax', period), [3600], absolute_error_margin = 0.01) +@pytest.mark.parametrize("simulation", [({}, PERIOD)], indirect = True) +def test_non_existing_variable(simulation): + with pytest.raises(VariableNotFoundError): + simulation.calculate("non_existent_variable", PERIOD) -def test_calculate_divide(make_simulation, period): - simulation = make_simulation({ - 'accommodation_size': 100, - 'housing_occupancy_status': 'tenant', - }) - assert_near(simulation.calculate_divide('housing_tax', period), [1000 / 12.], absolute_error_margin = 0.01) +@pytest.mark.parametrize("simulation", [({}, PERIOD)], indirect = True) +def test_calculate_variable_with_wrong_definition_period(simulation): + year = str(PERIOD.this_year) -def test_bareme(make_simulation, period): - simulation = make_simulation({'salary': 20000}) - expected_result = 0.02 * 6000 + 0.06 * 6400 + 0.12 * 7600 - assert_near(simulation.calculate('social_security_contribution', period), [expected_result], absolute_error_margin = 0.01) + with pytest.raises(ValueError) as error: + simulation.calculate("basic_income", year) + error_message = str(error.value) + expected_words = ["period", year, "month", "basic_income", "ADD"] -def test_non_existing_variable(make_simulation): - simulation = make_simulation({}) - with raises(VariableNotFound): - simulation.calculate('non_existent_variable', 2013) + for word in expected_words: + assert word in error_message, f"Expected '{word}' in error message '{error_message}'" -def test_calculate_variable_with_wrong_definition_period(make_simulation): - simulation = make_simulation({}) +@pytest.mark.parametrize("simulation", [({}, PERIOD)], indirect = True) +def test_divide_option_on_month_defined_variable(simulation): + with pytest.raises(ValueError): + simulation.person("disposable_income", PERIOD, options = [populations.DIVIDE]) - with raises(ValueError) as error: - simulation.calculate('basic_income', 2016) - error_message = str(error.value) - expected_words = ['period', '2016', 'month', 'basic_income', 'ADD'] +@pytest.mark.parametrize("simulation", [({}, PERIOD)], indirect = True) +def test_divide_option_with_complex_period(simulation): + quarter = PERIOD.last_3_months - for word in expected_words: - assert word in error_message, 'Expected "{}" in error message "{}"'.format(word, error_message) + with pytest.raises(ValueError) as error: + simulation.household("housing_tax", quarter, options = [populations.DIVIDE]) + error_message = str(error.value) + expected_words = ["DIVIDE", "one-year", "one-month", "period"] -def test_divide_option_on_month_defined_variable(make_simulation): - simulation = make_simulation({}) - with raises(ValueError): - simulation.person('disposable_income', "2016-01", options = [DIVIDE]) + for word in expected_words: + assert word in error_message, f"Expected '{word}' in error message '{error_message}'" -def test_divide_option_with_complex_period(make_simulation): - simulation = make_simulation({}) - quarter = periods.period('2013-12').last_3_months - with raises(ValueError): - simulation.household('housing_tax', quarter, options = [DIVIDE]) +def test_input_with_wrong_period(simulation_builder, tax_benefit_system): + year = str(PERIOD.this_year) + variables = {"basic_income": {year: 12000}} + simulation_builder.set_default_period(PERIOD) + with pytest.raises(ValueError): + simulation_builder.build_from_variables(tax_benefit_system, variables) -def test_input_with_wrong_period(make_simulation): - with raises(ValueError): - make_simulation({'basic_income': {2015: 12000}}) +def test_variable_with_reference(simulation_builder, isolated_tax_benefit_system): + variables = {"salary": 4000} + simulation_builder.set_default_period(PERIOD) -def test_variable_with_reference(make_isolated_simulation): - tax_benefit_system = CountryTaxBenefitSystem() # Work in isolation + simulation = \ + simulation_builder \ + .build_from_variables(isolated_tax_benefit_system, variables) - simulation_base = make_isolated_simulation(tax_benefit_system, {'salary': 4000}) + disposable_income = simulation.calculate("disposable_income", PERIOD) - revenu_disponible_avant_reforme = simulation_base.calculate('disposable_income', "2016-01") - assert(revenu_disponible_avant_reforme > 0) + assert disposable_income > 0 class disposable_income(Variable): - definition_period = MONTH + + definition_period = periods.MONTH def formula(household, period): return household.empty_array() - tax_benefit_system.update_variable(disposable_income) + isolated_tax_benefit_system.update_variable(disposable_income) - simulation_reform = make_isolated_simulation(tax_benefit_system, {'salary': 4000}) - revenu_disponible_apres_reforme = simulation_reform.calculate('disposable_income', "2016-01") + simulation = \ + simulation_builder \ + .build_from_variables(isolated_tax_benefit_system, variables) - assert(revenu_disponible_apres_reforme == 0) + disposable_income = simulation.calculate("disposable_income", PERIOD) + assert disposable_income == 0 + + +def test_variable_name_conflict(tax_benefit_system): -def test_variable_name_conflict(): class disposable_income(Variable): - reference = 'disposable_income' - definition_period = MONTH + reference = "disposable_income" + definition_period = periods.MONTH def formula(household, period): return household.empty_array() - with raises(VariableNameConflict): + + with pytest.raises(VariableNameConflictError): tax_benefit_system.add_variable(disposable_income) diff --git a/tests/fixtures/__init__.py b/tests/fixtures/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/fixtures/simulations.py b/tests/fixtures/simulations.py new file mode 100644 index 0000000000..23f73d2f1f --- /dev/null +++ b/tests/fixtures/simulations.py @@ -0,0 +1,8 @@ +import pytest + +from openfisca_core.simulation_builder import SimulationBuilder + + +@pytest.fixture +def simulation_builder(): + return SimulationBuilder() diff --git a/tests/fixtures/taxbenefitsystems.py b/tests/fixtures/taxbenefitsystems.py new file mode 100644 index 0000000000..c2c47071ca --- /dev/null +++ b/tests/fixtures/taxbenefitsystems.py @@ -0,0 +1,13 @@ +import pytest + +from openfisca_country_template import CountryTaxBenefitSystem + + +@pytest.fixture(scope = "module") +def tax_benefit_system(): + return CountryTaxBenefitSystem() + + +@pytest.fixture +def isolated_tax_benefit_system(): + return CountryTaxBenefitSystem() From 04adc8426b1bb90baca74ac3180fc7f515a1e2d5 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:36:03 +0200 Subject: [PATCH 02/22] Fix simulation builder tests --- tests/core/test_simulation_builder.py | 42 +++++++++++---------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/tests/core/test_simulation_builder.py b/tests/core/test_simulation_builder.py index 09e594cce1..864bcdae8a 100644 --- a/tests/core/test_simulation_builder.py +++ b/tests/core/test_simulation_builder.py @@ -7,7 +7,7 @@ from pytest import raises, fixture, approx -from openfisca_core.simulation_builder import SimulationBuilder, Simulation +from openfisca_core.simulation_builder import Simulation from openfisca_core.tools import assert_near from openfisca_core.tools.test_runner import yaml from openfisca_core.entities import Entity, GroupEntity @@ -20,9 +20,6 @@ from openfisca_core.indexed_enums import Enum as OFEnum -from .test_countries import tax_benefit_system - - class TestVariable(Variable): definition_period = ETERNITY value_type = float @@ -32,11 +29,6 @@ def __init__(self, entity): super().__init__() -@fixture -def simulation_builder(): - return SimulationBuilder() - - @fixture def int_variable(persons): @@ -121,7 +113,7 @@ def check_variable_defined_for_entity(self, variable_name): return Household("household", "households", "", "", roles) -def test_build_default_simulation(simulation_builder): +def test_build_default_simulation(simulation_builder, tax_benefit_system): one_person_simulation = simulation_builder.build_default_simulation(tax_benefit_system, 1) assert one_person_simulation.persons.count == 1 assert one_person_simulation.household.count == 1 @@ -135,7 +127,7 @@ def test_build_default_simulation(simulation_builder): assert (several_persons_simulation.household.members_role == Household.FIRST_PARENT).all() -def test_explicit_singular_entities(simulation_builder): +def test_explicit_singular_entities(simulation_builder, tax_benefit_system): assert simulation_builder.explicit_singular_entities( tax_benefit_system, {'persons': {'Javier': {}}, 'household': {'parents': ['Javier']}} @@ -275,7 +267,7 @@ def test_canonicalize_period_keys(simulation_builder, persons): assert_near(population.get_holder('salary').get_array('2018-12'), [100]) -def test_finalize_group_entity(simulation_builder): +def test_finalize_group_entity(simulation_builder, tax_benefit_system): simulation = Simulation(tax_benefit_system, tax_benefit_system.instantiate_entities()) simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', 'Tom'], simulation.household.entity, { 'Household_1': {'parents': ['Alicia', 'Javier']}, @@ -337,7 +329,7 @@ def test_allocate_person_twice(simulation_builder): assert exception.value.error == {'familles': {'famille1': {'parents': 'Alicia has been declared more than once in familles'}}} -def test_one_person_without_household(simulation_builder): +def test_one_person_without_household(simulation_builder, tax_benefit_system): simulation_dict = {'persons': {'Alicia': {}}} simulation = simulation_builder.build_from_dict(tax_benefit_system, simulation_dict) assert simulation.household.count == 1 @@ -345,7 +337,7 @@ def test_one_person_without_household(simulation_builder): assert parents_in_households.tolist() == [1] # household member default role is first_parent -def test_some_person_without_household(simulation_builder): +def test_some_person_without_household(simulation_builder, tax_benefit_system): input_yaml = """ persons: {'Alicia': {}, 'Bob': {}} household: {'parents': ['Alicia']} @@ -356,7 +348,7 @@ def test_some_person_without_household(simulation_builder): assert parents_in_households.tolist() == [1, 1] # household member default role is first_parent -def test_nb_persons_in_group_entity(simulation_builder): +def test_nb_persons_in_group_entity(simulation_builder, tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] @@ -371,7 +363,7 @@ def test_nb_persons_in_group_entity(simulation_builder): assert persons_in_households.tolist() == [1, 3, 1] -def test_nb_persons_no_role(simulation_builder): +def test_nb_persons_no_role(simulation_builder, tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] @@ -386,7 +378,7 @@ def test_nb_persons_no_role(simulation_builder): assert parents_in_households.tolist() == [1, 3, 1] # household member default role is first_parent -def test_nb_persons_by_role(simulation_builder): +def test_nb_persons_by_role(simulation_builder, tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] @@ -406,7 +398,7 @@ def test_nb_persons_by_role(simulation_builder): assert parents_in_households.tolist() == [0, 1, 1] -def test_integral_roles(simulation_builder): +def test_integral_roles(simulation_builder, tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] @@ -430,7 +422,7 @@ def test_integral_roles(simulation_builder): # Test Intégration -def test_from_person_variable_to_group(simulation_builder): +def test_from_person_variable_to_group(simulation_builder, tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] @@ -456,7 +448,7 @@ def test_from_person_variable_to_group(simulation_builder): assert total_taxes / simulation.calculate('rent', period) == approx(1) -def test_simulation(simulation_builder): +def test_simulation(simulation_builder, tax_benefit_system): input_yaml = """ salary: 2016-10: 12000 @@ -469,7 +461,7 @@ def test_simulation(simulation_builder): simulation.calculate("total_taxes", "2016-10") -def test_vectorial_input(simulation_builder): +def test_vectorial_input(simulation_builder, tax_benefit_system): input_yaml = """ salary: 2016-10: [12000, 20000] @@ -482,13 +474,13 @@ def test_vectorial_input(simulation_builder): simulation.calculate("total_taxes", "2016-10") -def test_fully_specified_entities(simulation_builder): +def test_fully_specified_entities(simulation_builder, tax_benefit_system): simulation = simulation_builder.build_from_dict(tax_benefit_system, couple) assert simulation.household.count == 1 assert simulation.persons.count == 2 -def test_single_entity_shortcut(simulation_builder): +def test_single_entity_shortcut(simulation_builder, tax_benefit_system): input_yaml = """ persons: Alicia: {} @@ -501,7 +493,7 @@ def test_single_entity_shortcut(simulation_builder): assert simulation.household.count == 1 -def test_order_preserved(simulation_builder): +def test_order_preserved(simulation_builder, tax_benefit_system): input_yaml = """ persons: Javier: {} @@ -519,7 +511,7 @@ def test_order_preserved(simulation_builder): assert simulation.persons.ids == ['Javier', 'Alicia', 'Sarah', 'Tom'] -def test_inconsistent_input(simulation_builder): +def test_inconsistent_input(simulation_builder, tax_benefit_system): input_yaml = """ salary: 2016-10: [12000, 20000] From 3f4ab44fe9ae29a6b12a22fec472eab5586616d8 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:38:20 +0200 Subject: [PATCH 03/22] Fix dump restore tests --- tests/core/test_dump_restore.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/core/test_dump_restore.py b/tests/core/test_dump_restore.py index fcc53f516f..cbb065b07b 100644 --- a/tests/core/test_dump_restore.py +++ b/tests/core/test_dump_restore.py @@ -1,21 +1,15 @@ -# -*- coding: utf-8 -*- - - import shutil import tempfile from numpy.testing import assert_array_equal -from openfisca_core.simulation_builder import SimulationBuilder from openfisca_country_template.situation_examples import couple from openfisca_core.tools.simulation_dumper import dump_simulation, restore_simulation -from .test_countries import tax_benefit_system - -def test_dump(): +def test_dump(simulation_builder, tax_benefit_system): directory = tempfile.mkdtemp(prefix = "openfisca_") - simulation = SimulationBuilder().build_from_entities(tax_benefit_system, couple) + simulation = simulation_builder.build_from_entities(tax_benefit_system, couple) calculated_value = simulation.calculate('disposable_income', '2018-01') dump_simulation(simulation, directory) From 2c9df2cf36ddc5d78874a1ca40e1a5aa25237830 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:51:48 +0200 Subject: [PATCH 04/22] Fix entity tests --- tests/core/test_entities.py | 103 +++++++++++++++++------------------- 1 file changed, 49 insertions(+), 54 deletions(-) diff --git a/tests/core/test_entities.py b/tests/core/test_entities.py index 0702ceaf3b..d1893e2fbc 100644 --- a/tests/core/test_entities.py +++ b/tests/core/test_entities.py @@ -1,14 +1,10 @@ -# -*- coding: utf-8 -*- - from copy import deepcopy -from openfisca_core.simulation_builder import SimulationBuilder from openfisca_core.tools import assert_near from openfisca_core.tools.test_runner import yaml from openfisca_country_template.entities import Household from openfisca_country_template.situation_examples import single, couple -from .test_countries import tax_benefit_system TEST_CASE = { 'persons': {'ind0': {}, 'ind1': {}, 'ind2': {}, 'ind3': {}, 'ind4': {}, 'ind5': {}}, @@ -32,14 +28,13 @@ MONTH = "2016-01" -def new_simulation(test_case, period = MONTH): - builder = SimulationBuilder() - builder.set_default_period(period) - return builder.build_from_entities(tax_benefit_system, test_case) +def new_simulation(simulation_builder, tax_benefit_system, test_case, period = MONTH): + simulation_builder.set_default_period(period) + return simulation_builder.build_from_entities(tax_benefit_system, test_case) -def test_role_index_and_positions(): - simulation = new_simulation(TEST_CASE) +def test_role_index_and_positions(simulation_builder, tax_benefit_system): + simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) assert_near(simulation.household.members_entity_id, [0, 0, 0, 0, 1, 1]) assert((simulation.household.members_role == [FIRST_PARENT, SECOND_PARENT, CHILD, CHILD, FIRST_PARENT, CHILD]).all()) assert_near(simulation.household.members_position, [0, 1, 2, 3, 0, 1]) @@ -47,7 +42,7 @@ def test_role_index_and_positions(): assert(simulation.household.ids == ['h1', 'h2']) -def test_entity_structure_with_constructor(): +def test_entity_structure_with_constructor(simulation_builder, tax_benefit_system): simulation_yaml = """ persons: bill: {} @@ -68,7 +63,7 @@ def test_entity_structure_with_constructor(): - claudia """ - simulation = SimulationBuilder().build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) household = simulation.household @@ -77,7 +72,7 @@ def test_entity_structure_with_constructor(): assert_near(household.members_position, [0, 1, 0, 2, 3]) -def test_entity_variables_with_constructor(): +def test_entity_variables_with_constructor(simulation_builder, tax_benefit_system): simulation_yaml = """ persons: bill: {} @@ -102,12 +97,12 @@ def test_entity_variables_with_constructor(): 2017-06: 600 """ - simulation = SimulationBuilder().build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) household = simulation.household assert_near(household('rent', "2017-06"), [800, 600]) -def test_person_variable_with_constructor(): +def test_person_variable_with_constructor(simulation_builder, tax_benefit_system): simulation_yaml = """ persons: bill: @@ -135,13 +130,13 @@ def test_person_variable_with_constructor(): - claudia """ - simulation = SimulationBuilder().build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) person = simulation.person assert_near(person('salary', "2017-11"), [1500, 0, 3000, 0, 0]) assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) -def test_set_input_with_constructor(): +def test_set_input_with_constructor(simulation_builder, tax_benefit_system): simulation_yaml = """ persons: bill: @@ -174,31 +169,31 @@ def test_set_input_with_constructor(): - claudia """ - simulation = SimulationBuilder().build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) person = simulation.person assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) assert_near(person('salary', "2017-10"), [2000, 3000, 1600, 0, 0]) -def test_has_role(): - simulation = new_simulation(TEST_CASE) +def test_has_role(simulation_builder, tax_benefit_system): + simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) individu = simulation.persons assert_near(individu.has_role(CHILD), [False, False, True, True, False, True]) -def test_has_role_with_subrole(): - simulation = new_simulation(TEST_CASE) +def test_has_role_with_subrole(simulation_builder, tax_benefit_system): + simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) individu = simulation.persons assert_near(individu.has_role(PARENT), [True, True, False, False, True, False]) assert_near(individu.has_role(FIRST_PARENT), [True, False, False, False, True, False]) assert_near(individu.has_role(SECOND_PARENT), [False, True, False, False, False, False]) -def test_project(): +def test_project(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['households']['h1']['housing_tax'] = 20000 - simulation = new_simulation(test_case, YEAR) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, YEAR) household = simulation.household housing_tax = household('housing_tax', YEAR) @@ -210,25 +205,25 @@ def test_project(): assert_near(housing_tax_projected_on_parents, [20000, 20000, 0, 0, 0, 0]) -def test_implicit_projection(): +def test_implicit_projection(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['households']['h1']['housing_tax'] = 20000 - simulation = new_simulation(test_case, YEAR) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, YEAR) individu = simulation.person housing_tax = individu.household('housing_tax', YEAR) assert_near(housing_tax, [20000, 20000, 20000, 20000, 0, 0]) -def test_sum(): +def test_sum(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['persons']['ind0']['salary'] = 1000 test_case['persons']['ind1']['salary'] = 1500 test_case['persons']['ind4']['salary'] = 3000 test_case['persons']['ind5']['salary'] = 500 - simulation = new_simulation(test_case, MONTH) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, MONTH) household = simulation.household salary = household.members('salary', "2016-01") @@ -241,9 +236,9 @@ def test_sum(): assert_near(total_salary_parents_by_household, [2500, 3000]) -def test_any(): +def test_any(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -256,9 +251,9 @@ def test_any(): assert_near(has_household_CHILD_with_age_sup_18, [False, True]) -def test_all(): +def test_all(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -271,9 +266,9 @@ def test_all(): assert_near(all_parents_age_sup_18, [True, True]) -def test_max(): +def test_max(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -285,9 +280,9 @@ def test_max(): assert_near(age_max_child, [9, 20]) -def test_min(): +def test_min(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -299,9 +294,9 @@ def test_min(): assert_near(age_min_parents, [37, 54]) -def test_value_nth_person(): +def test_value_nth_person(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household array = household.members('age', MONTH) @@ -318,9 +313,9 @@ def test_value_nth_person(): assert_near(result3, [9, -1]) -def test_rank(): +def test_rank(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) person = simulation.person age = person('age', MONTH) # [40, 37, 7, 9, 54, 20] @@ -331,14 +326,14 @@ def test_rank(): assert_near(rank_in_siblings, [-1, -1, 1, 0, -1, 0]) -def test_partner(): +def test_partner(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['persons']['ind0']['salary'] = 1000 test_case['persons']['ind1']['salary'] = 1500 test_case['persons']['ind4']['salary'] = 3000 test_case['persons']['ind5']['salary'] = 500 - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) persons = simulation.persons salary = persons('salary', period = MONTH) @@ -348,14 +343,14 @@ def test_partner(): assert_near(salary_second_parent, [1500, 1000, 0, 0, 0, 0]) -def test_value_from_first_person(): +def test_value_from_first_person(simulation_builder, tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['persons']['ind0']['salary'] = 1000 test_case['persons']['ind1']['salary'] = 1500 test_case['persons']['ind4']['salary'] = 3000 test_case['persons']['ind5']['salary'] = 500 - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household salaries = household.members('salary', period = MONTH) @@ -364,8 +359,8 @@ def test_value_from_first_person(): assert_near(salary_first_person, [1000, 3000]) -def test_projectors_methods(): - simulation = SimulationBuilder().build_from_dict(tax_benefit_system, couple) +def test_projectors_methods(simulation_builder, tax_benefit_system): + simulation = simulation_builder.build_from_dict(tax_benefit_system, couple) household = simulation.household person = simulation.person @@ -381,7 +376,7 @@ def test_projectors_methods(): assert(len(household.first_parent.get_rank(household, salary_i)) == 1) # Must be of a person dimension -def test_sum_following_bug_ipp_1(): +def test_sum_following_bug_ipp_1(simulation_builder, tax_benefit_system): test_case = { 'persons': {'ind0': {}, 'ind1': {}, 'ind2': {}, 'ind3': {}}, 'households': { @@ -394,7 +389,7 @@ def test_sum_following_bug_ipp_1(): test_case['persons']['ind2']['salary'] = 1000 test_case['persons']['ind3']['salary'] = 1000 - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household eligible_i = household.members('salary', period = MONTH) < 1500 @@ -403,7 +398,7 @@ def test_sum_following_bug_ipp_1(): assert_near(nb_eligibles_by_household, [0, 2]) -def test_sum_following_bug_ipp_2(): +def test_sum_following_bug_ipp_2(simulation_builder, tax_benefit_system): test_case = { 'persons': {'ind0': {}, 'ind1': {}, 'ind2': {}, 'ind3': {}}, 'households': { @@ -416,7 +411,7 @@ def test_sum_following_bug_ipp_2(): test_case['persons']['ind2']['salary'] = 1000 test_case['persons']['ind3']['salary'] = 1000 - simulation = new_simulation(test_case) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) household = simulation.household eligible_i = household.members('salary', period = MONTH) < 1500 @@ -425,17 +420,17 @@ def test_sum_following_bug_ipp_2(): assert_near(nb_eligibles_by_household, [2, 0]) -def test_get_memory_usage(): +def test_get_memory_usage(simulation_builder, tax_benefit_system): test_case = deepcopy(single) test_case["persons"]["Alicia"]["salary"] = {"2017-01": 0} - simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_case) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_case) simulation.calculate('disposable_income', '2017-01') memory_usage = simulation.person.get_memory_usage(variables = ['salary']) assert(memory_usage['total_nb_bytes'] > 0) assert(len(memory_usage['by_variable']) == 1) -def test_unordered_persons(): +def test_unordered_persons(simulation_builder, tax_benefit_system): test_case = { 'persons': {'ind4': {}, 'ind3': {}, 'ind1': {}, 'ind2': {}, 'ind5': {}, 'ind0': {}}, 'households': { @@ -456,7 +451,7 @@ def test_unordered_persons(): # household.members_entity_id == [1, 0, 0, 0, 1, 0] - simulation = new_simulation(test_case, MONTH) + simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, MONTH) household = simulation.household person = simulation.person From 61f326ef65ff8bfcc267c3f5808e4990d41564c9 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:53:32 +0200 Subject: [PATCH 05/22] Fix holder tests --- tests/core/test_holders.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/core/test_holders.py b/tests/core/test_holders.py index 9e62d6e64b..1ccc48bf64 100644 --- a/tests/core/test_holders.py +++ b/tests/core/test_holders.py @@ -1,29 +1,25 @@ -# -*- coding: utf-8 -*- - import numpy as np import pytest import openfisca_country_template.situation_examples -from openfisca_core.simulation_builder import SimulationBuilder from openfisca_country_template.variables.housing import HousingOccupancyStatus from openfisca_core.periods import period as make_period, ETERNITY from openfisca_core.tools import assert_near from openfisca_core.memory_config import MemoryConfig from openfisca_core.holders import Holder, set_input_dispatch_by_period from openfisca_core.errors import PeriodMismatchError -from .test_countries import tax_benefit_system from pytest import fixture @fixture -def single(): - return SimulationBuilder().build_from_entities(tax_benefit_system, openfisca_country_template.situation_examples.single) +def single(simulation_builder, tax_benefit_system): + return simulation_builder.build_from_entities(tax_benefit_system, openfisca_country_template.situation_examples.single) @fixture -def couple(): - return SimulationBuilder().build_from_entities(tax_benefit_system, openfisca_country_template.situation_examples.couple) +def couple(simulation_builder, tax_benefit_system): + return simulation_builder.build_from_entities(tax_benefit_system, openfisca_country_template.situation_examples.couple) period = make_period('2017-12') From 61ea4b3fc46a72fc24f42d9570b3f1d7ed4f4579 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:54:49 +0200 Subject: [PATCH 06/22] Fix simulation tests --- tests/core/test_simulations.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/tests/core/test_simulations.py b/tests/core/test_simulations.py index 6665cce8e1..520df1a29e 100644 --- a/tests/core/test_simulations.py +++ b/tests/core/test_simulations.py @@ -1,15 +1,8 @@ -# -*- coding: utf-8 -*- - - -from openfisca_core.simulation_builder import SimulationBuilder - from openfisca_country_template.situation_examples import single -from .test_countries import tax_benefit_system - -def test_calculate_full_tracer(): - simulation = SimulationBuilder().build_default_simulation(tax_benefit_system) +def test_calculate_full_tracer(simulation_builder, tax_benefit_system): + simulation = simulation_builder.build_default_simulation(tax_benefit_system) simulation.trace = True simulation.calculate('income_tax', '2017-01') @@ -29,13 +22,13 @@ def test_calculate_full_tracer(): assert income_tax_node.parameters[0].value == 0.15 -def test_get_entity_not_found(): - simulation = SimulationBuilder().build_default_simulation(tax_benefit_system) +def test_get_entity_not_found(simulation_builder, tax_benefit_system): + simulation = simulation_builder.build_default_simulation(tax_benefit_system) assert simulation.get_entity(plural = "no_such_entities") is None -def test_clone(): - simulation = SimulationBuilder().build_from_entities(tax_benefit_system, +def test_clone(simulation_builder, tax_benefit_system): + simulation = simulation_builder.build_from_entities(tax_benefit_system, { "persons": { "bill": {"salary": {"2017-01": 3000}}, @@ -63,8 +56,8 @@ def test_clone(): assert salary_holder_clone.population == simulation_clone.persons -def test_get_memory_usage(): - simulation = SimulationBuilder().build_from_entities(tax_benefit_system, single) +def test_get_memory_usage(simulation_builder, tax_benefit_system): + simulation = simulation_builder.build_from_entities(tax_benefit_system, single) simulation.calculate('disposable_income', '2017-01') memory_usage = simulation.get_memory_usage(variables = ['salary']) assert(memory_usage['total_nb_bytes'] > 0) From e4f7504bc3331655a797d7818596759f540cbe6d Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:56:40 +0200 Subject: [PATCH 07/22] Fix parameter tests --- tests/core/test_parameters.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/tests/core/test_parameters.py b/tests/core/test_parameters.py index 88fedcabab..40d8bb3fc9 100644 --- a/tests/core/test_parameters.py +++ b/tests/core/test_parameters.py @@ -1,14 +1,11 @@ -# -*- coding: utf-8 -*- - import tempfile import pytest from openfisca_core.parameters import ParameterNotFound, ParameterNode, ParameterNodeAtInstant, load_parameter_file -from .test_countries import tax_benefit_system -def test_get_at_instant(): +def test_get_at_instant(tax_benefit_system): parameters = tax_benefit_system.parameters assert isinstance(parameters, ParameterNode), parameters parameters_at_instant = parameters('2016-01-01') @@ -17,7 +14,7 @@ def test_get_at_instant(): assert parameters_at_instant.benefits.basic_income == 600 -def test_param_values(): +def test_param_values(tax_benefit_system): dated_values = { '2015-01-01': 0.15, '2014-01-01': 0.14, @@ -29,37 +26,37 @@ def test_param_values(): assert tax_benefit_system.get_parameters_at_instant(date).taxes.income_tax_rate == value -def test_param_before_it_is_defined(): +def test_param_before_it_is_defined(tax_benefit_system): with pytest.raises(ParameterNotFound): tax_benefit_system.get_parameters_at_instant('1997-12-31').taxes.income_tax_rate # The placeholder should have no effect on the parameter computation -def test_param_with_placeholder(): +def test_param_with_placeholder(tax_benefit_system): assert tax_benefit_system.get_parameters_at_instant('2018-01-01').taxes.income_tax_rate == 0.15 -def test_stopped_parameter_before_end_value(): +def test_stopped_parameter_before_end_value(tax_benefit_system): assert tax_benefit_system.get_parameters_at_instant('2011-12-31').benefits.housing_allowance == 0.25 -def test_stopped_parameter_after_end_value(): +def test_stopped_parameter_after_end_value(tax_benefit_system): with pytest.raises(ParameterNotFound): tax_benefit_system.get_parameters_at_instant('2016-12-01').benefits.housing_allowance -def test_parameter_for_period(): +def test_parameter_for_period(tax_benefit_system): income_tax_rate = tax_benefit_system.parameters.taxes.income_tax_rate assert income_tax_rate("2015") == income_tax_rate("2015-01-01") -def test_wrong_value(): +def test_wrong_value(tax_benefit_system): income_tax_rate = tax_benefit_system.parameters.taxes.income_tax_rate with pytest.raises(ValueError): income_tax_rate("test") -def test_parameter_repr(): +def test_parameter_repr(tax_benefit_system): parameters = tax_benefit_system.parameters tf = tempfile.NamedTemporaryFile(delete = False) tf.write(repr(parameters).encode('utf-8')) @@ -68,7 +65,7 @@ def test_parameter_repr(): assert repr(parameters) == repr(tf_parameters) -def test_parameters_metadata(): +def test_parameters_metadata(tax_benefit_system): parameter = tax_benefit_system.parameters.benefits.basic_income assert parameter.metadata['reference'] == 'https://law.gov.example/basic-income/amount' assert parameter.metadata['unit'] == 'currency-EUR' @@ -79,7 +76,7 @@ def test_parameters_metadata(): assert scale.metadata['rate_unit'] == '/1' -def test_parameter_node_metadata(): +def test_parameter_node_metadata(tax_benefit_system): parameter = tax_benefit_system.parameters.benefits assert parameter.description == 'Social benefits' @@ -87,12 +84,12 @@ def test_parameter_node_metadata(): assert parameter_2.description == 'Housing tax' -def test_parameter_documentation(): +def test_parameter_documentation(tax_benefit_system): parameter = tax_benefit_system.parameters.benefits.housing_allowance assert parameter.documentation == 'A fraction of the rent.\nFrom the 1st of Dec 2016, the housing allowance no longer exists.\n' -def test_get_descendants(): +def test_get_descendants(tax_benefit_system): all_parameters = {parameter.name for parameter in tax_benefit_system.parameters.get_descendants()} assert all_parameters.issuperset({'taxes', 'taxes.housing_tax', 'taxes.housing_tax.minimal_amount'}) From 14a8436bae8a60e14d4e657e439f206387049cea Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:58:33 +0200 Subject: [PATCH 08/22] Fix yaml tests --- tests/core/test_yaml.py | 53 +++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/tests/core/test_yaml.py b/tests/core/test_yaml.py index 2390eb6929..15085dbbf3 100644 --- a/tests/core/test_yaml.py +++ b/tests/core/test_yaml.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import pkg_resources import os import subprocess @@ -9,8 +7,6 @@ from openfisca_core.tools.test_runner import run_tests -from .test_countries import tax_benefit_system - openfisca_core_dir = pkg_resources.get_distribution('OpenFisca-Core').location yaml_tests_dir = os.path.join(openfisca_core_dir, 'tests', 'core', 'yaml_tests') @@ -18,7 +14,7 @@ EXIT_TESTSFAILED = 1 -def run_yaml_test(path, options = None): +def run_yaml_test(tax_benefit_system, path, options = None): yaml_path = os.path.join(yaml_tests_dir, path) if options is None: @@ -28,53 +24,54 @@ def run_yaml_test(path, options = None): return result -def test_success(): - assert run_yaml_test('test_success.yml') == EXIT_OK +def test_success(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'test_success.yml') == EXIT_OK -def test_fail(): - assert run_yaml_test('test_failure.yaml') == EXIT_TESTSFAILED +def test_fail(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'test_failure.yaml') == EXIT_TESTSFAILED -def test_relative_error_margin_success(): - assert run_yaml_test('test_relative_error_margin.yaml') == EXIT_OK +def test_relative_error_margin_success(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'test_relative_error_margin.yaml') == EXIT_OK -def test_relative_error_margin_fail(): - assert run_yaml_test('failing_test_relative_error_margin.yaml') == EXIT_TESTSFAILED +def test_relative_error_margin_fail(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'failing_test_relative_error_margin.yaml') == EXIT_TESTSFAILED -def test_absolute_error_margin_success(): - assert run_yaml_test('test_absolute_error_margin.yaml') == EXIT_OK +def test_absolute_error_margin_success(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'test_absolute_error_margin.yaml') == EXIT_OK -def test_absolute_error_margin_fail(): - assert run_yaml_test('failing_test_absolute_error_margin.yaml') == EXIT_TESTSFAILED +def test_absolute_error_margin_fail(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'failing_test_absolute_error_margin.yaml') == EXIT_TESTSFAILED -def test_run_tests_from_directory(): +def test_run_tests_from_directory(tax_benefit_system): dir_path = os.path.join(yaml_tests_dir, 'directory') - assert run_yaml_test(dir_path) == EXIT_OK + assert run_yaml_test(tax_benefit_system, dir_path) == EXIT_OK -def test_with_reform(): - assert run_yaml_test('test_with_reform.yaml') == EXIT_OK +def test_with_reform(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'test_with_reform.yaml') == EXIT_OK -def test_with_extension(): - assert run_yaml_test('test_with_extension.yaml') == EXIT_OK +def test_with_extension(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'test_with_extension.yaml') == EXIT_OK -def test_with_anchors(): - assert run_yaml_test('test_with_anchors.yaml') == EXIT_OK +def test_with_anchors(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, 'test_with_anchors.yaml') == EXIT_OK -def test_run_tests_from_directory_fail(): - assert run_yaml_test(yaml_tests_dir) == EXIT_TESTSFAILED +def test_run_tests_from_directory_fail(tax_benefit_system): + assert run_yaml_test(tax_benefit_system, yaml_tests_dir) == EXIT_TESTSFAILED -def test_name_filter(): +def test_name_filter(tax_benefit_system): assert run_yaml_test( + tax_benefit_system, yaml_tests_dir, options = {'name_filter': 'success'} ) == EXIT_OK From bd313ff4ce69e7b9a9765672442ef6cf9fa00dba Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 17:59:59 +0200 Subject: [PATCH 09/22] Fix parameter validation tests --- .../parameter_validation/test_parameter_clone.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/core/parameter_validation/test_parameter_clone.py b/tests/core/parameter_validation/test_parameter_clone.py index 7b839caa15..a14630e9a0 100644 --- a/tests/core/parameter_validation/test_parameter_clone.py +++ b/tests/core/parameter_validation/test_parameter_clone.py @@ -1,8 +1,7 @@ -# -*- coding: utf-8 -*- -from ..test_countries import tax_benefit_system - import os + from openfisca_core.parameters import ParameterNode + BASE_DIR = os.path.dirname(os.path.abspath(__file__)) year = 2016 @@ -20,7 +19,7 @@ def test_clone(): assert id(clone.node1.param) != id(parameters.node1.param) -def test_clone_parameter(): +def test_clone_parameter(tax_benefit_system): param = tax_benefit_system.parameters.taxes.income_tax_rate clone = param.clone() @@ -32,7 +31,7 @@ def test_clone_parameter(): assert clone.values_list == param.values_list -def test_clone_parameter_node(): +def test_clone_parameter_node(tax_benefit_system): node = tax_benefit_system.parameters.taxes clone = node.clone() @@ -41,7 +40,7 @@ def test_clone_parameter_node(): assert clone.children['income_tax_rate'] is not node.children['income_tax_rate'] -def test_clone_scale(): +def test_clone_scale(tax_benefit_system): scale = tax_benefit_system.parameters.taxes.social_security_contribution clone = scale.clone() @@ -49,7 +48,7 @@ def test_clone_scale(): assert clone.brackets[0].rate is not scale.brackets[0].rate -def test_deep_edit(): +def test_deep_edit(tax_benefit_system): parameters = tax_benefit_system.parameters clone = parameters.clone() From 0df429aa24f02dac71e2e8632db88fb3751caefc Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Fri, 9 Apr 2021 18:02:51 +0200 Subject: [PATCH 10/22] Fix axes tests --- tests/core/test_axes.py | 88 +++++++++++++++------------- tests/core/tools/test_assert_near.py | 7 +-- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/tests/core/test_axes.py b/tests/core/test_axes.py index 686c9b27e7..e4280efaf2 100644 --- a/tests/core/test_axes.py +++ b/tests/core/test_axes.py @@ -1,31 +1,27 @@ import pytest -from pytest import fixture, approx -from openfisca_core.simulation_builder import SimulationBuilder -from .test_simulation_builder import * # noqa: F401 - - -@fixture -def simulation_builder(): - return SimulationBuilder() +from openfisca_core.simulations import SimulationBuilder +from openfisca_core.tools import test_runner # With periods -def test_add_axis_without_period(simulation_builder, persons): +def test_add_axis_without_period(persons): + simulation_builder = SimulationBuilder() simulation_builder.set_default_period('2018-11') simulation_builder.add_person_entity(persons, {'Alicia': {}}) simulation_builder.register_variable('salary', persons) simulation_builder.add_parallel_axis({'count': 3, 'name': 'salary', 'min': 0, 'max': 3000}) simulation_builder.expand_axes() - assert simulation_builder.get_input('salary', '2018-11') == approx([0, 1500, 3000]) + assert simulation_builder.get_input('salary', '2018-11') == pytest.approx([0, 1500, 3000]) # With variables -def test_add_axis_on_a_non_existing_variable(simulation_builder, persons): +def test_add_axis_on_a_non_existing_variable(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}}) simulation_builder.add_parallel_axis({'count': 3, 'name': 'ubi', 'min': 0, 'max': 3000, 'period': '2018-11'}) @@ -33,12 +29,13 @@ def test_add_axis_on_a_non_existing_variable(simulation_builder, persons): simulation_builder.expand_axes() -def test_add_axis_on_an_existing_variable_with_input(simulation_builder, persons): +def test_add_axis_on_an_existing_variable_with_input(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {'salary': {'2018-11': 1000}}}) simulation_builder.register_variable('salary', persons) simulation_builder.add_parallel_axis({'count': 3, 'name': 'salary', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.expand_axes() - assert simulation_builder.get_input('salary', '2018-11') == approx([0, 1500, 3000]) + assert simulation_builder.get_input('salary', '2018-11') == pytest.approx([0, 1500, 3000]) assert simulation_builder.get_count('persons') == 3 assert simulation_builder.get_ids('persons') == ['Alicia0', 'Alicia1', 'Alicia2'] @@ -46,27 +43,30 @@ def test_add_axis_on_an_existing_variable_with_input(simulation_builder, persons # With entities -def test_add_axis_on_persons(simulation_builder, persons): +def test_add_axis_on_persons(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}}) simulation_builder.register_variable('salary', persons) simulation_builder.add_parallel_axis({'count': 3, 'name': 'salary', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.expand_axes() - assert simulation_builder.get_input('salary', '2018-11') == approx([0, 1500, 3000]) + assert simulation_builder.get_input('salary', '2018-11') == pytest.approx([0, 1500, 3000]) assert simulation_builder.get_count('persons') == 3 assert simulation_builder.get_ids('persons') == ['Alicia0', 'Alicia1', 'Alicia2'] -def test_add_two_axes(simulation_builder, persons): +def test_add_two_axes(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}}) simulation_builder.register_variable('salary', persons) simulation_builder.add_parallel_axis({'count': 3, 'name': 'salary', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.add_parallel_axis({'count': 3, 'name': 'pension', 'min': 0, 'max': 2000, 'period': '2018-11'}) simulation_builder.expand_axes() - assert simulation_builder.get_input('salary', '2018-11') == approx([0, 1500, 3000]) - assert simulation_builder.get_input('pension', '2018-11') == approx([0, 1000, 2000]) + assert simulation_builder.get_input('salary', '2018-11') == pytest.approx([0, 1500, 3000]) + assert simulation_builder.get_input('pension', '2018-11') == pytest.approx([0, 1000, 2000]) -def test_add_axis_with_group(simulation_builder, persons): +def test_add_axis_with_group(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}}) simulation_builder.register_variable('salary', persons) simulation_builder.add_parallel_axis({'count': 2, 'name': 'salary', 'min': 0, 'max': 3000, 'period': '2018-11'}) @@ -74,19 +74,21 @@ def test_add_axis_with_group(simulation_builder, persons): simulation_builder.expand_axes() assert simulation_builder.get_count('persons') == 4 assert simulation_builder.get_ids('persons') == ['Alicia0', 'Javier1', 'Alicia2', 'Javier3'] - assert simulation_builder.get_input('salary', '2018-11') == approx([0, 0, 3000, 3000]) + assert simulation_builder.get_input('salary', '2018-11') == pytest.approx([0, 0, 3000, 3000]) -def test_add_axis_with_group_int_period(simulation_builder, persons): +def test_add_axis_with_group_int_period(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}}) simulation_builder.register_variable('salary', persons) simulation_builder.add_parallel_axis({'count': 2, 'name': 'salary', 'min': 0, 'max': 3000, 'period': 2018}) simulation_builder.add_parallel_axis({'count': 2, 'name': 'salary', 'min': 0, 'max': 3000, 'period': 2018, 'index': 1}) simulation_builder.expand_axes() - assert simulation_builder.get_input('salary', '2018') == approx([0, 0, 3000, 3000]) + assert simulation_builder.get_input('salary', '2018') == pytest.approx([0, 0, 3000, 3000]) -def test_add_axis_on_group_entity(simulation_builder, persons, group_entity): +def test_add_axis_on_group_entity(persons, group_entity): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { 'housea': {'parents': ['Alicia', 'Javier']}, @@ -97,10 +99,11 @@ def test_add_axis_on_group_entity(simulation_builder, persons, group_entity): simulation_builder.expand_axes() assert simulation_builder.get_count('households') == 4 assert simulation_builder.get_ids('households') == ['housea0', 'houseb1', 'housea2', 'houseb3'] - assert simulation_builder.get_input('rent', '2018-11') == approx([0, 0, 3000, 0]) + assert simulation_builder.get_input('rent', '2018-11') == pytest.approx([0, 0, 3000, 0]) -def test_axis_on_group_expands_persons(simulation_builder, persons, group_entity): +def test_axis_on_group_expands_persons(persons, group_entity): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { 'housea': {'parents': ['Alicia', 'Javier']}, @@ -112,7 +115,8 @@ def test_axis_on_group_expands_persons(simulation_builder, persons, group_entity assert simulation_builder.get_count('persons') == 6 -def test_add_axis_distributes_roles(simulation_builder, persons, group_entity): +def test_add_axis_distributes_roles(persons, group_entity): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { 'housea': {'parents': ['Alicia']}, @@ -124,7 +128,8 @@ def test_add_axis_distributes_roles(simulation_builder, persons, group_entity): assert [role.key for role in simulation_builder.get_roles('households')] == ['parent', 'child', 'parent', 'parent', 'child', 'parent'] -def test_add_axis_on_persons_distributes_roles(simulation_builder, persons, group_entity): +def test_add_axis_on_persons_distributes_roles(persons, group_entity): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { 'housea': {'parents': ['Alicia']}, @@ -136,7 +141,8 @@ def test_add_axis_on_persons_distributes_roles(simulation_builder, persons, grou assert [role.key for role in simulation_builder.get_roles('households')] == ['parent', 'child', 'parent', 'parent', 'child', 'parent'] -def test_add_axis_distributes_memberships(simulation_builder, persons, group_entity): +def test_add_axis_distributes_memberships(persons, group_entity): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { 'housea': {'parents': ['Alicia']}, @@ -148,18 +154,20 @@ def test_add_axis_distributes_memberships(simulation_builder, persons, group_ent assert simulation_builder.get_memberships('households') == [0, 1, 1, 2, 3, 3] -def test_add_perpendicular_axes(simulation_builder, persons): +def test_add_perpendicular_axes(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}}) simulation_builder.register_variable('salary', persons) simulation_builder.register_variable('pension', persons) simulation_builder.add_parallel_axis({'count': 3, 'name': 'salary', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.add_perpendicular_axis({'count': 2, 'name': 'pension', 'min': 0, 'max': 2000, 'period': '2018-11'}) simulation_builder.expand_axes() - assert simulation_builder.get_input('salary', '2018-11') == approx([0, 1500, 3000, 0, 1500, 3000]) - assert simulation_builder.get_input('pension', '2018-11') == approx([0, 0, 0, 2000, 2000, 2000]) + assert simulation_builder.get_input('salary', '2018-11') == pytest.approx([0, 1500, 3000, 0, 1500, 3000]) + assert simulation_builder.get_input('pension', '2018-11') == pytest.approx([0, 0, 0, 2000, 2000, 2000]) -def test_add_perpendicular_axis_on_an_existing_variable_with_input(simulation_builder, persons): +def test_add_perpendicular_axis_on_an_existing_variable_with_input(persons): + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, { 'Alicia': { 'salary': {'2018-11': 1000}, @@ -171,14 +179,14 @@ def test_add_perpendicular_axis_on_an_existing_variable_with_input(simulation_bu simulation_builder.add_parallel_axis({'count': 3, 'name': 'salary', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.add_perpendicular_axis({'count': 2, 'name': 'pension', 'min': 0, 'max': 2000, 'period': '2018-11'}) simulation_builder.expand_axes() - assert simulation_builder.get_input('salary', '2018-11') == approx([0, 1500, 3000, 0, 1500, 3000]) - assert simulation_builder.get_input('pension', '2018-11') == approx([0, 0, 0, 2000, 2000, 2000]) + assert simulation_builder.get_input('salary', '2018-11') == pytest.approx([0, 1500, 3000, 0, 1500, 3000]) + assert simulation_builder.get_input('pension', '2018-11') == pytest.approx([0, 0, 0, 2000, 2000, 2000]) + # Integration test -def test_simulation_with_axes(simulation_builder): - from .test_countries import tax_benefit_system +def test_simulation_with_axes(tax_benefit_system): input_yaml = """ persons: Alicia: {salary: {2018-11: 0}} @@ -197,7 +205,7 @@ def test_simulation_with_axes(simulation_builder): max: 3000 period: 2018-11 """ - data = yaml.safe_load(input_yaml) - simulation = simulation_builder.build_from_dict(tax_benefit_system, data) - assert simulation.get_array('salary', '2018-11') == approx([0, 0, 0, 0, 0, 0]) - assert simulation.get_array('rent', '2018-11') == approx([0, 0, 3000, 0]) + data = test_runner.yaml.safe_load(input_yaml) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, data) + assert simulation.get_array('salary', '2018-11') == pytest.approx([0, 0, 0, 0, 0, 0]) + assert simulation.get_array('rent', '2018-11') == pytest.approx([0, 0, 3000, 0]) diff --git a/tests/core/tools/test_assert_near.py b/tests/core/tools/test_assert_near.py index 597e3d612b..eecf9d1d1f 100644 --- a/tests/core/tools/test_assert_near.py +++ b/tests/core/tools/test_assert_near.py @@ -1,23 +1,20 @@ - import numpy as np from openfisca_core.tools import assert_near -from ..test_countries import tax_benefit_system - def test_date(): assert_near(np.array("2012-03-24", dtype = 'datetime64[D]'), "2012-03-24") -def test_enum(): +def test_enum(tax_benefit_system): possible_values = tax_benefit_system.variables['housing_occupancy_status'].possible_values value = possible_values.encode(np.array(['tenant'])) expected_value = 'tenant' assert_near(value, expected_value) -def test_enum_2(): +def test_enum_2(tax_benefit_system): possible_values = tax_benefit_system.variables['housing_occupancy_status'].possible_values value = possible_values.encode(np.array(['tenant', 'owner'])) expected_value = ['tenant', 'owner'] From 88d5a6a6d7cb32f6bc3aa0bef6cdc4aa06d65ccf Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Sat, 10 Apr 2021 01:17:25 +0200 Subject: [PATCH 11/22] Fix calculate output tests --- tests/core/test_calculate_output.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/tests/core/test_calculate_output.py b/tests/core/test_calculate_output.py index 63959155d2..a982da0c52 100644 --- a/tests/core/test_calculate_output.py +++ b/tests/core/test_calculate_output.py @@ -1,19 +1,12 @@ from openfisca_core.model_api import * # noqa analysis:ignore -from openfisca_core.simulation_builder import SimulationBuilder from openfisca_core.tools import assert_near -from openfisca_country_template import CountryTaxBenefitSystem from openfisca_country_template.entities import * # noqa analysis:ignore from openfisca_country_template.situation_examples import single from pytest import fixture, raises -@fixture -def simulation(): - return SimulationBuilder().build_from_entities(tax_benefit_system, single) - - class simple_variable(Variable): entity = Person definition_period = MONTH @@ -34,12 +27,18 @@ class variable_with_calculate_output_divide(Variable): calculate_output = calculate_output_divide -tax_benefit_system = CountryTaxBenefitSystem() -tax_benefit_system.add_variables( - simple_variable, - variable_with_calculate_output_add, - variable_with_calculate_output_divide - ) +@fixture(scope = "module", autouse = True) +def add_variables_to_tax_benefit_system(tax_benefit_system): + tax_benefit_system.add_variables( + simple_variable, + variable_with_calculate_output_add, + variable_with_calculate_output_divide + ) + + +@fixture +def simulation(simulation_builder, tax_benefit_system): + return simulation_builder.build_from_entities(tax_benefit_system, single) def test_calculate_output_default(simulation): From 69398539c7080cb8797d3e438d5a0811eadafa4d Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Sat, 10 Apr 2021 01:20:33 +0200 Subject: [PATCH 12/22] Fix cycle tests --- tests/core/test_cycles.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/core/test_cycles.py b/tests/core/test_cycles.py index 949df40336..3ba0830a8b 100644 --- a/tests/core/test_cycles.py +++ b/tests/core/test_cycles.py @@ -1,12 +1,8 @@ -# -*- coding: utf-8 -*- - from openfisca_core import periods from openfisca_core.periods import MONTH -from openfisca_core.simulation_builder import SimulationBuilder from openfisca_core.simulations import CycleError from openfisca_core.variables import Variable -from openfisca_country_template import CountryTaxBenefitSystem from openfisca_country_template.entities import Person from openfisca_core.tools import assert_near @@ -19,8 +15,8 @@ def reference_period(): @fixture -def simulation(reference_period): - return SimulationBuilder().build_default_simulation(tax_benefit_system) +def simulation(simulation_builder, tax_benefit_system): + return simulation_builder.build_default_simulation(tax_benefit_system) # 1 <--> 2 with same period @@ -106,10 +102,18 @@ def formula(person, period): return person.empty_array() + 1 -# TaxBenefitSystem instance declared after formulas -tax_benefit_system = CountryTaxBenefitSystem() -tax_benefit_system.add_variables(variable1, variable2, variable3, variable4, - variable5, variable6, variable7, cotisation) +@fixture(scope = "module", autouse = True) +def add_variables_to_tax_benefit_system(tax_benefit_system): + tax_benefit_system.add_variables( + variable1, + variable2, + variable3, + variable4, + variable5, + variable6, + variable7, + cotisation, + ) def test_pure_cycle(simulation, reference_period): From 23a27b1dcf5f95694e929255877b6c187775bb5c Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Sat, 10 Apr 2021 01:22:33 +0200 Subject: [PATCH 13/22] Fix extension tests --- tests/core/test_extensions.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tests/core/test_extensions.py b/tests/core/test_extensions.py index 864adf606e..5c3da81d66 100644 --- a/tests/core/test_extensions.py +++ b/tests/core/test_extensions.py @@ -1,29 +1,24 @@ import pytest -from openfisca_country_template import CountryTaxBenefitSystem - -original_tbs = CountryTaxBenefitSystem() - - -def test_load_extension(): - tbs = original_tbs.clone() +def test_load_extension(tax_benefit_system): + tbs = tax_benefit_system.clone() assert tbs.get_variable('local_town_child_allowance') is None tbs.load_extension('openfisca_extension_template') assert tbs.get_variable('local_town_child_allowance') is not None - assert original_tbs.get_variable('local_town_child_allowance') is None + assert tax_benefit_system.get_variable('local_town_child_allowance') is None -def test_access_to_parameters(): - tbs = original_tbs.clone() +def test_access_to_parameters(tax_benefit_system): + tbs = tax_benefit_system.clone() tbs.load_extension('openfisca_extension_template') assert tbs.parameters('2016-01').local_town.child_allowance.amount == 100.0 assert tbs.parameters.local_town.child_allowance.amount('2016-01') == 100.0 -def test_failure_to_load_extension_when_directory_doesnt_exist(): +def test_failure_to_load_extension_when_directory_doesnt_exist(tax_benefit_system): with pytest.raises(ValueError): - original_tbs.load_extension('/this/is/not/a/real/path') + tax_benefit_system.load_extension('/this/is/not/a/real/path') From 8adfb743205447967398f06a90ed93a62f53e8bc Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Sat, 10 Apr 2021 01:25:47 +0200 Subject: [PATCH 14/22] Fix formula tests --- tests/core/test_formulas.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/core/test_formulas.py b/tests/core/test_formulas.py index 19dd6bbf4e..1b92b2e3be 100644 --- a/tests/core/test_formulas.py +++ b/tests/core/test_formulas.py @@ -1,13 +1,8 @@ -# -*- coding: utf-8 -*- - - import numpy as np from openfisca_core.periods import MONTH -from openfisca_core.simulation_builder import SimulationBuilder from openfisca_core.variables import Variable from openfisca_core.formula_helpers import switch -from openfisca_country_template import CountryTaxBenefitSystem from openfisca_country_template.entities import Person from pytest import fixture, approx @@ -59,9 +54,9 @@ def formula(person, period): return result -# TaxBenefitSystem instance declared after formulas -our_tbs = CountryTaxBenefitSystem() -our_tbs.add_variables(choice, uses_multiplication, uses_switch, returns_scalar) +@fixture(scope = "module", autouse = True) +def add_variables_to_tax_benefit_system(tax_benefit_system): + tax_benefit_system.add_variables(choice, uses_multiplication, uses_switch, returns_scalar) @fixture @@ -70,10 +65,9 @@ def month(): @fixture -def simulation(month): - builder = SimulationBuilder() - builder.default_period = month - simulation = builder.build_from_variables(our_tbs, {'choice': np.random.randint(2, size = 1000) + 1}) +def simulation(simulation_builder, tax_benefit_system, month): + simulation_builder.default_period = month + simulation = simulation_builder.build_from_variables(tax_benefit_system, {'choice': np.random.randint(2, size = 1000) + 1}) simulation.debug = True return simulation From d1b3e8b584994f2695d529ee3eb0948f58ab1182 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Sat, 10 Apr 2021 01:54:19 +0200 Subject: [PATCH 15/22] Fix opt out cache tests --- tests/core/test_countries.py | 11 ------ tests/core/test_opt_out_cache.py | 66 +++++++++++--------------------- tests/fixtures/simulations.py | 11 ++++++ 3 files changed, 33 insertions(+), 55 deletions(-) diff --git a/tests/core/test_countries.py b/tests/core/test_countries.py index 1b143b178a..46d5cfc42a 100644 --- a/tests/core/test_countries.py +++ b/tests/core/test_countries.py @@ -7,17 +7,6 @@ PERIOD = periods.period("2016-01") -@pytest.fixture -def simulation(simulation_builder, tax_benefit_system, request): - variables, period = request.param - simulation_builder.set_default_period(period) - simulation = \ - simulation_builder \ - .build_from_variables(tax_benefit_system, variables) - - return simulation - - @pytest.mark.parametrize("simulation", [({"salary": 2000}, PERIOD)], indirect = True) def test_input_variable(simulation): result = simulation.calculate("salary", PERIOD) diff --git a/tests/core/test_opt_out_cache.py b/tests/core/test_opt_out_cache.py index 1b76287264..b4eab3e5a5 100644 --- a/tests/core/test_opt_out_cache.py +++ b/tests/core/test_opt_out_cache.py @@ -1,26 +1,13 @@ -# -*- coding: utf-8 -*- +import pytest -from pytest import fixture - -from openfisca_core.simulation_builder import SimulationBuilder -from openfisca_country_template import CountryTaxBenefitSystem from openfisca_country_template.entities import Person -from openfisca_core.variables import Variable -from openfisca_core.periods import MONTH - -@fixture -def month(): - return '2016-05' +from openfisca_core import periods +from openfisca_core.periods import MONTH +from openfisca_core.variables import Variable -@fixture -def make_isolated_simulation(month): - def _make_simulation(tbs, data): - builder = SimulationBuilder() - builder.default_period = month - return builder.build_from_variables(tbs, data) - return _make_simulation +PERIOD = periods.period("2016-01") class input(Variable): @@ -50,43 +37,34 @@ def formula(person, period): return person('intermediate', period) -def get_filled_tbs(): - tax_benefit_system = CountryTaxBenefitSystem() +@pytest.fixture(scope = "module", autouse = True) +def add_variables_to_tax_benefit_system(tax_benefit_system): tax_benefit_system.add_variables(input, intermediate, output) - return tax_benefit_system - -# TaxBenefitSystem instance declared after formulas +@pytest.fixture(scope = "module", autouse = True) +def add_variables_to_cache_blakclist(tax_benefit_system): + tax_benefit_system.cache_blacklist = set(['intermediate']) -tax_benefit_system = get_filled_tbs() - - -tax_benefit_system.cache_blacklist = set(['intermediate']) - - -def test_without_cache_opt_out(make_isolated_simulation, month): - simulation = make_isolated_simulation(tax_benefit_system, {'input': 1}) - simulation.calculate('output', period = month) +@pytest.mark.parametrize("simulation", [({'input': 1}, PERIOD)], indirect = True) +def test_without_cache_opt_out(simulation): + simulation.calculate('output', period = PERIOD) intermediate_cache = simulation.persons.get_holder('intermediate') - assert(intermediate_cache.get_array(month) is not None) + assert(intermediate_cache.get_array(PERIOD) is not None) -def test_with_cache_opt_out(make_isolated_simulation, month): - simulation = make_isolated_simulation(tax_benefit_system, {'input': 1}) +@pytest.mark.parametrize("simulation", [({'input': 1}, PERIOD)], indirect = True) +def test_with_cache_opt_out(simulation): simulation.debug = True simulation.opt_out_cache = True - simulation.calculate('output', period = month) + simulation.calculate('output', period = PERIOD) intermediate_cache = simulation.persons.get_holder('intermediate') - assert(intermediate_cache.get_array(month) is None) - - -tax_benefit_system2 = get_filled_tbs() + assert(intermediate_cache.get_array(PERIOD) is None) -def test_with_no_blacklist(make_isolated_simulation, month): - simulation = make_isolated_simulation(tax_benefit_system2, {'input': 1}) - simulation.calculate('output', period = month) +@pytest.mark.parametrize("simulation", [({'input': 1}, PERIOD)], indirect = True) +def test_with_no_blacklist(simulation): + simulation.calculate('output', period = PERIOD) intermediate_cache = simulation.persons.get_holder('intermediate') - assert(intermediate_cache.get_array(month) is not None) + assert(intermediate_cache.get_array(PERIOD) is not None) diff --git a/tests/fixtures/simulations.py b/tests/fixtures/simulations.py index 23f73d2f1f..f598e79c2b 100644 --- a/tests/fixtures/simulations.py +++ b/tests/fixtures/simulations.py @@ -6,3 +6,14 @@ @pytest.fixture def simulation_builder(): return SimulationBuilder() + + +@pytest.fixture +def simulation(simulation_builder, tax_benefit_system, request): + variables, period = request.param + simulation_builder.set_default_period(period) + simulation = \ + simulation_builder \ + .build_from_variables(tax_benefit_system, variables) + + return simulation From 48647f301489374e675b5885c50e933846324a7f Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Sat, 10 Apr 2021 02:18:24 +0200 Subject: [PATCH 16/22] Fix reform tests --- tests/core/test_countries.py | 22 ++++------- tests/core/test_reforms.py | 72 +++++++++++++++-------------------- tests/fixtures/simulations.py | 11 ++++++ 3 files changed, 48 insertions(+), 57 deletions(-) diff --git a/tests/core/test_countries.py b/tests/core/test_countries.py index 46d5cfc42a..430ca04c18 100644 --- a/tests/core/test_countries.py +++ b/tests/core/test_countries.py @@ -91,34 +91,26 @@ def test_input_with_wrong_period(simulation_builder, tax_benefit_system): simulation_builder.build_from_variables(tax_benefit_system, variables) -def test_variable_with_reference(simulation_builder, isolated_tax_benefit_system): +def test_variable_with_reference(make_simulation, isolated_tax_benefit_system): variables = {"salary": 4000} - simulation_builder.set_default_period(PERIOD) - - simulation = \ - simulation_builder \ - .build_from_variables(isolated_tax_benefit_system, variables) + simulation = make_simulation(isolated_tax_benefit_system, variables, PERIOD) - disposable_income = simulation.calculate("disposable_income", PERIOD) + result = simulation.calculate("disposable_income", PERIOD) - assert disposable_income > 0 + assert result > 0 class disposable_income(Variable): - definition_period = periods.MONTH def formula(household, period): return household.empty_array() isolated_tax_benefit_system.update_variable(disposable_income) + simulation = make_simulation(isolated_tax_benefit_system, variables, PERIOD) - simulation = \ - simulation_builder \ - .build_from_variables(isolated_tax_benefit_system, variables) - - disposable_income = simulation.calculate("disposable_income", PERIOD) + result = simulation.calculate("disposable_income", PERIOD) - assert disposable_income == 0 + assert result == 0 def test_variable_name_conflict(tax_benefit_system): diff --git a/tests/core/test_reforms.py b/tests/core/test_reforms.py index c76739691d..8735cee18f 100644 --- a/tests/core/test_reforms.py +++ b/tests/core/test_reforms.py @@ -1,27 +1,13 @@ -# -*- coding: utf-8 -*- - import warnings -from pytest import fixture, raises +import pytest from openfisca_core import periods from openfisca_core.periods import Instant -from openfisca_core.simulation_builder import SimulationBuilder from openfisca_core.tools import assert_near from openfisca_core.parameters import ValuesHistory, ParameterNode from openfisca_country_template.entities import Household, Person from openfisca_core.model_api import * # noqa analysis:ignore -from openfisca_country_template import CountryTaxBenefitSystem -tax_benefit_system = CountryTaxBenefitSystem() - - -@fixture -def make_simulation(): - def _make_simulation(tbs, period, data): - builder = SimulationBuilder() - builder.default_period = period - return builder.build_from_variables(tbs, data) - return _make_simulation class goes_to_school(Variable): @@ -32,19 +18,21 @@ class goes_to_school(Variable): definition_period = MONTH -tax_benefit_system.add_variable(goes_to_school) - - class WithBasicIncomeNeutralized(Reform): def apply(self): self.neutralize_variable('basic_income') -def test_formula_neutralization(make_simulation): +@pytest.fixture(scope = "module", autouse = True) +def add_variables_to_tax_benefit_system(tax_benefit_system): + tax_benefit_system.add_variables(goes_to_school) + + +def test_formula_neutralization(make_simulation, tax_benefit_system): reform = WithBasicIncomeNeutralized(tax_benefit_system) period = '2017-01' - simulation = make_simulation(reform.base_tax_benefit_system, period, {}) + simulation = make_simulation(reform.base_tax_benefit_system, {}, period) simulation.debug = True basic_income = simulation.calculate('basic_income', period = period) @@ -52,7 +40,7 @@ def test_formula_neutralization(make_simulation): disposable_income = simulation.calculate('disposable_income', period = period) assert disposable_income > 0 - reform_simulation = make_simulation(reform, period, {}) + reform_simulation = make_simulation(reform, {}, period) reform_simulation.debug = True basic_income_reform = reform_simulation.calculate('basic_income', period = '2013-01') @@ -61,7 +49,7 @@ def test_formula_neutralization(make_simulation): assert_near(disposable_income_reform, 0) -def test_neutralization_variable_with_default_value(make_simulation): +def test_neutralization_variable_with_default_value(make_simulation, tax_benefit_system): class test_goes_to_school_neutralization(Reform): def apply(self): self.neutralize_variable('goes_to_school') @@ -69,17 +57,17 @@ def apply(self): reform = test_goes_to_school_neutralization(tax_benefit_system) period = "2017-01" - simulation = make_simulation(reform.base_tax_benefit_system, period, {}) + simulation = make_simulation(reform.base_tax_benefit_system, {}, period) goes_to_school = simulation.calculate('goes_to_school', period) assert_near(goes_to_school, [True], absolute_error_margin = 0) -def test_neutralization_optimization(make_simulation): +def test_neutralization_optimization(make_simulation, tax_benefit_system): reform = WithBasicIncomeNeutralized(tax_benefit_system) period = '2017-01' - simulation = make_simulation(reform, period, {}) + simulation = make_simulation(reform, {}, period) simulation.debug = True simulation.calculate('basic_income', period = '2013-01') @@ -90,7 +78,7 @@ def test_neutralization_optimization(make_simulation): assert basic_income_holder.get_known_periods() == [] -def test_input_variable_neutralization(make_simulation): +def test_input_variable_neutralization(make_simulation, tax_benefit_system): class test_salary_neutralization(Reform): def apply(self): @@ -103,7 +91,7 @@ def apply(self): reform = test_salary_neutralization(tax_benefit_system) with warnings.catch_warnings(record=True) as raised_warnings: - reform_simulation = make_simulation(reform, period, {'salary': [1200, 1000]}) + reform_simulation = make_simulation(reform, {'salary': [1200, 1000]}, period) assert 'You cannot set a value for the variable' in raised_warnings[0].message.args[0] salary = reform_simulation.calculate('salary', period) assert_near(salary, [0, 0],) @@ -111,7 +99,7 @@ def apply(self): assert_near(disposable_income_reform, [600, 600]) -def test_permanent_variable_neutralization(make_simulation): +def test_permanent_variable_neutralization(make_simulation, tax_benefit_system): class test_date_naissance_neutralization(Reform): def apply(self): @@ -120,9 +108,9 @@ def apply(self): reform = test_date_naissance_neutralization(tax_benefit_system) period = '2017-01' - simulation = make_simulation(reform.base_tax_benefit_system, period, {'birth': '1980-01-01'}) + simulation = make_simulation(reform.base_tax_benefit_system, {'birth': '1980-01-01'}, period) with warnings.catch_warnings(record=True) as raised_warnings: - reform_simulation = make_simulation(reform, period, {'birth': '1980-01-01'}) + reform_simulation = make_simulation(reform, {'birth': '1980-01-01'}, period) assert 'You cannot set a value for the variable' in raised_warnings[0].message.args[0] assert str(simulation.calculate('birth', None)[0]) == '1980-01-01' assert str(reform_simulation.calculate('birth', None)[0]) == '1970-01-01' @@ -223,7 +211,7 @@ def check_update_items(description, value_history, start_instant, stop_instant, ) -def test_add_variable(make_simulation): +def test_add_variable(make_simulation, tax_benefit_system): class new_variable(Variable): value_type = int label = "Nouvelle variable introduite par la réforme" @@ -241,13 +229,13 @@ def apply(self): reform = test_add_variable(tax_benefit_system) assert tax_benefit_system.get_variable('new_variable') is None - reform_simulation = make_simulation(reform, 2013, {}) + reform_simulation = make_simulation(reform, {}, 2013) reform_simulation.debug = True new_variable1 = reform_simulation.calculate('new_variable', period = '2013-01') assert_near(new_variable1, 10, absolute_error_margin = 0) -def test_add_dated_variable(make_simulation): +def test_add_dated_variable(make_simulation, tax_benefit_system): class new_dated_variable(Variable): value_type = int label = "Nouvelle variable introduite par la réforme" @@ -266,13 +254,13 @@ def apply(self): reform = test_add_variable(tax_benefit_system) - reform_simulation = make_simulation(reform, period, {}) + reform_simulation = make_simulation(reform, {}, '2013-01') reform_simulation.debug = True new_dated_variable1 = reform_simulation.calculate('new_dated_variable', period = '2013-01') assert_near(new_dated_variable1, 15, absolute_error_margin = 0) -def test_update_variable(make_simulation): +def test_update_variable(make_simulation, tax_benefit_system): class disposable_income(Variable): definition_period = MONTH @@ -294,7 +282,7 @@ def apply(self): assert disposable_income_reform.name == disposable_income_baseline.name assert disposable_income_reform.label == disposable_income_baseline.label - reform_simulation = make_simulation(reform, 2018, {}) + reform_simulation = make_simulation(reform, {}, 2018) disposable_income1 = reform_simulation.calculate('disposable_income', period = '2018-01') assert_near(disposable_income1, 10, absolute_error_margin = 0) @@ -303,7 +291,7 @@ def apply(self): assert(disposable_income2 > 100) -def test_replace_variable(): +def test_replace_variable(tax_benefit_system): class disposable_income(Variable): definition_period = MONTH @@ -324,16 +312,16 @@ def apply(self): assert disposable_income_reform.get_formula('2017') is None -def test_wrong_reform(): +def test_wrong_reform(tax_benefit_system): class wrong_reform(Reform): # A Reform must implement an `apply` method pass - with raises(Exception): + with pytest.raises(Exception): wrong_reform(tax_benefit_system) -def test_modify_parameters(): +def test_modify_parameters(tax_benefit_system): def modify_parameters(reference_parameters): reform_parameters_subtree = ParameterNode( @@ -361,7 +349,7 @@ def apply(self): assert parameters_at_instant.new_node.new_param is True -def test_attributes_conservation(): +def test_attributes_conservation(tax_benefit_system): class some_variable(Variable): value_type = int @@ -391,7 +379,7 @@ def apply(self): assert reform_variable.calculate_output == baseline_variable.calculate_output -def test_formulas_removal(): +def test_formulas_removal(tax_benefit_system): class reform(Reform): def apply(self): diff --git a/tests/fixtures/simulations.py b/tests/fixtures/simulations.py index f598e79c2b..0d8c8b2829 100644 --- a/tests/fixtures/simulations.py +++ b/tests/fixtures/simulations.py @@ -1,3 +1,5 @@ +import functools + import pytest from openfisca_core.simulation_builder import SimulationBuilder @@ -11,6 +13,15 @@ def simulation_builder(): @pytest.fixture def simulation(simulation_builder, tax_benefit_system, request): variables, period = request.param + return _simulation(simulation_builder, tax_benefit_system, variables, period) + + +@pytest.fixture +def make_simulation(simulation_builder): + return functools.partial(_simulation, simulation_builder) + + +def _simulation(simulation_builder, tax_benefit_system, variables, period): simulation_builder.set_default_period(period) simulation = \ simulation_builder \ From c000963f65b8b1b578c2ae3d4c965d9d0f317192 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Mon, 12 Apr 2021 11:54:22 +0200 Subject: [PATCH 17/22] Do not use deprecated SimulationBuilder module Co-authored-by: Ram Parameswaran <33742989+RamParameswaran@users.noreply.github.com> --- tests/fixtures/simulations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixtures/simulations.py b/tests/fixtures/simulations.py index 0d8c8b2829..fec8403959 100644 --- a/tests/fixtures/simulations.py +++ b/tests/fixtures/simulations.py @@ -2,7 +2,7 @@ import pytest -from openfisca_core.simulation_builder import SimulationBuilder +from openfisca_core.simulations.simulation_builder import SimulationBuilder @pytest.fixture From 4b2aca9b055119a52d0f0a68ebcb2be39e7c9087 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Wed, 14 Apr 2021 00:00:48 +0200 Subject: [PATCH 18/22] Apply import styles consistently --- conftest.py | 1 + tests/core/test_axes.py | 28 ++--- tests/core/test_calculate_output.py | 37 +++--- tests/core/test_cycles.py | 62 +++++----- tests/core/test_dump_restore.py | 29 ++--- tests/core/test_entities.py | 155 ++++++++++++------------ tests/core/test_simulation_builder.py | 164 +++++++++----------------- tests/fixtures/entities.py | 44 +++++++ tests/fixtures/variables.py | 11 ++ 9 files changed, 266 insertions(+), 265 deletions(-) create mode 100644 tests/fixtures/entities.py create mode 100644 tests/fixtures/variables.py diff --git a/conftest.py b/conftest.py index 6144b5a847..ae14b71c8a 100644 --- a/conftest.py +++ b/conftest.py @@ -1,4 +1,5 @@ pytest_plugins = [ + "tests.fixtures.entities", "tests.fixtures.simulations", "tests.fixtures.taxbenefitsystems", ] diff --git a/tests/core/test_axes.py b/tests/core/test_axes.py index e4280efaf2..f106a82a5b 100644 --- a/tests/core/test_axes.py +++ b/tests/core/test_axes.py @@ -87,14 +87,14 @@ def test_add_axis_with_group_int_period(persons): assert simulation_builder.get_input('salary', '2018') == pytest.approx([0, 0, 3000, 3000]) -def test_add_axis_on_group_entity(persons, group_entity): +def test_add_axis_on_households(persons, households): simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) - simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { + simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], households, { 'housea': {'parents': ['Alicia', 'Javier']}, 'houseb': {'parents': ['Tom']}, }) - simulation_builder.register_variable('rent', group_entity) + simulation_builder.register_variable('rent', households) simulation_builder.add_parallel_axis({'count': 2, 'name': 'rent', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.expand_axes() assert simulation_builder.get_count('households') == 4 @@ -102,36 +102,36 @@ def test_add_axis_on_group_entity(persons, group_entity): assert simulation_builder.get_input('rent', '2018-11') == pytest.approx([0, 0, 3000, 0]) -def test_axis_on_group_expands_persons(persons, group_entity): +def test_axis_on_group_expands_persons(persons, households): simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) - simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { + simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], households, { 'housea': {'parents': ['Alicia', 'Javier']}, 'houseb': {'parents': ['Tom']}, }) - simulation_builder.register_variable('rent', group_entity) + simulation_builder.register_variable('rent', households) simulation_builder.add_parallel_axis({'count': 2, 'name': 'rent', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.expand_axes() assert simulation_builder.get_count('persons') == 6 -def test_add_axis_distributes_roles(persons, group_entity): +def test_add_axis_distributes_roles(persons, households): simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) - simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { + simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], households, { 'housea': {'parents': ['Alicia']}, 'houseb': {'parents': ['Tom'], 'children': ['Javier']}, }) - simulation_builder.register_variable('rent', group_entity) + simulation_builder.register_variable('rent', households) simulation_builder.add_parallel_axis({'count': 2, 'name': 'rent', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.expand_axes() assert [role.key for role in simulation_builder.get_roles('households')] == ['parent', 'child', 'parent', 'parent', 'child', 'parent'] -def test_add_axis_on_persons_distributes_roles(persons, group_entity): +def test_add_axis_on_persons_distributes_roles(persons, households): simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) - simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { + simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], households, { 'housea': {'parents': ['Alicia']}, 'houseb': {'parents': ['Tom'], 'children': ['Javier']}, }) @@ -141,14 +141,14 @@ def test_add_axis_on_persons_distributes_roles(persons, group_entity): assert [role.key for role in simulation_builder.get_roles('households')] == ['parent', 'child', 'parent', 'parent', 'child', 'parent'] -def test_add_axis_distributes_memberships(persons, group_entity): +def test_add_axis_distributes_memberships(persons, households): simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, {'Alicia': {}, 'Javier': {}, 'Tom': {}}) - simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], group_entity, { + simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Tom'], households, { 'housea': {'parents': ['Alicia']}, 'houseb': {'parents': ['Tom'], 'children': ['Javier']}, }) - simulation_builder.register_variable('rent', group_entity) + simulation_builder.register_variable('rent', households) simulation_builder.add_parallel_axis({'count': 2, 'name': 'rent', 'min': 0, 'max': 3000, 'period': '2018-11'}) simulation_builder.expand_axes() assert simulation_builder.get_memberships('households') == [0, 1, 1, 2, 3, 3] diff --git a/tests/core/test_calculate_output.py b/tests/core/test_calculate_output.py index a982da0c52..5e738400ae 100644 --- a/tests/core/test_calculate_output.py +++ b/tests/core/test_calculate_output.py @@ -1,33 +1,32 @@ -from openfisca_core.model_api import * # noqa analysis:ignore -from openfisca_core.tools import assert_near +import pytest -from openfisca_country_template.entities import * # noqa analysis:ignore -from openfisca_country_template.situation_examples import single +from openfisca_country_template import entities, situation_examples -from pytest import fixture, raises +from openfisca_core import periods, simulations, tools +from openfisca_core.variables import Variable class simple_variable(Variable): - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH value_type = int class variable_with_calculate_output_add(Variable): - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH value_type = int - calculate_output = calculate_output_add + calculate_output = simulations.calculate_output_add class variable_with_calculate_output_divide(Variable): - entity = Person - definition_period = YEAR + entity = entities.Person + definition_period = periods.YEAR value_type = int - calculate_output = calculate_output_divide + calculate_output = simulations.calculate_output_divide -@fixture(scope = "module", autouse = True) +@pytest.fixture(scope = "module", autouse = True) def add_variables_to_tax_benefit_system(tax_benefit_system): tax_benefit_system.add_variables( simple_variable, @@ -36,13 +35,13 @@ def add_variables_to_tax_benefit_system(tax_benefit_system): ) -@fixture +@pytest.fixture def simulation(simulation_builder, tax_benefit_system): - return simulation_builder.build_from_entities(tax_benefit_system, single) + return simulation_builder.build_from_entities(tax_benefit_system, situation_examples.single) def test_calculate_output_default(simulation): - with raises(ValueError): + with pytest.raises(ValueError): simulation.calculate_output('simple_variable', 2017) @@ -50,9 +49,9 @@ def test_calculate_output_add(simulation): simulation.set_input('variable_with_calculate_output_add', '2017-01', [10]) simulation.set_input('variable_with_calculate_output_add', '2017-05', [20]) simulation.set_input('variable_with_calculate_output_add', '2017-12', [70]) - assert_near(simulation.calculate_output('variable_with_calculate_output_add', 2017), 100) + tools.assert_near(simulation.calculate_output('variable_with_calculate_output_add', 2017), 100) def test_calculate_output_divide(simulation): simulation.set_input('variable_with_calculate_output_divide', 2017, [12000]) - assert_near(simulation.calculate_output('variable_with_calculate_output_divide', '2017-06'), 1000) + tools.assert_near(simulation.calculate_output('variable_with_calculate_output_divide', '2017-06'), 1000) diff --git a/tests/core/test_cycles.py b/tests/core/test_cycles.py index 3ba0830a8b..47390dc5e0 100644 --- a/tests/core/test_cycles.py +++ b/tests/core/test_cycles.py @@ -1,20 +1,18 @@ -from openfisca_core import periods -from openfisca_core.periods import MONTH -from openfisca_core.simulations import CycleError -from openfisca_core.variables import Variable +import pytest -from openfisca_country_template.entities import Person -from openfisca_core.tools import assert_near +from openfisca_country_template import entities -from pytest import fixture, raises +from openfisca_core import periods, tools +from openfisca_core.errors import CycleError +from openfisca_core.variables import Variable -@fixture +@pytest.fixture def reference_period(): return periods.period('2013-01') -@fixture +@pytest.fixture def simulation(simulation_builder, tax_benefit_system): return simulation_builder.build_default_simulation(tax_benefit_system) @@ -22,8 +20,8 @@ def simulation(simulation_builder, tax_benefit_system): # 1 <--> 2 with same period class variable1(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): return person('variable2', period) @@ -31,8 +29,8 @@ def formula(person, period): class variable2(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): return person('variable1', period) @@ -41,8 +39,8 @@ def formula(person, period): # 3 <--> 4 with a period offset class variable3(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): return person('variable4', period.last_month) @@ -50,8 +48,8 @@ def formula(person, period): class variable4(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): return person('variable3', period) @@ -61,8 +59,8 @@ def formula(person, period): # <--- class variable5(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): variable6 = person('variable6', period.last_month) @@ -71,8 +69,8 @@ def formula(person, period): class variable6(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): variable5 = person('variable5', period) @@ -81,8 +79,8 @@ def formula(person, period): class variable7(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): variable5 = person('variable5', period) @@ -92,8 +90,8 @@ def formula(person, period): # december cotisation depending on november value class cotisation(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH def formula(person, period): if period.start.month == 12: @@ -102,7 +100,7 @@ def formula(person, period): return person.empty_array() + 1 -@fixture(scope = "module", autouse = True) +@pytest.fixture(scope = "module", autouse = True) def add_variables_to_tax_benefit_system(tax_benefit_system): tax_benefit_system.add_variables( variable1, @@ -117,22 +115,22 @@ def add_variables_to_tax_benefit_system(tax_benefit_system): def test_pure_cycle(simulation, reference_period): - with raises(CycleError): + with pytest.raises(CycleError): simulation.calculate('variable1', period = reference_period) def test_spirals_result_in_default_value(simulation, reference_period): variable3 = simulation.calculate('variable3', period = reference_period) - assert_near(variable3, [0]) + tools.assert_near(variable3, [0]) def test_spiral_heuristic(simulation, reference_period): variable5 = simulation.calculate('variable5', period = reference_period) variable6 = simulation.calculate('variable6', period = reference_period) variable6_last_month = simulation.calculate('variable6', reference_period.last_month) - assert_near(variable5, [11]) - assert_near(variable6, [11]) - assert_near(variable6_last_month, [11]) + tools.assert_near(variable5, [11]) + tools.assert_near(variable6, [11]) + tools.assert_near(variable6_last_month, [11]) def test_spiral_cache(simulation, reference_period): @@ -144,4 +142,4 @@ def test_spiral_cache(simulation, reference_period): def test_cotisation_1_level(simulation, reference_period): month = reference_period.last_month cotisation = simulation.calculate('cotisation', period = month) - assert_near(cotisation, [0]) + tools.assert_near(cotisation, [0]) diff --git a/tests/core/test_dump_restore.py b/tests/core/test_dump_restore.py index cbb065b07b..2d426e156f 100644 --- a/tests/core/test_dump_restore.py +++ b/tests/core/test_dump_restore.py @@ -1,35 +1,36 @@ import shutil import tempfile -from numpy.testing import assert_array_equal +from numpy import testing -from openfisca_country_template.situation_examples import couple -from openfisca_core.tools.simulation_dumper import dump_simulation, restore_simulation +from openfisca_country_template import situation_examples + +from openfisca_core.tools import simulation_dumper def test_dump(simulation_builder, tax_benefit_system): directory = tempfile.mkdtemp(prefix = "openfisca_") - simulation = simulation_builder.build_from_entities(tax_benefit_system, couple) + simulation = simulation_builder.build_from_entities(tax_benefit_system, situation_examples.couple) calculated_value = simulation.calculate('disposable_income', '2018-01') - dump_simulation(simulation, directory) + simulation_dumper.dump_simulation(simulation, directory) - simulation_2 = restore_simulation(directory, tax_benefit_system) + simulation_2 = simulation_dumper.restore_simulation(directory, tax_benefit_system) # Check entities structure have been restored - assert_array_equal(simulation.person.ids, simulation_2.person.ids) - assert_array_equal(simulation.person.count, simulation_2.person.count) - assert_array_equal(simulation.household.ids, simulation_2.household.ids) - assert_array_equal(simulation.household.count, simulation_2.household.count) - assert_array_equal(simulation.household.members_position, simulation_2.household.members_position) - assert_array_equal(simulation.household.members_entity_id, simulation_2.household.members_entity_id) - assert_array_equal(simulation.household.members_role, simulation_2.household.members_role) + testing.assert_array_equal(simulation.person.ids, simulation_2.person.ids) + testing.assert_array_equal(simulation.person.count, simulation_2.person.count) + testing.assert_array_equal(simulation.household.ids, simulation_2.household.ids) + testing.assert_array_equal(simulation.household.count, simulation_2.household.count) + testing.assert_array_equal(simulation.household.members_position, simulation_2.household.members_position) + testing.assert_array_equal(simulation.household.members_entity_id, simulation_2.household.members_entity_id) + testing.assert_array_equal(simulation.household.members_role, simulation_2.household.members_role) # Check calculated values are in cache disposable_income_holder = simulation_2.person.get_holder('disposable_income') cached_value = disposable_income_holder.get_array('2018-01') assert cached_value is not None - assert_array_equal(cached_value, calculated_value) + testing.assert_array_equal(cached_value, calculated_value) shutil.rmtree(directory) diff --git a/tests/core/test_entities.py b/tests/core/test_entities.py index d1893e2fbc..d3027dc9c7 100644 --- a/tests/core/test_entities.py +++ b/tests/core/test_entities.py @@ -1,10 +1,9 @@ from copy import deepcopy -from openfisca_core.tools import assert_near -from openfisca_core.tools.test_runner import yaml -from openfisca_country_template.entities import Household -from openfisca_country_template.situation_examples import single, couple +from openfisca_country_template import entities, situation_examples +from openfisca_core import tools +from openfisca_core.tools import test_runner TEST_CASE = { 'persons': {'ind0': {}, 'ind1': {}, 'ind2': {}, 'ind3': {}, 'ind4': {}, 'ind5': {}}, @@ -19,10 +18,10 @@ for (individu, age) in zip(TEST_CASE_AGES['persons'].values(), AGES): individu['age'] = age -FIRST_PARENT = Household.FIRST_PARENT -SECOND_PARENT = Household.SECOND_PARENT -PARENT = Household.PARENT -CHILD = Household.CHILD +FIRST_PARENT = entities.Household.FIRST_PARENT +SECOND_PARENT = entities.Household.SECOND_PARENT +PARENT = entities.Household.PARENT +CHILD = entities.Household.CHILD YEAR = 2016 MONTH = "2016-01" @@ -35,9 +34,9 @@ def new_simulation(simulation_builder, tax_benefit_system, test_case, period = M def test_role_index_and_positions(simulation_builder, tax_benefit_system): simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) - assert_near(simulation.household.members_entity_id, [0, 0, 0, 0, 1, 1]) + tools.assert_near(simulation.household.members_entity_id, [0, 0, 0, 0, 1, 1]) assert((simulation.household.members_role == [FIRST_PARENT, SECOND_PARENT, CHILD, CHILD, FIRST_PARENT, CHILD]).all()) - assert_near(simulation.household.members_position, [0, 1, 2, 3, 0, 1]) + tools.assert_near(simulation.household.members_position, [0, 1, 2, 3, 0, 1]) assert(simulation.person.ids == ["ind0", "ind1", "ind2", "ind3", "ind4", "ind5"]) assert(simulation.household.ids == ['h1', 'h2']) @@ -63,13 +62,13 @@ def test_entity_structure_with_constructor(simulation_builder, tax_benefit_syste - claudia """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) household = simulation.household - assert_near(household.members_entity_id, [0, 0, 1, 0, 0]) + tools.assert_near(household.members_entity_id, [0, 0, 1, 0, 0]) assert((household.members_role == [FIRST_PARENT, SECOND_PARENT, FIRST_PARENT, CHILD, CHILD]).all()) - assert_near(household.members_position, [0, 1, 0, 2, 3]) + tools.assert_near(household.members_position, [0, 1, 0, 2, 3]) def test_entity_variables_with_constructor(simulation_builder, tax_benefit_system): @@ -97,9 +96,9 @@ def test_entity_variables_with_constructor(simulation_builder, tax_benefit_syste 2017-06: 600 """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) household = simulation.household - assert_near(household('rent', "2017-06"), [800, 600]) + tools.assert_near(household('rent', "2017-06"), [800, 600]) def test_person_variable_with_constructor(simulation_builder, tax_benefit_system): @@ -130,10 +129,10 @@ def test_person_variable_with_constructor(simulation_builder, tax_benefit_system - claudia """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) person = simulation.person - assert_near(person('salary', "2017-11"), [1500, 0, 3000, 0, 0]) - assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) + tools.assert_near(person('salary', "2017-11"), [1500, 0, 3000, 0, 0]) + tools.assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) def test_set_input_with_constructor(simulation_builder, tax_benefit_system): @@ -169,24 +168,24 @@ def test_set_input_with_constructor(simulation_builder, tax_benefit_system): - claudia """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(simulation_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) person = simulation.person - assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) - assert_near(person('salary', "2017-10"), [2000, 3000, 1600, 0, 0]) + tools.assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) + tools.assert_near(person('salary', "2017-10"), [2000, 3000, 1600, 0, 0]) def test_has_role(simulation_builder, tax_benefit_system): simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) individu = simulation.persons - assert_near(individu.has_role(CHILD), [False, False, True, True, False, True]) + tools.assert_near(individu.has_role(CHILD), [False, False, True, True, False, True]) def test_has_role_with_subrole(simulation_builder, tax_benefit_system): simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) individu = simulation.persons - assert_near(individu.has_role(PARENT), [True, True, False, False, True, False]) - assert_near(individu.has_role(FIRST_PARENT), [True, False, False, False, True, False]) - assert_near(individu.has_role(SECOND_PARENT), [False, True, False, False, False, False]) + tools.assert_near(individu.has_role(PARENT), [True, True, False, False, True, False]) + tools.assert_near(individu.has_role(FIRST_PARENT), [True, False, False, False, True, False]) + tools.assert_near(individu.has_role(SECOND_PARENT), [False, True, False, False, False, False]) def test_project(simulation_builder, tax_benefit_system): @@ -199,10 +198,10 @@ def test_project(simulation_builder, tax_benefit_system): housing_tax = household('housing_tax', YEAR) projected_housing_tax = household.project(housing_tax) - assert_near(projected_housing_tax, [20000, 20000, 20000, 20000, 0, 0]) + tools.assert_near(projected_housing_tax, [20000, 20000, 20000, 20000, 0, 0]) housing_tax_projected_on_parents = household.project(housing_tax, role = PARENT) - assert_near(housing_tax_projected_on_parents, [20000, 20000, 0, 0, 0, 0]) + tools.assert_near(housing_tax_projected_on_parents, [20000, 20000, 0, 0, 0, 0]) def test_implicit_projection(simulation_builder, tax_benefit_system): @@ -213,7 +212,7 @@ def test_implicit_projection(simulation_builder, tax_benefit_system): individu = simulation.person housing_tax = individu.household('housing_tax', YEAR) - assert_near(housing_tax, [20000, 20000, 20000, 20000, 0, 0]) + tools.assert_near(housing_tax, [20000, 20000, 20000, 20000, 0, 0]) def test_sum(simulation_builder, tax_benefit_system): @@ -229,11 +228,11 @@ def test_sum(simulation_builder, tax_benefit_system): salary = household.members('salary', "2016-01") total_salary_by_household = household.sum(salary) - assert_near(total_salary_by_household, [2500, 3500]) + tools.assert_near(total_salary_by_household, [2500, 3500]) total_salary_parents_by_household = household.sum(salary, role = PARENT) - assert_near(total_salary_parents_by_household, [2500, 3000]) + tools.assert_near(total_salary_parents_by_household, [2500, 3000]) def test_any(simulation_builder, tax_benefit_system): @@ -244,11 +243,11 @@ def test_any(simulation_builder, tax_benefit_system): age = household.members('age', period = MONTH) condition_age = (age <= 18) has_household_member_with_age_inf_18 = household.any(condition_age) - assert_near(has_household_member_with_age_inf_18, [True, False]) + tools.assert_near(has_household_member_with_age_inf_18, [True, False]) condition_age_2 = (age > 18) has_household_CHILD_with_age_sup_18 = household.any(condition_age_2, role = CHILD) - assert_near(has_household_CHILD_with_age_sup_18, [False, True]) + tools.assert_near(has_household_CHILD_with_age_sup_18, [False, True]) def test_all(simulation_builder, tax_benefit_system): @@ -260,10 +259,10 @@ def test_all(simulation_builder, tax_benefit_system): condition_age = (age >= 18) all_persons_age_sup_18 = household.all(condition_age) - assert_near(all_persons_age_sup_18, [False, True]) + tools.assert_near(all_persons_age_sup_18, [False, True]) all_parents_age_sup_18 = household.all(condition_age, role = PARENT) - assert_near(all_parents_age_sup_18, [True, True]) + tools.assert_near(all_parents_age_sup_18, [True, True]) def test_max(simulation_builder, tax_benefit_system): @@ -274,10 +273,10 @@ def test_max(simulation_builder, tax_benefit_system): age = household.members('age', period = MONTH) age_max = household.max(age) - assert_near(age_max, [40, 54]) + tools.assert_near(age_max, [40, 54]) age_max_child = household.max(age, role = CHILD) - assert_near(age_max_child, [9, 20]) + tools.assert_near(age_max_child, [9, 20]) def test_min(simulation_builder, tax_benefit_system): @@ -288,10 +287,10 @@ def test_min(simulation_builder, tax_benefit_system): age = household.members('age', period = MONTH) age_min = household.min(age) - assert_near(age_min, [7, 20]) + tools.assert_near(age_min, [7, 20]) age_min_parents = household.min(age, role = PARENT) - assert_near(age_min_parents, [37, 54]) + tools.assert_near(age_min_parents, [37, 54]) def test_value_nth_person(simulation_builder, tax_benefit_system): @@ -301,16 +300,16 @@ def test_value_nth_person(simulation_builder, tax_benefit_system): array = household.members('age', MONTH) result0 = household.value_nth_person(0, array, default=-1) - assert_near(result0, [40, 54]) + tools.assert_near(result0, [40, 54]) result1 = household.value_nth_person(1, array, default=-1) - assert_near(result1, [37, 20]) + tools.assert_near(result1, [37, 20]) result2 = household.value_nth_person(2, array, default=-1) - assert_near(result2, [7, -1]) + tools.assert_near(result2, [7, -1]) result3 = household.value_nth_person(3, array, default=-1) - assert_near(result3, [9, -1]) + tools.assert_near(result3, [9, -1]) def test_rank(simulation_builder, tax_benefit_system): @@ -320,10 +319,10 @@ def test_rank(simulation_builder, tax_benefit_system): age = person('age', MONTH) # [40, 37, 7, 9, 54, 20] rank = person.get_rank(person.household, age) - assert_near(rank, [3, 2, 0, 1, 1, 0]) + tools.assert_near(rank, [3, 2, 0, 1, 1, 0]) - rank_in_siblings = person.get_rank(person.household, - age, condition = person.has_role(Household.CHILD)) - assert_near(rank_in_siblings, [-1, -1, 1, 0, -1, 0]) + rank_in_siblings = person.get_rank(person.household, - age, condition = person.has_role(entities.Household.CHILD)) + tools.assert_near(rank_in_siblings, [-1, -1, 1, 0, -1, 0]) def test_partner(simulation_builder, tax_benefit_system): @@ -340,7 +339,7 @@ def test_partner(simulation_builder, tax_benefit_system): salary_second_parent = persons.value_from_partner(salary, persons.household, PARENT) - assert_near(salary_second_parent, [1500, 1000, 0, 0, 0, 0]) + tools.assert_near(salary_second_parent, [1500, 1000, 0, 0, 0, 0]) def test_value_from_first_person(simulation_builder, tax_benefit_system): @@ -356,15 +355,15 @@ def test_value_from_first_person(simulation_builder, tax_benefit_system): salaries = household.members('salary', period = MONTH) salary_first_person = household.value_from_first_person(salaries) - assert_near(salary_first_person, [1000, 3000]) + tools.assert_near(salary_first_person, [1000, 3000]) def test_projectors_methods(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_from_dict(tax_benefit_system, couple) + simulation = simulation_builder.build_from_dict(tax_benefit_system, situation_examples.couple) household = simulation.household person = simulation.person - projected_vector = household.first_parent.has_role(Household.FIRST_PARENT) + projected_vector = household.first_parent.has_role(entities.Household.FIRST_PARENT) assert(len(projected_vector) == 1) # Must be of a household dimension salary_i = person.household.members('salary', '2017-01') @@ -395,7 +394,7 @@ def test_sum_following_bug_ipp_1(simulation_builder, tax_benefit_system): eligible_i = household.members('salary', period = MONTH) < 1500 nb_eligibles_by_household = household.sum(eligible_i, role = CHILD) - assert_near(nb_eligibles_by_household, [0, 2]) + tools.assert_near(nb_eligibles_by_household, [0, 2]) def test_sum_following_bug_ipp_2(simulation_builder, tax_benefit_system): @@ -417,11 +416,11 @@ def test_sum_following_bug_ipp_2(simulation_builder, tax_benefit_system): eligible_i = household.members('salary', period = MONTH) < 1500 nb_eligibles_by_household = household.sum(eligible_i, role = CHILD) - assert_near(nb_eligibles_by_household, [2, 0]) + tools.assert_near(nb_eligibles_by_household, [2, 0]) def test_get_memory_usage(simulation_builder, tax_benefit_system): - test_case = deepcopy(single) + test_case = deepcopy(situation_examples.single) test_case["persons"]["Alicia"]["salary"] = {"2017-01": 0} simulation = simulation_builder.build_from_dict(tax_benefit_system, test_case) simulation.calculate('disposable_income', '2017-01') @@ -460,35 +459,35 @@ def test_unordered_persons(simulation_builder, tax_benefit_system): # Aggregation/Projection persons -> entity - assert_near(household.sum(salary), [2520, 3500]) - assert_near(household.max(salary), [1500, 3000]) - assert_near(household.min(salary), [0, 500]) - assert_near(household.all(salary > 0), [False, True]) - assert_near(household.any(salary > 2000), [False, True]) - assert_near(household.first_person('salary', "2016-01"), [0, 3000]) - assert_near(household.first_parent('salary', "2016-01"), [1000, 3000]) - assert_near(household.second_parent('salary', "2016-01"), [1500, 0]) - assert_near(person.value_from_partner(salary, person.household, PARENT), [0, 0, 1000, 0, 0, 1500]) - - assert_near(household.sum(salary, role = PARENT), [2500, 3000]) - assert_near(household.sum(salary, role = CHILD), [20, 500]) - assert_near(household.max(salary, role = PARENT), [1500, 3000]) - assert_near(household.max(salary, role = CHILD), [20, 500]) - assert_near(household.min(salary, role = PARENT), [1000, 3000]) - assert_near(household.min(salary, role = CHILD), [0, 500]) - assert_near(household.all(salary > 0, role = PARENT), [True, True]) - assert_near(household.all(salary > 0, role = CHILD), [False, True]) - assert_near(household.any(salary < 1500, role = PARENT), [True, False]) - assert_near(household.any(salary > 200, role = CHILD), [False, True]) + tools.assert_near(household.sum(salary), [2520, 3500]) + tools.assert_near(household.max(salary), [1500, 3000]) + tools.assert_near(household.min(salary), [0, 500]) + tools.assert_near(household.all(salary > 0), [False, True]) + tools.assert_near(household.any(salary > 2000), [False, True]) + tools.assert_near(household.first_person('salary', "2016-01"), [0, 3000]) + tools.assert_near(household.first_parent('salary', "2016-01"), [1000, 3000]) + tools.assert_near(household.second_parent('salary', "2016-01"), [1500, 0]) + tools.assert_near(person.value_from_partner(salary, person.household, PARENT), [0, 0, 1000, 0, 0, 1500]) + + tools.assert_near(household.sum(salary, role = PARENT), [2500, 3000]) + tools.assert_near(household.sum(salary, role = CHILD), [20, 500]) + tools.assert_near(household.max(salary, role = PARENT), [1500, 3000]) + tools.assert_near(household.max(salary, role = CHILD), [20, 500]) + tools.assert_near(household.min(salary, role = PARENT), [1000, 3000]) + tools.assert_near(household.min(salary, role = CHILD), [0, 500]) + tools.assert_near(household.all(salary > 0, role = PARENT), [True, True]) + tools.assert_near(household.all(salary > 0, role = CHILD), [False, True]) + tools.assert_near(household.any(salary < 1500, role = PARENT), [True, False]) + tools.assert_near(household.any(salary > 200, role = CHILD), [False, True]) # nb_persons - assert_near(household.nb_persons(), [4, 2]) - assert_near(household.nb_persons(role = PARENT), [2, 1]) - assert_near(household.nb_persons(role = CHILD), [2, 1]) + tools.assert_near(household.nb_persons(), [4, 2]) + tools.assert_near(household.nb_persons(role = PARENT), [2, 1]) + tools.assert_near(household.nb_persons(role = CHILD), [2, 1]) # Projection entity -> persons - assert_near(household.project(accommodation_size), [60, 160, 160, 160, 60, 160]) - assert_near(household.project(accommodation_size, role = PARENT), [60, 0, 160, 0, 0, 160]) - assert_near(household.project(accommodation_size, role = CHILD), [0, 160, 0, 160, 60, 0]) + tools.assert_near(household.project(accommodation_size), [60, 160, 160, 160, 60, 160]) + tools.assert_near(household.project(accommodation_size, role = PARENT), [60, 0, 160, 0, 0, 160]) + tools.assert_near(household.project(accommodation_size, role = CHILD), [0, 160, 0, 160, 60, 0]) diff --git a/tests/core/test_simulation_builder.py b/tests/core/test_simulation_builder.py index 864bcdae8a..73d7b57ece 100644 --- a/tests/core/test_simulation_builder.py +++ b/tests/core/test_simulation_builder.py @@ -1,39 +1,24 @@ -# -*- coding: utf-8 -*- - +import datetime from typing import Iterable -from enum import Enum -from datetime import date +import pytest -from pytest import raises, fixture, approx +from openfisca_country_template import entities, situation_examples -from openfisca_core.simulation_builder import Simulation -from openfisca_core.tools import assert_near -from openfisca_core.tools.test_runner import yaml -from openfisca_core.entities import Entity, GroupEntity +from openfisca_core import periods, tools +from openfisca_core.errors import SituationParsingError +from openfisca_core.indexed_enums import Enum from openfisca_core.populations import Population +from openfisca_core.simulations import Simulation +from openfisca_core.tools import test_runner from openfisca_core.variables import Variable -from openfisca_country_template.entities import Household -from openfisca_country_template.situation_examples import couple -from openfisca_core.errors import SituationParsingError -from openfisca_core.periods import ETERNITY -from openfisca_core.indexed_enums import Enum as OFEnum - -class TestVariable(Variable): - definition_period = ETERNITY - value_type = float - def __init__(self, entity): - self.__class__.entity = entity - super().__init__() - - -@fixture +@pytest.fixture def int_variable(persons): class intvar(Variable): - definition_period = ETERNITY + definition_period = periods.ETERNITY value_type = int entity = persons @@ -43,12 +28,12 @@ def __init__(self): return intvar() -@fixture +@pytest.fixture def date_variable(persons): class datevar(Variable): - definition_period = ETERNITY - value_type = date + definition_period = periods.ETERNITY + value_type = datetime.date entity = persons def __init__(self): @@ -57,12 +42,12 @@ def __init__(self): return datevar() -@fixture +@pytest.fixture def enum_variable(): class TestEnum(Variable): - definition_period = ETERNITY - value_type = OFEnum + definition_period = periods.ETERNITY + value_type = Enum dtype = 'O' default_value = '0' is_neutralized = False @@ -76,55 +61,18 @@ def __init__(self): return TestEnum() -@fixture -def persons(): - class TestPersonEntity(Entity): - def get_variable(self, variable_name): - result = TestVariable(self) - result.name = variable_name - return result - - def check_variable_defined_for_entity(self, variable_name): - return True - - return TestPersonEntity("person", "persons", "", "") - - -@fixture -def group_entity(): - class Household(GroupEntity): - def get_variable(self, variable_name): - result = TestVariable(self) - result.name = variable_name - return result - - def check_variable_defined_for_entity(self, variable_name): - return True - - roles = [{ - 'key': 'parent', - 'plural': 'parents', - 'max': 2 - }, { - 'key': 'child', - 'plural': 'children' - }] - - return Household("household", "households", "", "", roles) - - def test_build_default_simulation(simulation_builder, tax_benefit_system): one_person_simulation = simulation_builder.build_default_simulation(tax_benefit_system, 1) assert one_person_simulation.persons.count == 1 assert one_person_simulation.household.count == 1 assert one_person_simulation.household.members_entity_id == [0] - assert one_person_simulation.household.members_role == Household.FIRST_PARENT + assert one_person_simulation.household.members_role == entities.Household.FIRST_PARENT several_persons_simulation = simulation_builder.build_default_simulation(tax_benefit_system, 4) assert several_persons_simulation.persons.count == 4 assert several_persons_simulation.household.count == 4 assert (several_persons_simulation.household.members_entity_id == [0, 1, 2, 3]).all() - assert (several_persons_simulation.household.members_role == Household.FIRST_PARENT).all() + assert (several_persons_simulation.household.members_role == entities.Household.FIRST_PARENT).all() def test_explicit_singular_entities(simulation_builder, tax_benefit_system): @@ -151,25 +99,25 @@ def test_numeric_ids(simulation_builder, persons): def test_add_person_entity_with_values(simulation_builder, persons): persons_json = {'Alicia': {'salary': {'2018-11': 3000}}, 'Javier': {}} simulation_builder.add_person_entity(persons, persons_json) - assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) + tools.assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) def test_add_person_values_with_default_period(simulation_builder, persons): simulation_builder.set_default_period('2018-11') persons_json = {'Alicia': {'salary': 3000}, 'Javier': {}} simulation_builder.add_person_entity(persons, persons_json) - assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) + tools.assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) def test_add_person_values_with_default_period_old_syntax(simulation_builder, persons): simulation_builder.set_default_period('month:2018-11') persons_json = {'Alicia': {'salary': 3000}, 'Javier': {}} simulation_builder.add_person_entity(persons, persons_json) - assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) + tools.assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) -def test_add_group_entity(simulation_builder, group_entity): - simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', 'Tom'], group_entity, { +def test_add_group_entity(simulation_builder, households): + simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', 'Tom'], households, { 'Household_1': {'parents': ['Alicia', 'Javier']}, 'Household_2': {'parents': ['Tom'], 'children': ['Sarah']}, }) @@ -179,8 +127,8 @@ def test_add_group_entity(simulation_builder, group_entity): assert [role.key for role in simulation_builder.get_roles('households')] == ['parent', 'parent', 'child', 'parent'] -def test_add_group_entity_loose_syntax(simulation_builder, group_entity): - simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', '1'], group_entity, { +def test_add_group_entity_loose_syntax(simulation_builder, households): + simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', '1'], households, { 'Household_1': {'parents': ['Alicia', 'Javier']}, 'Household_2': {'parents': 1, 'children': 'Sarah'}, }) @@ -196,7 +144,7 @@ def test_add_variable_value(simulation_builder, persons): simulation_builder.entity_counts['persons'] = 1 simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', 3000) input_array = simulation_builder.get_input('salary', '2018-11') - assert input_array[instance_index] == approx(3000) + assert input_array[instance_index] == pytest.approx(3000) def test_add_variable_value_as_expression(simulation_builder, persons): @@ -205,14 +153,14 @@ def test_add_variable_value_as_expression(simulation_builder, persons): simulation_builder.entity_counts['persons'] = 1 simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', '3 * 1000') input_array = simulation_builder.get_input('salary', '2018-11') - assert input_array[instance_index] == approx(3000) + assert input_array[instance_index] == pytest.approx(3000) def test_fail_on_wrong_data(simulation_builder, persons): salary = persons.get_variable('salary') instance_index = 0 simulation_builder.entity_counts['persons'] = 1 - with raises(SituationParsingError) as excinfo: + with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', 'alicia') assert excinfo.value.error == {'persons': {'Alicia': {'salary': {'2018-11': "Can't deal with value: expected type number, received 'alicia'."}}}} @@ -221,7 +169,7 @@ def test_fail_on_ill_formed_expression(simulation_builder, persons): salary = persons.get_variable('salary') instance_index = 0 simulation_builder.entity_counts['persons'] = 1 - with raises(SituationParsingError) as excinfo: + with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', '2 * / 1000') assert excinfo.value.error == {'persons': {'Alicia': {'salary': {'2018-11': "I couldn't understand '2 * / 1000' as a value for 'salary'"}}}} @@ -229,7 +177,7 @@ def test_fail_on_ill_formed_expression(simulation_builder, persons): def test_fail_on_integer_overflow(simulation_builder, persons, int_variable): instance_index = 0 simulation_builder.entity_counts['persons'] = 1 - with raises(SituationParsingError) as excinfo: + with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, int_variable, instance_index, 'Alicia', '2018-11', 9223372036854775808) assert excinfo.value.error == {'persons': {'Alicia': {'intvar': {'2018-11': "Can't deal with value: '9223372036854775808', it's too large for type 'integer'."}}}} @@ -237,7 +185,7 @@ def test_fail_on_integer_overflow(simulation_builder, persons, int_variable): def test_fail_on_date_parsing(simulation_builder, persons, date_variable): instance_index = 0 simulation_builder.entity_counts['persons'] = 1 - with raises(SituationParsingError) as excinfo: + with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, date_variable, instance_index, 'Alicia', '2018-11', '2019-02-30') assert excinfo.value.error == {'persons': {'Alicia': {'datevar': {'2018-11': "Can't deal with date: '2019-02-30'."}}}} @@ -245,7 +193,7 @@ def test_fail_on_date_parsing(simulation_builder, persons, date_variable): def test_add_unknown_enum_variable_value(simulation_builder, persons, enum_variable): instance_index = 0 simulation_builder.entity_counts['persons'] = 1 - with raises(SituationParsingError): + with pytest.raises(SituationParsingError): simulation_builder.add_variable_value(persons, enum_variable, instance_index, 'Alicia', '2018-11', 'baz') @@ -254,7 +202,7 @@ def test_finalize_person_entity(simulation_builder, persons): simulation_builder.add_person_entity(persons, persons_json) population = Population(persons) simulation_builder.finalize_variables_init(population) - assert_near(population.get_holder('salary').get_array('2018-11'), [3000, 0]) + tools.assert_near(population.get_holder('salary').get_array('2018-11'), [3000, 0]) assert population.count == 2 assert population.ids == ['Alicia', 'Javier'] @@ -264,18 +212,18 @@ def test_canonicalize_period_keys(simulation_builder, persons): simulation_builder.add_person_entity(persons, persons_json) population = Population(persons) simulation_builder.finalize_variables_init(population) - assert_near(population.get_holder('salary').get_array('2018-12'), [100]) + tools.assert_near(population.get_holder('salary').get_array('2018-12'), [100]) -def test_finalize_group_entity(simulation_builder, tax_benefit_system): +def test_finalize_households(simulation_builder, tax_benefit_system): simulation = Simulation(tax_benefit_system, tax_benefit_system.instantiate_entities()) simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', 'Tom'], simulation.household.entity, { 'Household_1': {'parents': ['Alicia', 'Javier']}, 'Household_2': {'parents': ['Tom'], 'children': ['Sarah']}, }) simulation_builder.finalize_variables_init(simulation.household) - assert_near(simulation.household.members_entity_id, [0, 0, 1, 1]) - assert_near(simulation.persons.has_role(Household.PARENT), [True, True, False, True]) + tools.assert_near(simulation.household.members_entity_id, [0, 0, 1, 1]) + tools.assert_near(simulation.persons.has_role(entities.Household.PARENT), [True, True, False, True]) def test_check_persons_to_allocate(simulation_builder): @@ -302,7 +250,7 @@ def test_allocate_undeclared_person(simulation_builder): persons_to_allocate = ['Alicia'] persons_ids = [] index = 0 - with raises(SituationParsingError) as exception: + with pytest.raises(SituationParsingError) as exception: simulation_builder.check_persons_to_allocate( persons_plural, entity_plural, persons_ids, @@ -320,7 +268,7 @@ def test_allocate_person_twice(simulation_builder): persons_to_allocate = [] persons_ids = ['Alicia'] index = 0 - with raises(SituationParsingError) as exception: + with pytest.raises(SituationParsingError) as exception: simulation_builder.check_persons_to_allocate( persons_plural, entity_plural, persons_ids, @@ -333,7 +281,7 @@ def test_one_person_without_household(simulation_builder, tax_benefit_system): simulation_dict = {'persons': {'Alicia': {}}} simulation = simulation_builder.build_from_dict(tax_benefit_system, simulation_dict) assert simulation.household.count == 1 - parents_in_households = simulation.household.nb_persons(role = Household.PARENT) + parents_in_households = simulation.household.nb_persons(role = entities.Household.PARENT) assert parents_in_households.tolist() == [1] # household member default role is first_parent @@ -342,13 +290,13 @@ def test_some_person_without_household(simulation_builder, tax_benefit_system): persons: {'Alicia': {}, 'Bob': {}} household: {'parents': ['Alicia']} """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(input_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert simulation.household.count == 2 - parents_in_households = simulation.household.nb_persons(role = Household.PARENT) + parents_in_households = simulation.household.nb_persons(role = entities.Household.PARENT) assert parents_in_households.tolist() == [1, 1] # household member default role is first_parent -def test_nb_persons_in_group_entity(simulation_builder, tax_benefit_system): +def test_nb_persons_in_households(simulation_builder, tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] @@ -373,7 +321,7 @@ def test_nb_persons_no_role(simulation_builder, tax_benefit_system): household_instance = simulation_builder.declare_entity('household', households_ids) simulation_builder.join_with_persons(household_instance, persons_households, ['first_parent'] * 5) - parents_in_households = household_instance.nb_persons(role = Household.PARENT) + parents_in_households = household_instance.nb_persons(role = entities.Household.PARENT) assert parents_in_households.tolist() == [1, 3, 1] # household member default role is first_parent @@ -393,7 +341,7 @@ def test_nb_persons_by_role(simulation_builder, tax_benefit_system): persons_households, persons_households_roles ) - parents_in_households = household_instance.nb_persons(role = Household.FIRST_PARENT) + parents_in_households = household_instance.nb_persons(role = entities.Household.FIRST_PARENT) assert parents_in_households.tolist() == [0, 1, 1] @@ -414,7 +362,7 @@ def test_integral_roles(simulation_builder, tax_benefit_system): persons_households, persons_households_roles ) - parents_in_households = household_instance.nb_persons(role = Household.FIRST_PARENT) + parents_in_households = household_instance.nb_persons(role = entities.Household.FIRST_PARENT) assert parents_in_households.tolist() == [0, 1, 1] @@ -444,8 +392,8 @@ def test_from_person_variable_to_group(simulation_builder, tax_benefit_system): simulation.set_input('rent', period, households_rents) total_taxes = simulation.calculate('total_taxes', period) - assert total_taxes == approx(households_rents) - assert total_taxes / simulation.calculate('rent', period) == approx(1) + assert total_taxes == pytest.approx(households_rents) + assert total_taxes / simulation.calculate('rent', period) == pytest.approx(1) def test_simulation(simulation_builder, tax_benefit_system): @@ -454,7 +402,7 @@ def test_simulation(simulation_builder, tax_benefit_system): 2016-10: 12000 """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(input_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert simulation.get_array("salary", "2016-10") == 12000 simulation.calculate("income_tax", "2016-10") @@ -467,15 +415,15 @@ def test_vectorial_input(simulation_builder, tax_benefit_system): 2016-10: [12000, 20000] """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(input_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) - assert_near(simulation.get_array("salary", "2016-10"), [12000, 20000]) + tools.assert_near(simulation.get_array("salary", "2016-10"), [12000, 20000]) simulation.calculate("income_tax", "2016-10") simulation.calculate("total_taxes", "2016-10") def test_fully_specified_entities(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_from_dict(tax_benefit_system, couple) + simulation = simulation_builder.build_from_dict(tax_benefit_system, situation_examples.couple) assert simulation.household.count == 1 assert simulation.persons.count == 2 @@ -489,7 +437,7 @@ def test_single_entity_shortcut(simulation_builder, tax_benefit_system): parents: [Alicia, Javier] """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(input_yaml)) + simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert simulation.household.count == 1 @@ -505,7 +453,7 @@ def test_order_preserved(simulation_builder, tax_benefit_system): children: [Tom, Sarah] """ - data = yaml.safe_load(input_yaml) + data = test_runner.yaml.safe_load(input_yaml) simulation = simulation_builder.build_from_dict(tax_benefit_system, data) assert simulation.persons.ids == ['Javier', 'Alicia', 'Sarah', 'Tom'] @@ -518,6 +466,6 @@ def test_inconsistent_input(simulation_builder, tax_benefit_system): income_tax: 2016-10: [100, 200, 300] """ - with raises(ValueError) as error: - simulation_builder.build_from_dict(tax_benefit_system, yaml.safe_load(input_yaml)) + with pytest.raises(ValueError) as error: + simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert "its length is 3 while there are 2" in error.value.args[0] diff --git a/tests/fixtures/entities.py b/tests/fixtures/entities.py new file mode 100644 index 0000000000..99b6196599 --- /dev/null +++ b/tests/fixtures/entities.py @@ -0,0 +1,44 @@ +import pytest + +from openfisca_core.entities import Entity, GroupEntity + +from .variables import TestVariable + + +class TestEntity(Entity): + def get_variable(self, variable_name): + result = TestVariable(self) + result.name = variable_name + return result + + def check_variable_defined_for_entity(self, variable_name): + return True + + +class TestGroupEntity(GroupEntity): + def get_variable(self, variable_name): + result = TestVariable(self) + result.name = variable_name + return result + + def check_variable_defined_for_entity(self, variable_name): + return True + + +@pytest.fixture +def persons(): + return TestEntity("person", "persons", "", "") + + +@pytest.fixture +def households(): + roles = [{ + 'key': 'parent', + 'plural': 'parents', + 'max': 2 + }, { + 'key': 'child', + 'plural': 'children' + }] + + return TestGroupEntity("household", "households", "", "", roles) diff --git a/tests/fixtures/variables.py b/tests/fixtures/variables.py new file mode 100644 index 0000000000..cd0d9b70ce --- /dev/null +++ b/tests/fixtures/variables.py @@ -0,0 +1,11 @@ +from openfisca_core import periods +from openfisca_core.variables import Variable + + +class TestVariable(Variable): + definition_period = periods.ETERNITY + value_type = float + + def __init__(self, entity): + self.__class__.entity = entity + super().__init__() From e5d63760cce12c744f750f70d6160170d8698933 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Wed, 14 Apr 2021 00:36:49 +0200 Subject: [PATCH 19/22] Do not fixture SimulationBuilder --- tests/core/test_calculate_output.py | 5 +- tests/core/test_countries.py | 4 +- tests/core/test_cycles.py | 5 +- tests/core/test_dump_restore.py | 5 +- tests/core/test_entities.py | 96 +++++++++--------- tests/core/test_formulas.py | 42 ++++---- tests/core/test_holders.py | 96 +++++++++--------- tests/core/test_simulation_builder.py | 138 ++++++++++++++++---------- tests/core/test_simulations.py | 18 ++-- tests/fixtures/simulations.py | 21 ++-- 10 files changed, 237 insertions(+), 193 deletions(-) diff --git a/tests/core/test_calculate_output.py b/tests/core/test_calculate_output.py index 5e738400ae..6a11a27d84 100644 --- a/tests/core/test_calculate_output.py +++ b/tests/core/test_calculate_output.py @@ -3,6 +3,7 @@ from openfisca_country_template import entities, situation_examples from openfisca_core import periods, simulations, tools +from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable @@ -36,8 +37,8 @@ def add_variables_to_tax_benefit_system(tax_benefit_system): @pytest.fixture -def simulation(simulation_builder, tax_benefit_system): - return simulation_builder.build_from_entities(tax_benefit_system, situation_examples.single) +def simulation(tax_benefit_system): + return SimulationBuilder().build_from_entities(tax_benefit_system, situation_examples.single) def test_calculate_output_default(simulation): diff --git a/tests/core/test_countries.py b/tests/core/test_countries.py index 430ca04c18..aeb4d762c7 100644 --- a/tests/core/test_countries.py +++ b/tests/core/test_countries.py @@ -2,6 +2,7 @@ from openfisca_core import periods, populations, tools from openfisca_core.errors import VariableNameConflictError, VariableNotFoundError +from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable PERIOD = periods.period("2016-01") @@ -82,9 +83,10 @@ def test_divide_option_with_complex_period(simulation): assert word in error_message, f"Expected '{word}' in error message '{error_message}'" -def test_input_with_wrong_period(simulation_builder, tax_benefit_system): +def test_input_with_wrong_period(tax_benefit_system): year = str(PERIOD.this_year) variables = {"basic_income": {year: 12000}} + simulation_builder = SimulationBuilder() simulation_builder.set_default_period(PERIOD) with pytest.raises(ValueError): diff --git a/tests/core/test_cycles.py b/tests/core/test_cycles.py index 47390dc5e0..1c4361ded2 100644 --- a/tests/core/test_cycles.py +++ b/tests/core/test_cycles.py @@ -4,6 +4,7 @@ from openfisca_core import periods, tools from openfisca_core.errors import CycleError +from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable @@ -13,8 +14,8 @@ def reference_period(): @pytest.fixture -def simulation(simulation_builder, tax_benefit_system): - return simulation_builder.build_default_simulation(tax_benefit_system) +def simulation(tax_benefit_system): + return SimulationBuilder().build_default_simulation(tax_benefit_system) # 1 <--> 2 with same period diff --git a/tests/core/test_dump_restore.py b/tests/core/test_dump_restore.py index 2d426e156f..5d377913c9 100644 --- a/tests/core/test_dump_restore.py +++ b/tests/core/test_dump_restore.py @@ -5,12 +5,13 @@ from openfisca_country_template import situation_examples +from openfisca_core.simulations import SimulationBuilder from openfisca_core.tools import simulation_dumper -def test_dump(simulation_builder, tax_benefit_system): +def test_dump(tax_benefit_system): directory = tempfile.mkdtemp(prefix = "openfisca_") - simulation = simulation_builder.build_from_entities(tax_benefit_system, situation_examples.couple) + simulation = SimulationBuilder().build_from_entities(tax_benefit_system, situation_examples.couple) calculated_value = simulation.calculate('disposable_income', '2018-01') simulation_dumper.dump_simulation(simulation, directory) diff --git a/tests/core/test_entities.py b/tests/core/test_entities.py index d3027dc9c7..b15653b055 100644 --- a/tests/core/test_entities.py +++ b/tests/core/test_entities.py @@ -3,6 +3,7 @@ from openfisca_country_template import entities, situation_examples from openfisca_core import tools +from openfisca_core.simulations import SimulationBuilder from openfisca_core.tools import test_runner TEST_CASE = { @@ -27,13 +28,14 @@ MONTH = "2016-01" -def new_simulation(simulation_builder, tax_benefit_system, test_case, period = MONTH): +def new_simulation(tax_benefit_system, test_case, period = MONTH): + simulation_builder = SimulationBuilder() simulation_builder.set_default_period(period) return simulation_builder.build_from_entities(tax_benefit_system, test_case) -def test_role_index_and_positions(simulation_builder, tax_benefit_system): - simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) +def test_role_index_and_positions(tax_benefit_system): + simulation = new_simulation(tax_benefit_system, TEST_CASE) tools.assert_near(simulation.household.members_entity_id, [0, 0, 0, 0, 1, 1]) assert((simulation.household.members_role == [FIRST_PARENT, SECOND_PARENT, CHILD, CHILD, FIRST_PARENT, CHILD]).all()) tools.assert_near(simulation.household.members_position, [0, 1, 2, 3, 0, 1]) @@ -41,7 +43,7 @@ def test_role_index_and_positions(simulation_builder, tax_benefit_system): assert(simulation.household.ids == ['h1', 'h2']) -def test_entity_structure_with_constructor(simulation_builder, tax_benefit_system): +def test_entity_structure_with_constructor(tax_benefit_system): simulation_yaml = """ persons: bill: {} @@ -62,7 +64,7 @@ def test_entity_structure_with_constructor(simulation_builder, tax_benefit_syste - claudia """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) household = simulation.household @@ -71,7 +73,7 @@ def test_entity_structure_with_constructor(simulation_builder, tax_benefit_syste tools.assert_near(household.members_position, [0, 1, 0, 2, 3]) -def test_entity_variables_with_constructor(simulation_builder, tax_benefit_system): +def test_entity_variables_with_constructor(tax_benefit_system): simulation_yaml = """ persons: bill: {} @@ -96,12 +98,12 @@ def test_entity_variables_with_constructor(simulation_builder, tax_benefit_syste 2017-06: 600 """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) household = simulation.household tools.assert_near(household('rent', "2017-06"), [800, 600]) -def test_person_variable_with_constructor(simulation_builder, tax_benefit_system): +def test_person_variable_with_constructor(tax_benefit_system): simulation_yaml = """ persons: bill: @@ -129,13 +131,13 @@ def test_person_variable_with_constructor(simulation_builder, tax_benefit_system - claudia """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) person = simulation.person tools.assert_near(person('salary', "2017-11"), [1500, 0, 3000, 0, 0]) tools.assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) -def test_set_input_with_constructor(simulation_builder, tax_benefit_system): +def test_set_input_with_constructor(tax_benefit_system): simulation_yaml = """ persons: bill: @@ -168,31 +170,31 @@ def test_set_input_with_constructor(simulation_builder, tax_benefit_system): - claudia """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(simulation_yaml)) person = simulation.person tools.assert_near(person('salary', "2017-12"), [2000, 0, 4000, 0, 0]) tools.assert_near(person('salary', "2017-10"), [2000, 3000, 1600, 0, 0]) -def test_has_role(simulation_builder, tax_benefit_system): - simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) +def test_has_role(tax_benefit_system): + simulation = new_simulation(tax_benefit_system, TEST_CASE) individu = simulation.persons tools.assert_near(individu.has_role(CHILD), [False, False, True, True, False, True]) -def test_has_role_with_subrole(simulation_builder, tax_benefit_system): - simulation = new_simulation(simulation_builder, tax_benefit_system, TEST_CASE) +def test_has_role_with_subrole(tax_benefit_system): + simulation = new_simulation(tax_benefit_system, TEST_CASE) individu = simulation.persons tools.assert_near(individu.has_role(PARENT), [True, True, False, False, True, False]) tools.assert_near(individu.has_role(FIRST_PARENT), [True, False, False, False, True, False]) tools.assert_near(individu.has_role(SECOND_PARENT), [False, True, False, False, False, False]) -def test_project(simulation_builder, tax_benefit_system): +def test_project(tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['households']['h1']['housing_tax'] = 20000 - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, YEAR) + simulation = new_simulation(tax_benefit_system, test_case, YEAR) household = simulation.household housing_tax = household('housing_tax', YEAR) @@ -204,25 +206,25 @@ def test_project(simulation_builder, tax_benefit_system): tools.assert_near(housing_tax_projected_on_parents, [20000, 20000, 0, 0, 0, 0]) -def test_implicit_projection(simulation_builder, tax_benefit_system): +def test_implicit_projection(tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['households']['h1']['housing_tax'] = 20000 - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, YEAR) + simulation = new_simulation(tax_benefit_system, test_case, YEAR) individu = simulation.person housing_tax = individu.household('housing_tax', YEAR) tools.assert_near(housing_tax, [20000, 20000, 20000, 20000, 0, 0]) -def test_sum(simulation_builder, tax_benefit_system): +def test_sum(tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['persons']['ind0']['salary'] = 1000 test_case['persons']['ind1']['salary'] = 1500 test_case['persons']['ind4']['salary'] = 3000 test_case['persons']['ind5']['salary'] = 500 - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, MONTH) + simulation = new_simulation(tax_benefit_system, test_case, MONTH) household = simulation.household salary = household.members('salary', "2016-01") @@ -235,9 +237,9 @@ def test_sum(simulation_builder, tax_benefit_system): tools.assert_near(total_salary_parents_by_household, [2500, 3000]) -def test_any(simulation_builder, tax_benefit_system): +def test_any(tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -250,9 +252,9 @@ def test_any(simulation_builder, tax_benefit_system): tools.assert_near(has_household_CHILD_with_age_sup_18, [False, True]) -def test_all(simulation_builder, tax_benefit_system): +def test_all(tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -265,9 +267,9 @@ def test_all(simulation_builder, tax_benefit_system): tools.assert_near(all_parents_age_sup_18, [True, True]) -def test_max(simulation_builder, tax_benefit_system): +def test_max(tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -279,9 +281,9 @@ def test_max(simulation_builder, tax_benefit_system): tools.assert_near(age_max_child, [9, 20]) -def test_min(simulation_builder, tax_benefit_system): +def test_min(tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household age = household.members('age', period = MONTH) @@ -293,9 +295,9 @@ def test_min(simulation_builder, tax_benefit_system): tools.assert_near(age_min_parents, [37, 54]) -def test_value_nth_person(simulation_builder, tax_benefit_system): +def test_value_nth_person(tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household array = household.members('age', MONTH) @@ -312,9 +314,9 @@ def test_value_nth_person(simulation_builder, tax_benefit_system): tools.assert_near(result3, [9, -1]) -def test_rank(simulation_builder, tax_benefit_system): +def test_rank(tax_benefit_system): test_case = deepcopy(TEST_CASE_AGES) - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) person = simulation.person age = person('age', MONTH) # [40, 37, 7, 9, 54, 20] @@ -325,14 +327,14 @@ def test_rank(simulation_builder, tax_benefit_system): tools.assert_near(rank_in_siblings, [-1, -1, 1, 0, -1, 0]) -def test_partner(simulation_builder, tax_benefit_system): +def test_partner(tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['persons']['ind0']['salary'] = 1000 test_case['persons']['ind1']['salary'] = 1500 test_case['persons']['ind4']['salary'] = 3000 test_case['persons']['ind5']['salary'] = 500 - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) persons = simulation.persons salary = persons('salary', period = MONTH) @@ -342,14 +344,14 @@ def test_partner(simulation_builder, tax_benefit_system): tools.assert_near(salary_second_parent, [1500, 1000, 0, 0, 0, 0]) -def test_value_from_first_person(simulation_builder, tax_benefit_system): +def test_value_from_first_person(tax_benefit_system): test_case = deepcopy(TEST_CASE) test_case['persons']['ind0']['salary'] = 1000 test_case['persons']['ind1']['salary'] = 1500 test_case['persons']['ind4']['salary'] = 3000 test_case['persons']['ind5']['salary'] = 500 - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household salaries = household.members('salary', period = MONTH) @@ -358,8 +360,8 @@ def test_value_from_first_person(simulation_builder, tax_benefit_system): tools.assert_near(salary_first_person, [1000, 3000]) -def test_projectors_methods(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_from_dict(tax_benefit_system, situation_examples.couple) +def test_projectors_methods(tax_benefit_system): + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, situation_examples.couple) household = simulation.household person = simulation.person @@ -375,7 +377,7 @@ def test_projectors_methods(simulation_builder, tax_benefit_system): assert(len(household.first_parent.get_rank(household, salary_i)) == 1) # Must be of a person dimension -def test_sum_following_bug_ipp_1(simulation_builder, tax_benefit_system): +def test_sum_following_bug_ipp_1(tax_benefit_system): test_case = { 'persons': {'ind0': {}, 'ind1': {}, 'ind2': {}, 'ind3': {}}, 'households': { @@ -388,7 +390,7 @@ def test_sum_following_bug_ipp_1(simulation_builder, tax_benefit_system): test_case['persons']['ind2']['salary'] = 1000 test_case['persons']['ind3']['salary'] = 1000 - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household eligible_i = household.members('salary', period = MONTH) < 1500 @@ -397,7 +399,7 @@ def test_sum_following_bug_ipp_1(simulation_builder, tax_benefit_system): tools.assert_near(nb_eligibles_by_household, [0, 2]) -def test_sum_following_bug_ipp_2(simulation_builder, tax_benefit_system): +def test_sum_following_bug_ipp_2(tax_benefit_system): test_case = { 'persons': {'ind0': {}, 'ind1': {}, 'ind2': {}, 'ind3': {}}, 'households': { @@ -410,7 +412,7 @@ def test_sum_following_bug_ipp_2(simulation_builder, tax_benefit_system): test_case['persons']['ind2']['salary'] = 1000 test_case['persons']['ind3']['salary'] = 1000 - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case) + simulation = new_simulation(tax_benefit_system, test_case) household = simulation.household eligible_i = household.members('salary', period = MONTH) < 1500 @@ -419,17 +421,17 @@ def test_sum_following_bug_ipp_2(simulation_builder, tax_benefit_system): tools.assert_near(nb_eligibles_by_household, [2, 0]) -def test_get_memory_usage(simulation_builder, tax_benefit_system): +def test_get_memory_usage(tax_benefit_system): test_case = deepcopy(situation_examples.single) test_case["persons"]["Alicia"]["salary"] = {"2017-01": 0} - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_case) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_case) simulation.calculate('disposable_income', '2017-01') memory_usage = simulation.person.get_memory_usage(variables = ['salary']) assert(memory_usage['total_nb_bytes'] > 0) assert(len(memory_usage['by_variable']) == 1) -def test_unordered_persons(simulation_builder, tax_benefit_system): +def test_unordered_persons(tax_benefit_system): test_case = { 'persons': {'ind4': {}, 'ind3': {}, 'ind1': {}, 'ind2': {}, 'ind5': {}, 'ind0': {}}, 'households': { @@ -450,7 +452,7 @@ def test_unordered_persons(simulation_builder, tax_benefit_system): # household.members_entity_id == [1, 0, 0, 0, 1, 0] - simulation = new_simulation(simulation_builder, tax_benefit_system, test_case, MONTH) + simulation = new_simulation(tax_benefit_system, test_case, MONTH) household = simulation.household person = simulation.person diff --git a/tests/core/test_formulas.py b/tests/core/test_formulas.py index 1b92b2e3be..876ca239d1 100644 --- a/tests/core/test_formulas.py +++ b/tests/core/test_formulas.py @@ -1,24 +1,25 @@ -import numpy as np +import numpy -from openfisca_core.periods import MONTH +from openfisca_country_template import entities + +from openfisca_core import commons, periods +from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable -from openfisca_core.formula_helpers import switch -from openfisca_country_template.entities import Person from pytest import fixture, approx class choice(Variable): value_type = int - entity = Person - definition_period = MONTH + entity = entities.Person + definition_period = periods.MONTH class uses_multiplication(Variable): value_type = int - entity = Person + entity = entities.Person label = 'Variable with formula that uses multiplication' - definition_period = MONTH + definition_period = periods.MONTH def formula(person, period): choice = person('choice', period) @@ -28,9 +29,9 @@ def formula(person, period): class returns_scalar(Variable): value_type = int - entity = Person + entity = entities.Person label = 'Variable with formula that returns a scalar value' - definition_period = MONTH + definition_period = periods.MONTH def formula(person, period): return 666 @@ -38,13 +39,13 @@ def formula(person, period): class uses_switch(Variable): value_type = int - entity = Person + entity = entities.Person label = 'Variable with formula that uses switch' - definition_period = MONTH + definition_period = periods.MONTH def formula(person, period): choice = person('choice', period) - result = switch( + result = commons.switch( choice, { 1: 80, @@ -65,30 +66,31 @@ def month(): @fixture -def simulation(simulation_builder, tax_benefit_system, month): +def simulation(tax_benefit_system, month): + simulation_builder = SimulationBuilder() simulation_builder.default_period = month - simulation = simulation_builder.build_from_variables(tax_benefit_system, {'choice': np.random.randint(2, size = 1000) + 1}) + simulation = simulation_builder.build_from_variables(tax_benefit_system, {'choice': numpy.random.randint(2, size = 1000) + 1}) simulation.debug = True return simulation def test_switch(simulation, month): uses_switch = simulation.calculate('uses_switch', period = month) - assert isinstance(uses_switch, np.ndarray) + assert isinstance(uses_switch, numpy.ndarray) def test_multiplication(simulation, month): uses_multiplication = simulation.calculate('uses_multiplication', period = month) - assert isinstance(uses_multiplication, np.ndarray) + assert isinstance(uses_multiplication, numpy.ndarray) def test_broadcast_scalar(simulation, month): array_value = simulation.calculate('returns_scalar', period = month) - assert isinstance(array_value, np.ndarray) - assert array_value == approx(np.repeat(666, 1000)) + assert isinstance(array_value, numpy.ndarray) + assert array_value == approx(numpy.repeat(666, 1000)) def test_compare_multiplication_and_switch(simulation, month): uses_multiplication = simulation.calculate('uses_multiplication', period = month) uses_switch = simulation.calculate('uses_switch', period = month) - assert np.all(uses_switch == uses_multiplication) + assert numpy.all(uses_switch == uses_multiplication) diff --git a/tests/core/test_holders.py b/tests/core/test_holders.py index 1ccc48bf64..cd26231037 100644 --- a/tests/core/test_holders.py +++ b/tests/core/test_holders.py @@ -1,52 +1,56 @@ -import numpy as np import pytest -import openfisca_country_template.situation_examples -from openfisca_country_template.variables.housing import HousingOccupancyStatus -from openfisca_core.periods import period as make_period, ETERNITY -from openfisca_core.tools import assert_near -from openfisca_core.memory_config import MemoryConfig -from openfisca_core.holders import Holder, set_input_dispatch_by_period -from openfisca_core.errors import PeriodMismatchError +import numpy + +from openfisca_country_template import situation_examples +from openfisca_country_template.variables import housing -from pytest import fixture +from openfisca_core import holders, periods, tools +from openfisca_core.errors import PeriodMismatchError +from openfisca_core.memory_config import MemoryConfig +from openfisca_core.simulations import SimulationBuilder +from openfisca_core.holders import Holder -@fixture -def single(simulation_builder, tax_benefit_system): - return simulation_builder.build_from_entities(tax_benefit_system, openfisca_country_template.situation_examples.single) +@pytest.fixture +def single(tax_benefit_system): + return \ + SimulationBuilder() \ + .build_from_entities(tax_benefit_system, situation_examples.single) -@fixture -def couple(simulation_builder, tax_benefit_system): - return simulation_builder.build_from_entities(tax_benefit_system, openfisca_country_template.situation_examples.couple) +@pytest.fixture +def couple(tax_benefit_system): + return \ + SimulationBuilder(). \ + build_from_entities(tax_benefit_system, situation_examples.couple) -period = make_period('2017-12') +period = periods.period('2017-12') def test_set_input_enum_string(couple): simulation = couple - status_occupancy = np.asarray(['free_lodger']) + status_occupancy = numpy.asarray(['free_lodger']) simulation.household.get_holder('housing_occupancy_status').set_input(period, status_occupancy) result = simulation.calculate('housing_occupancy_status', period) - assert result == HousingOccupancyStatus.free_lodger + assert result == housing.HousingOccupancyStatus.free_lodger def test_set_input_enum_int(couple): simulation = couple - status_occupancy = np.asarray([2], dtype = np.int16) + status_occupancy = numpy.asarray([2], dtype = numpy.int16) simulation.household.get_holder('housing_occupancy_status').set_input(period, status_occupancy) result = simulation.calculate('housing_occupancy_status', period) - assert result == HousingOccupancyStatus.free_lodger + assert result == housing.HousingOccupancyStatus.free_lodger def test_set_input_enum_item(couple): simulation = couple - status_occupancy = np.asarray([HousingOccupancyStatus.free_lodger]) + status_occupancy = numpy.asarray([housing.HousingOccupancyStatus.free_lodger]) simulation.household.get_holder('housing_occupancy_status').set_input(period, status_occupancy) result = simulation.calculate('housing_occupancy_status', period) - assert result == HousingOccupancyStatus.free_lodger + assert result == housing.HousingOccupancyStatus.free_lodger def test_yearly_input_month_variable(couple): @@ -69,7 +73,7 @@ def test_month_input_year_variable(couple): def test_enum_dtype(couple): simulation = couple - status_occupancy = np.asarray([2], dtype = np.int16) + status_occupancy = numpy.asarray([2], dtype = numpy.int16) simulation.household.get_holder('housing_occupancy_status').set_input(period, status_occupancy) result = simulation.calculate('housing_occupancy_status', period) assert result.dtype.kind is not None @@ -84,22 +88,22 @@ def test_permanent_variable_empty(single): def test_permanent_variable_filled(single): simulation = single holder = simulation.person.get_holder('birth') - value = np.asarray(['1980-01-01'], dtype = holder.variable.dtype) - holder.set_input(make_period(ETERNITY), value) + value = numpy.asarray(['1980-01-01'], dtype = holder.variable.dtype) + holder.set_input(periods.period(periods.ETERNITY), value) assert holder.get_array(None) == value - assert holder.get_array(ETERNITY) == value + assert holder.get_array(periods.ETERNITY) == value assert holder.get_array('2016-01') == value def test_delete_arrays(single): simulation = single salary_holder = simulation.person.get_holder('salary') - salary_holder.set_input(make_period(2017), np.asarray([30000])) - salary_holder.set_input(make_period(2018), np.asarray([60000])) + salary_holder.set_input(periods.period(2017), numpy.asarray([30000])) + salary_holder.set_input(periods.period(2018), numpy.asarray([60000])) assert simulation.person('salary', '2017-01') == 2500 assert simulation.person('salary', '2018-01') == 5000 salary_holder.delete_arrays(period = 2018) - salary_holder.set_input(make_period(2018), np.asarray([15000])) + salary_holder.set_input(periods.period(2018), numpy.asarray([15000])) assert simulation.person('salary', '2017-01') == 2500 assert simulation.person('salary', '2018-01') == 1250 @@ -109,7 +113,7 @@ def test_get_memory_usage(single): salary_holder = simulation.person.get_holder('salary') memory_usage = salary_holder.get_memory_usage() assert memory_usage['total_nb_bytes'] == 0 - salary_holder.set_input(make_period(2017), np.asarray([30000])) + salary_holder.set_input(periods.period(2017), numpy.asarray([30000])) memory_usage = salary_holder.get_memory_usage() assert memory_usage['nb_cells_by_array'] == 1 assert memory_usage['cell_size'] == 4 # float 32 @@ -122,7 +126,7 @@ def test_get_memory_usage_with_trace(single): simulation = single simulation.trace = True salary_holder = simulation.person.get_holder('salary') - salary_holder.set_input(make_period(2017), np.asarray([30000])) + salary_holder.set_input(periods.period(2017), numpy.asarray([30000])) simulation.calculate('salary', '2017-01') simulation.calculate('salary', '2017-01') simulation.calculate('salary', '2017-02') @@ -137,7 +141,7 @@ def test_set_input_dispatch_by_period(single): variable = simulation.tax_benefit_system.get_variable('housing_occupancy_status') entity = simulation.household holder = Holder(variable, entity) - set_input_dispatch_by_period(holder, make_period(2019), 'owner') + holders.set_input_dispatch_by_period(holder, periods.period(2019), 'owner') assert holder.get_array('2019-01') == holder.get_array('2019-12') # Check the feature assert holder.get_array('2019-01') is holder.get_array('2019-12') # Check that the vectors are the same in memory, to avoid duplication @@ -149,12 +153,12 @@ def test_delete_arrays_on_disk(single): simulation = single simulation.memory_config = force_storage_on_disk salary_holder = simulation.person.get_holder('salary') - salary_holder.set_input(make_period(2017), np.asarray([30000])) - salary_holder.set_input(make_period(2018), np.asarray([60000])) + salary_holder.set_input(periods.period(2017), numpy.asarray([30000])) + salary_holder.set_input(periods.period(2018), numpy.asarray([60000])) assert simulation.person('salary', '2017-01') == 2500 assert simulation.person('salary', '2018-01') == 5000 salary_holder.delete_arrays(period = 2018) - salary_holder.set_input(make_period(2018), np.asarray([15000])) + salary_holder.set_input(periods.period(2018), numpy.asarray([15000])) assert simulation.person('salary', '2017-01') == 2500 assert simulation.person('salary', '2018-01') == 1250 @@ -162,21 +166,21 @@ def test_delete_arrays_on_disk(single): def test_cache_disk(couple): simulation = couple simulation.memory_config = force_storage_on_disk - month = make_period('2017-01') + month = periods.period('2017-01') holder = simulation.person.get_holder('disposable_income') - data = np.asarray([2000, 3000]) + data = numpy.asarray([2000, 3000]) holder.put_in_cache(data, month) stored_data = holder.get_array(month) - assert_near(data, stored_data) + tools.assert_near(data, stored_data) def test_known_periods(couple): simulation = couple simulation.memory_config = force_storage_on_disk - month = make_period('2017-01') - month_2 = make_period('2017-02') + month = periods.period('2017-01') + month_2 = periods.period('2017-02') holder = simulation.person.get_holder('disposable_income') - data = np.asarray([2000, 3000]) + data = numpy.asarray([2000, 3000]) holder.put_in_cache(data, month) holder._memory_storage.put(data, month_2) @@ -186,10 +190,10 @@ def test_known_periods(couple): def test_cache_enum_on_disk(single): simulation = single simulation.memory_config = force_storage_on_disk - month = make_period('2017-01') + month = periods.period('2017-01') simulation.calculate('housing_occupancy_status', month) # First calculation housing_occupancy_status = simulation.calculate('housing_occupancy_status', month) # Read from cache - assert housing_occupancy_status == HousingOccupancyStatus.tenant + assert housing_occupancy_status == housing.HousingOccupancyStatus.tenant def test_set_not_cached_variable(single): @@ -197,14 +201,14 @@ def test_set_not_cached_variable(single): simulation = single simulation.memory_config = dont_cache_variable holder = simulation.person.get_holder('salary') - array = np.asarray([2000]) + array = numpy.asarray([2000]) holder.set_input('2015-01', array) assert simulation.calculate('salary', '2015-01') == array def test_set_input_float_to_int(single): simulation = single - age = np.asarray([50.6]) + age = numpy.asarray([50.6]) simulation.person.get_holder('age').set_input(period, age) result = simulation.calculate('age', period) - assert result == np.asarray([50]) + assert result == numpy.asarray([50]) diff --git a/tests/core/test_simulation_builder.py b/tests/core/test_simulation_builder.py index 73d7b57ece..b6a558751d 100644 --- a/tests/core/test_simulation_builder.py +++ b/tests/core/test_simulation_builder.py @@ -9,7 +9,7 @@ from openfisca_core.errors import SituationParsingError from openfisca_core.indexed_enums import Enum from openfisca_core.populations import Population -from openfisca_core.simulations import Simulation +from openfisca_core.simulations import Simulation, SimulationBuilder from openfisca_core.tools import test_runner from openfisca_core.variables import Variable @@ -61,62 +61,68 @@ def __init__(self): return TestEnum() -def test_build_default_simulation(simulation_builder, tax_benefit_system): - one_person_simulation = simulation_builder.build_default_simulation(tax_benefit_system, 1) +def test_build_default_simulation(tax_benefit_system): + one_person_simulation = SimulationBuilder().build_default_simulation(tax_benefit_system, 1) assert one_person_simulation.persons.count == 1 assert one_person_simulation.household.count == 1 assert one_person_simulation.household.members_entity_id == [0] assert one_person_simulation.household.members_role == entities.Household.FIRST_PARENT - several_persons_simulation = simulation_builder.build_default_simulation(tax_benefit_system, 4) + several_persons_simulation = SimulationBuilder().build_default_simulation(tax_benefit_system, 4) assert several_persons_simulation.persons.count == 4 assert several_persons_simulation.household.count == 4 assert (several_persons_simulation.household.members_entity_id == [0, 1, 2, 3]).all() assert (several_persons_simulation.household.members_role == entities.Household.FIRST_PARENT).all() -def test_explicit_singular_entities(simulation_builder, tax_benefit_system): - assert simulation_builder.explicit_singular_entities( +def test_explicit_singular_entities(tax_benefit_system): + assert SimulationBuilder().explicit_singular_entities( tax_benefit_system, {'persons': {'Javier': {}}, 'household': {'parents': ['Javier']}} ) == {'persons': {'Javier': {}}, 'households': {'household': {'parents': ['Javier']}}} -def test_add_person_entity(simulation_builder, persons): +def test_add_person_entity(persons): persons_json = {'Alicia': {'salary': {}}, 'Javier': {}} + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, persons_json) assert simulation_builder.get_count('persons') == 2 assert simulation_builder.get_ids('persons') == ['Alicia', 'Javier'] -def test_numeric_ids(simulation_builder, persons): +def test_numeric_ids(persons): persons_json = {1: {'salary': {}}, 2: {}} + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, persons_json) assert simulation_builder.get_count('persons') == 2 assert simulation_builder.get_ids('persons') == ['1', '2'] -def test_add_person_entity_with_values(simulation_builder, persons): +def test_add_person_entity_with_values(persons): persons_json = {'Alicia': {'salary': {'2018-11': 3000}}, 'Javier': {}} + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, persons_json) tools.assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) -def test_add_person_values_with_default_period(simulation_builder, persons): - simulation_builder.set_default_period('2018-11') +def test_add_person_values_with_default_period(persons): persons_json = {'Alicia': {'salary': 3000}, 'Javier': {}} + simulation_builder = SimulationBuilder() + simulation_builder.set_default_period('2018-11') simulation_builder.add_person_entity(persons, persons_json) tools.assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) -def test_add_person_values_with_default_period_old_syntax(simulation_builder, persons): - simulation_builder.set_default_period('month:2018-11') +def test_add_person_values_with_default_period_old_syntax(persons): persons_json = {'Alicia': {'salary': 3000}, 'Javier': {}} + simulation_builder = SimulationBuilder() + simulation_builder.set_default_period('month:2018-11') simulation_builder.add_person_entity(persons, persons_json) tools.assert_near(simulation_builder.get_input('salary', '2018-11'), [3000, 0]) -def test_add_group_entity(simulation_builder, households): +def test_add_group_entity(households): + simulation_builder = SimulationBuilder() simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', 'Tom'], households, { 'Household_1': {'parents': ['Alicia', 'Javier']}, 'Household_2': {'parents': ['Tom'], 'children': ['Sarah']}, @@ -127,7 +133,8 @@ def test_add_group_entity(simulation_builder, households): assert [role.key for role in simulation_builder.get_roles('households')] == ['parent', 'parent', 'child', 'parent'] -def test_add_group_entity_loose_syntax(simulation_builder, households): +def test_add_group_entity_loose_syntax(households): + simulation_builder = SimulationBuilder() simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', '1'], households, { 'Household_1': {'parents': ['Alicia', 'Javier']}, 'Household_2': {'parents': 1, 'children': 'Sarah'}, @@ -138,67 +145,75 @@ def test_add_group_entity_loose_syntax(simulation_builder, households): assert [role.key for role in simulation_builder.get_roles('households')] == ['parent', 'parent', 'child', 'parent'] -def test_add_variable_value(simulation_builder, persons): +def test_add_variable_value(persons): salary = persons.get_variable('salary') instance_index = 0 + simulation_builder = SimulationBuilder() simulation_builder.entity_counts['persons'] = 1 simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', 3000) input_array = simulation_builder.get_input('salary', '2018-11') assert input_array[instance_index] == pytest.approx(3000) -def test_add_variable_value_as_expression(simulation_builder, persons): +def test_add_variable_value_as_expression(persons): salary = persons.get_variable('salary') instance_index = 0 + simulation_builder = SimulationBuilder() simulation_builder.entity_counts['persons'] = 1 simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', '3 * 1000') input_array = simulation_builder.get_input('salary', '2018-11') assert input_array[instance_index] == pytest.approx(3000) -def test_fail_on_wrong_data(simulation_builder, persons): +def test_fail_on_wrong_data(persons): salary = persons.get_variable('salary') instance_index = 0 + simulation_builder = SimulationBuilder() simulation_builder.entity_counts['persons'] = 1 with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', 'alicia') assert excinfo.value.error == {'persons': {'Alicia': {'salary': {'2018-11': "Can't deal with value: expected type number, received 'alicia'."}}}} -def test_fail_on_ill_formed_expression(simulation_builder, persons): +def test_fail_on_ill_formed_expression(persons): salary = persons.get_variable('salary') instance_index = 0 + simulation_builder = SimulationBuilder() simulation_builder.entity_counts['persons'] = 1 with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, salary, instance_index, 'Alicia', '2018-11', '2 * / 1000') assert excinfo.value.error == {'persons': {'Alicia': {'salary': {'2018-11': "I couldn't understand '2 * / 1000' as a value for 'salary'"}}}} -def test_fail_on_integer_overflow(simulation_builder, persons, int_variable): +def test_fail_on_integer_overflow(persons, int_variable): instance_index = 0 + simulation_builder = SimulationBuilder() simulation_builder.entity_counts['persons'] = 1 with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, int_variable, instance_index, 'Alicia', '2018-11', 9223372036854775808) assert excinfo.value.error == {'persons': {'Alicia': {'intvar': {'2018-11': "Can't deal with value: '9223372036854775808', it's too large for type 'integer'."}}}} -def test_fail_on_date_parsing(simulation_builder, persons, date_variable): +def test_fail_on_date_parsing(persons, date_variable): instance_index = 0 + simulation_builder = SimulationBuilder() simulation_builder.entity_counts['persons'] = 1 with pytest.raises(SituationParsingError) as excinfo: simulation_builder.add_variable_value(persons, date_variable, instance_index, 'Alicia', '2018-11', '2019-02-30') assert excinfo.value.error == {'persons': {'Alicia': {'datevar': {'2018-11': "Can't deal with date: '2019-02-30'."}}}} -def test_add_unknown_enum_variable_value(simulation_builder, persons, enum_variable): +def test_add_unknown_enum_variable_value(persons, enum_variable): instance_index = 0 + simulation_builder = SimulationBuilder() simulation_builder.entity_counts['persons'] = 1 with pytest.raises(SituationParsingError): simulation_builder.add_variable_value(persons, enum_variable, instance_index, 'Alicia', '2018-11', 'baz') -def test_finalize_person_entity(simulation_builder, persons): +def test_finalize_person_entity(persons): persons_json = {'Alicia': {'salary': {'2018-11': 3000}}, 'Javier': {}} + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, persons_json) population = Population(persons) simulation_builder.finalize_variables_init(population) @@ -207,16 +222,18 @@ def test_finalize_person_entity(simulation_builder, persons): assert population.ids == ['Alicia', 'Javier'] -def test_canonicalize_period_keys(simulation_builder, persons): +def test_canonicalize_period_keys(persons): persons_json = {'Alicia': {'salary': {'year:2018-01': 100}}} + simulation_builder = SimulationBuilder() simulation_builder.add_person_entity(persons, persons_json) population = Population(persons) simulation_builder.finalize_variables_init(population) tools.assert_near(population.get_holder('salary').get_array('2018-12'), [100]) -def test_finalize_households(simulation_builder, tax_benefit_system): +def test_finalize_households(tax_benefit_system): simulation = Simulation(tax_benefit_system, tax_benefit_system.instantiate_entities()) + simulation_builder = SimulationBuilder() simulation_builder.add_group_entity('persons', ['Alicia', 'Javier', 'Sarah', 'Tom'], simulation.household.entity, { 'Household_1': {'parents': ['Alicia', 'Javier']}, 'Household_2': {'parents': ['Tom'], 'children': ['Sarah']}, @@ -226,7 +243,7 @@ def test_finalize_households(simulation_builder, tax_benefit_system): tools.assert_near(simulation.persons.has_role(entities.Household.PARENT), [True, True, False, True]) -def test_check_persons_to_allocate(simulation_builder): +def test_check_persons_to_allocate(): entity_plural = 'familles' persons_plural = 'individus' person_id = 'Alicia' @@ -235,13 +252,19 @@ def test_check_persons_to_allocate(simulation_builder): persons_to_allocate = ['Alicia'] persons_ids = ['Alicia'] index = 0 - simulation_builder.check_persons_to_allocate(persons_plural, entity_plural, - persons_ids, - person_id, entity_id, role_id, - persons_to_allocate, index) + SimulationBuilder().check_persons_to_allocate( + persons_plural, + entity_plural, + persons_ids, + person_id, + entity_id, + role_id, + persons_to_allocate, + index, + ) -def test_allocate_undeclared_person(simulation_builder): +def test_allocate_undeclared_person(): entity_plural = 'familles' persons_plural = 'individus' person_id = 'Alicia' @@ -251,7 +274,7 @@ def test_allocate_undeclared_person(simulation_builder): persons_ids = [] index = 0 with pytest.raises(SituationParsingError) as exception: - simulation_builder.check_persons_to_allocate( + SimulationBuilder().check_persons_to_allocate( persons_plural, entity_plural, persons_ids, person_id, entity_id, role_id, @@ -259,7 +282,7 @@ def test_allocate_undeclared_person(simulation_builder): assert exception.value.error == {'familles': {'famille1': {'parents': 'Unexpected value: Alicia. Alicia has been declared in famille1 parents, but has not been declared in individus.'}}} -def test_allocate_person_twice(simulation_builder): +def test_allocate_person_twice(): entity_plural = 'familles' persons_plural = 'individus' person_id = 'Alicia' @@ -269,7 +292,7 @@ def test_allocate_person_twice(simulation_builder): persons_ids = ['Alicia'] index = 0 with pytest.raises(SituationParsingError) as exception: - simulation_builder.check_persons_to_allocate( + SimulationBuilder().check_persons_to_allocate( persons_plural, entity_plural, persons_ids, person_id, entity_id, role_id, @@ -277,30 +300,31 @@ def test_allocate_person_twice(simulation_builder): assert exception.value.error == {'familles': {'famille1': {'parents': 'Alicia has been declared more than once in familles'}}} -def test_one_person_without_household(simulation_builder, tax_benefit_system): +def test_one_person_without_household(tax_benefit_system): simulation_dict = {'persons': {'Alicia': {}}} - simulation = simulation_builder.build_from_dict(tax_benefit_system, simulation_dict) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, simulation_dict) assert simulation.household.count == 1 parents_in_households = simulation.household.nb_persons(role = entities.Household.PARENT) assert parents_in_households.tolist() == [1] # household member default role is first_parent -def test_some_person_without_household(simulation_builder, tax_benefit_system): +def test_some_person_without_household(tax_benefit_system): input_yaml = """ persons: {'Alicia': {}, 'Bob': {}} household: {'parents': ['Alicia']} """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert simulation.household.count == 2 parents_in_households = simulation.household.nb_persons(role = entities.Household.PARENT) assert parents_in_households.tolist() == [1, 1] # household member default role is first_parent -def test_nb_persons_in_households(simulation_builder, tax_benefit_system): +def test_nb_persons_in_households(tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] + simulation_builder = SimulationBuilder() simulation_builder.create_entities(tax_benefit_system) simulation_builder.declare_person_entity('person', persons_ids) household_instance = simulation_builder.declare_entity('household', households_ids) @@ -311,11 +335,12 @@ def test_nb_persons_in_households(simulation_builder, tax_benefit_system): assert persons_in_households.tolist() == [1, 3, 1] -def test_nb_persons_no_role(simulation_builder, tax_benefit_system): +def test_nb_persons_no_role(tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] + simulation_builder = SimulationBuilder() simulation_builder.create_entities(tax_benefit_system) simulation_builder.declare_person_entity('person', persons_ids) household_instance = simulation_builder.declare_entity('household', households_ids) @@ -326,12 +351,13 @@ def test_nb_persons_no_role(simulation_builder, tax_benefit_system): assert parents_in_households.tolist() == [1, 3, 1] # household member default role is first_parent -def test_nb_persons_by_role(simulation_builder, tax_benefit_system): +def test_nb_persons_by_role(tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] persons_households_roles: Iterable = ['child', 'first_parent', 'second_parent', 'first_parent', 'child'] + simulation_builder = SimulationBuilder() simulation_builder.create_entities(tax_benefit_system) simulation_builder.declare_person_entity('person', persons_ids) household_instance = simulation_builder.declare_entity('household', households_ids) @@ -346,13 +372,14 @@ def test_nb_persons_by_role(simulation_builder, tax_benefit_system): assert parents_in_households.tolist() == [0, 1, 1] -def test_integral_roles(simulation_builder, tax_benefit_system): +def test_integral_roles(tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] persons_households: Iterable = ['c', 'a', 'a', 'b', 'a'] # Same roles as test_nb_persons_by_role persons_households_roles: Iterable = [2, 0, 1, 0, 2] + simulation_builder = SimulationBuilder() simulation_builder.create_entities(tax_benefit_system) simulation_builder.declare_person_entity('person', persons_ids) household_instance = simulation_builder.declare_entity('household', households_ids) @@ -370,7 +397,7 @@ def test_integral_roles(simulation_builder, tax_benefit_system): # Test Intégration -def test_from_person_variable_to_group(simulation_builder, tax_benefit_system): +def test_from_person_variable_to_group(tax_benefit_system): persons_ids: Iterable = [2, 0, 1, 4, 3] households_ids: Iterable = ['c', 'a', 'b'] @@ -381,6 +408,7 @@ def test_from_person_variable_to_group(simulation_builder, tax_benefit_system): period = '2018-12' + simulation_builder = SimulationBuilder() simulation_builder.create_entities(tax_benefit_system) simulation_builder.declare_person_entity('person', persons_ids) @@ -396,39 +424,39 @@ def test_from_person_variable_to_group(simulation_builder, tax_benefit_system): assert total_taxes / simulation.calculate('rent', period) == pytest.approx(1) -def test_simulation(simulation_builder, tax_benefit_system): +def test_simulation(tax_benefit_system): input_yaml = """ salary: 2016-10: 12000 """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert simulation.get_array("salary", "2016-10") == 12000 simulation.calculate("income_tax", "2016-10") simulation.calculate("total_taxes", "2016-10") -def test_vectorial_input(simulation_builder, tax_benefit_system): +def test_vectorial_input(tax_benefit_system): input_yaml = """ salary: 2016-10: [12000, 20000] """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) tools.assert_near(simulation.get_array("salary", "2016-10"), [12000, 20000]) simulation.calculate("income_tax", "2016-10") simulation.calculate("total_taxes", "2016-10") -def test_fully_specified_entities(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_from_dict(tax_benefit_system, situation_examples.couple) +def test_fully_specified_entities(tax_benefit_system): + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, situation_examples.couple) assert simulation.household.count == 1 assert simulation.persons.count == 2 -def test_single_entity_shortcut(simulation_builder, tax_benefit_system): +def test_single_entity_shortcut(tax_benefit_system): input_yaml = """ persons: Alicia: {} @@ -437,11 +465,11 @@ def test_single_entity_shortcut(simulation_builder, tax_benefit_system): parents: [Alicia, Javier] """ - simulation = simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert simulation.household.count == 1 -def test_order_preserved(simulation_builder, tax_benefit_system): +def test_order_preserved(tax_benefit_system): input_yaml = """ persons: Javier: {} @@ -454,12 +482,12 @@ def test_order_preserved(simulation_builder, tax_benefit_system): """ data = test_runner.yaml.safe_load(input_yaml) - simulation = simulation_builder.build_from_dict(tax_benefit_system, data) + simulation = SimulationBuilder().build_from_dict(tax_benefit_system, data) assert simulation.persons.ids == ['Javier', 'Alicia', 'Sarah', 'Tom'] -def test_inconsistent_input(simulation_builder, tax_benefit_system): +def test_inconsistent_input(tax_benefit_system): input_yaml = """ salary: 2016-10: [12000, 20000] @@ -467,5 +495,5 @@ def test_inconsistent_input(simulation_builder, tax_benefit_system): 2016-10: [100, 200, 300] """ with pytest.raises(ValueError) as error: - simulation_builder.build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) + SimulationBuilder().build_from_dict(tax_benefit_system, test_runner.yaml.safe_load(input_yaml)) assert "its length is 3 while there are 2" in error.value.args[0] diff --git a/tests/core/test_simulations.py b/tests/core/test_simulations.py index 520df1a29e..d5f3ac8008 100644 --- a/tests/core/test_simulations.py +++ b/tests/core/test_simulations.py @@ -1,8 +1,10 @@ from openfisca_country_template.situation_examples import single +from openfisca_core.simulations import SimulationBuilder -def test_calculate_full_tracer(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_default_simulation(tax_benefit_system) + +def test_calculate_full_tracer(tax_benefit_system): + simulation = SimulationBuilder().build_default_simulation(tax_benefit_system) simulation.trace = True simulation.calculate('income_tax', '2017-01') @@ -22,13 +24,13 @@ def test_calculate_full_tracer(simulation_builder, tax_benefit_system): assert income_tax_node.parameters[0].value == 0.15 -def test_get_entity_not_found(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_default_simulation(tax_benefit_system) +def test_get_entity_not_found(tax_benefit_system): + simulation = SimulationBuilder().build_default_simulation(tax_benefit_system) assert simulation.get_entity(plural = "no_such_entities") is None -def test_clone(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_from_entities(tax_benefit_system, +def test_clone(tax_benefit_system): + simulation = SimulationBuilder().build_from_entities(tax_benefit_system, { "persons": { "bill": {"salary": {"2017-01": 3000}}, @@ -56,8 +58,8 @@ def test_clone(simulation_builder, tax_benefit_system): assert salary_holder_clone.population == simulation_clone.persons -def test_get_memory_usage(simulation_builder, tax_benefit_system): - simulation = simulation_builder.build_from_entities(tax_benefit_system, single) +def test_get_memory_usage(tax_benefit_system): + simulation = SimulationBuilder().build_from_entities(tax_benefit_system, single) simulation.calculate('disposable_income', '2017-01') memory_usage = simulation.get_memory_usage(variables = ['salary']) assert(memory_usage['total_nb_bytes'] > 0) diff --git a/tests/fixtures/simulations.py b/tests/fixtures/simulations.py index fec8403959..9d343d5ac0 100644 --- a/tests/fixtures/simulations.py +++ b/tests/fixtures/simulations.py @@ -2,23 +2,24 @@ import pytest -from openfisca_core.simulations.simulation_builder import SimulationBuilder +from openfisca_core.simulations import SimulationBuilder @pytest.fixture -def simulation_builder(): - return SimulationBuilder() - - -@pytest.fixture -def simulation(simulation_builder, tax_benefit_system, request): +def simulation(tax_benefit_system, request): variables, period = request.param - return _simulation(simulation_builder, tax_benefit_system, variables, period) + + return _simulation( + SimulationBuilder(), + tax_benefit_system, + variables, + period, + ) @pytest.fixture -def make_simulation(simulation_builder): - return functools.partial(_simulation, simulation_builder) +def make_simulation(): + return functools.partial(_simulation, SimulationBuilder()) def _simulation(simulation_builder, tax_benefit_system, variables, period): From dc2271e8024ec483035118f3bf2991cfd7d07b71 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Wed, 14 Apr 2021 00:39:56 +0200 Subject: [PATCH 20/22] Add style guide --- README.md | 2 +- STYLEGUIDE.md | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 STYLEGUIDE.md diff --git a/README.md b/README.md index d1f5767689..bbb2be461e 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ pytest tests/core/test_parameters.py -k test_parameter_for_period ## Style -This repository adheres to a certain coding style, and we invite you to follow it for your contributions to be integrated promptly. +This repository adheres to a [certain coding style](STYLEGUIDE.md), and we invite you to follow it for your contributions to be integrated promptly. Style checking is already run with `make test`. To run the style checker alone: diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md new file mode 100644 index 0000000000..e69de29bb2 From 392358ed02119957abef3049d86184cfa7a73852 Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Wed, 14 Apr 2021 01:28:19 +0200 Subject: [PATCH 21/22] Add imports to style guide --- STYLEGUIDE.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index e69de29bb2..db5ea925e2 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -0,0 +1,84 @@ +# OpenFisca's Python Style Guide + +Arguments over code style and formatting are the bread and butter of most open-source projets out there, including OpenFisca. + +To avoid this, we have a style guide, that is a set or arbitrary but consistent conventions about how code should be written, for contributors and maintainers alike. + +## Notice + +### About this style guide + +The present style guide is a work in progress. + +It largely follows [Python Foundation's](https://www.python.org/dev/peps/pep-0008/), [NumPy's](https://numpydoc.readthedocs.io/en/latest/format.html) and [Google's](https://google.github.io/styleguide/pyguide.html), but it has a lot of her own as well. + +### Contributing + +Please refer whenever possible to this style guide both for your contributions and your reviews. + +If the style in question is not present and contentious, do not hesitate to include an addition to this guide within your proposal or review. + +## Imports + +1. In general, use import statements for entire namespaces and modules, rather than for classes and functions. Are exempt of this rule the `typing` module, NumPy's `typing` module, and `openfisca_core` module and submodules (but only in the case of class imports). + +2. In general, use absolute import statements rather that relative ones. Are exempt of this rule the modules relative to a submodule of OpenFisca, in order to improve the delimitation of internal and external interfaces. + +3. Always follow this order for your imports: system modules, third party modules, third party OpenFisca modules, external OpenFisca Core modules, internal OpenFisca Core modules. + +For example given: + +``` +/openfisca_core/axes/__init__.py +/openfisca_core/axes/nothing.py +/openfisca_core/axes/something.py +``` + +Whenever possible we should expect: + +```python +# /openfisca_core/axes/nothing.py +# +# Yes + +import copy +from typing import List + +import numpy +from numpy.typing import ArrayLike + +from openfisca_country_template import entities + +from openfisca_core import tools +from openfisca_core.variables import Variable + +from . import Something + +def do(this: List) -> ArrayLike: + that = copy.deepcopy(this) + array = numpy.ndarray(that) + return Something(entities.Person, Variable) +``` + +And avoid: + +```python +# /openfisca_core/axes/nothing.py +# +# No + +from openfisca_country_template.entities import Person +from openfisca_core import variables +from openfisca_core.tools import assert_near +from openfisca_core import axes + +from numpy import ndarray +from copy import deepcopy +import typing +import numpy.typing + +def do(this: typing.List) -> numpy.typing.ArrayLike: + that = deepcopy(this) + array = ndarray(that) + return axes.Something(Person, variables.Variable) +``` From 7311ceaeae5b7fd4da307e46c123aa5a3c18618a Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Wed, 14 Apr 2021 01:46:10 +0200 Subject: [PATCH 22/22] Bump version to 35.3.5 --- CHANGELOG.md | 8 ++++++++ setup.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fbf6cacac..897aef89a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +### 35.3.5 [#997](https://github.com/openfisca/openfisca-core/pull/997) + +#### Technical changes + +- In tests, extract `CountryTaxBenefitSystem` to a fixture reusable by all the tests in the test suite. + - It allows for a better reusability of test scenarios available to new contributors. + - To mitigate possible performance issues, by default the fixture is initialised once per test module. + ### 35.3.4 [#999](https://github.com/openfisca/openfisca-core/pull/999) #### Technical improvements diff --git a/setup.py b/setup.py index 170aefe700..601c0e7493 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ setup( name = 'OpenFisca-Core', - version = '35.3.4', + version = '35.3.5', author = 'OpenFisca Team', author_email = 'contact@openfisca.org', classifiers = [