Skip to content

Commit d79eec0

Browse files
Refactoring due to modularisation works on #997
1 parent 3e6f555 commit d79eec0

2 files changed

Lines changed: 34 additions & 234 deletions

File tree

tests/web_api/conftest.py

Lines changed: 0 additions & 69 deletions
This file was deleted.

tests/web_api/test_variables.py

Lines changed: 34 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,44 @@
1-
# -*- coding: utf-8 -*-
2-
3-
from datetime import date
4-
from http.client import OK, NOT_FOUND
1+
from http import client
52
import json
6-
from numpy import where
7-
import re
8-
93
import pytest
4+
import re
105

11-
from openfisca_core.indexed_enums import Enum
12-
from openfisca_core.periods import MONTH, ETERNITY
13-
from openfisca_core.variables import Variable
14-
from openfisca_web_api.app import create_app
15-
from .conftest import Person, Household
6+
from openfisca_web_api import app
167

178

189
def assert_items_equal(x, y):
1910
assert set(x) == set(y)
2011

2112

22-
GITHUB_URL_REGEX = r'^https://github\.com/openfisca/openfisca-core/blob/\d+\.\d+\.\d+((.dev|rc)\d+)?/tests/web_api/(.)+\.py#L\d+-L\d+$'
13+
GITHUB_URL_REGEX = r'^https://github\.com/openfisca/country-template/blob/\d+\.\d+\.\d+((.dev|rc)\d+)?/openfisca_country_template/variables/(.)+\.py#L\d+-L\d+$'
2314

2415

2516
@pytest.fixture(scope="module")
26-
def test_client(test_tax_benefit_system):
27-
28-
###
29-
# In this section you define the mock Variables you will need for tests in this module
30-
class birth(Variable):
31-
value_type = date
32-
default_value = date(1970, 1, 1) # By default, if no value is set for a simulation, we consider the people involved in a simulation to be born on the 1st of Jan 1970.
33-
entity = Person
34-
label = "Birth date"
35-
definition_period = ETERNITY # This variable cannot change over time.
36-
reference = "https://en.wiktionary.org/wiki/birthdate"
37-
38-
class income_tax(Variable):
39-
value_type = float
40-
entity = Person
41-
definition_period = MONTH
42-
label = "Income tax"
43-
reference = "https://law.gov.example/income_tax" # Always use the most official source
44-
45-
def formula(person, period, parameters):
46-
"""
47-
Income tax.
48-
49-
The formula to compute the income tax for a given person at a given period
50-
"""
51-
return person("salary", period) * parameters(period).taxes.income_tax_rate
52-
53-
class age(Variable):
54-
value_type = int
55-
entity = Person
56-
definition_period = MONTH
57-
label = "Person's age (in years)"
58-
59-
def formula(person, period, _parameters):
60-
"""
61-
Person's age (in years).
62-
63-
A person's age is computed according to its birth date.
64-
"""
65-
birth = person("birth", period)
66-
birth_year = birth.astype("datetime64[Y]").astype(int) + 1970
67-
birth_month = birth.astype("datetime64[M]").astype(int) % 12 + 1
68-
birth_day = (birth - birth.astype("datetime64[M]") + 1).astype(int)
69-
70-
is_birthday_past = (birth_month < period.start.month) + (birth_month == period.start.month) * (birth_day <= period.start.day)
71-
72-
return (period.start.year - birth_year) - where(is_birthday_past, 0, 1) # If the birthday is not passed this year, subtract one year
73-
74-
class housing_allowance(Variable):
75-
value_type = float
76-
entity = Household
77-
definition_period = MONTH
78-
label = "Housing allowance"
79-
reference = "https://law.gov.example/housing_allowance" # Always use the most official source
80-
end = "2016-11-30" # This allowance was removed on the 1st of Dec 2016. Calculating it before this date will always return the variable default value, 0.
81-
unit = "currency-EUR"
82-
documentation = """
83-
This allowance was introduced on the 1st of Jan 1980.
84-
It disappeared in Dec 2016.
85-
"""
86-
87-
def formula_1980(household, period, parameters):
88-
"""
89-
Housing allowance.
90-
91-
This allowance was introduced on the 1st of Jan 1980.
92-
Calculating it before this date will always return the variable default value, 0.
93-
94-
To compute this allowance, the 'rent' value must be provided for the same month,
95-
but 'housing_occupancy_status' is not necessary.
96-
"""
97-
return household("rent", period) * parameters(period).benefits.housing_allowance
98-
99-
class HousingOccupancyStatus(Enum):
100-
__order__ = "owner tenant free_lodger homeless"
101-
owner = "Owner"
102-
tenant = "Tenant"
103-
free_lodger = "Free lodger"
104-
homeless = "Homeless"
105-
106-
class housing_occupancy_status(Variable):
107-
value_type = Enum
108-
possible_values = HousingOccupancyStatus
109-
default_value = HousingOccupancyStatus.tenant
110-
entity = Household
111-
definition_period = MONTH
112-
label = "Legal housing situation of the household concerning their main residence"
113-
114-
class basic_income(Variable):
115-
value_type = float
116-
entity = Person
117-
definition_period = MONTH
118-
label = "Basic income provided to adults"
119-
reference = "https://law.gov.example/basic_income" # Always use the most official source
120-
121-
def formula_2016_12(person, period, parameters):
122-
"""
123-
Basic income provided to adults.
124-
125-
Since Dec 1st 2016, the basic income is provided to any adult, without considering their income.
126-
"""
127-
age_condition = person("age", period) >= parameters(period).general.age_of_majority
128-
return age_condition * parameters(period).benefits.basic_income # This '*' is a vectorial 'if'. See https://openfisca.org/doc/coding-the-legislation/25_vectorial_computing.html#control-structures
129-
130-
def formula_2015_12(person, period, parameters):
131-
"""
132-
Basic income provided to adults.
133-
134-
From Dec 1st 2015 to Nov 30 2016, the basic income is provided to adults who have no income.
135-
Before Dec 1st 2015, the basic income does not exist in the law, and calculating it returns its default value, which is 0.
136-
"""
137-
age_condition = person("age", period) >= parameters(period).general.age_of_majority
138-
salary_condition = person("salary", period) == 0
139-
return age_condition * salary_condition * parameters(period).benefits.basic_income # The '*' is also used as a vectorial 'and'. See https://openfisca.org/doc/coding-the-legislation/25_vectorial_computing.html#boolean-operations
140-
141-
class pension(Variable):
142-
value_type = float
143-
entity = Person
144-
definition_period = MONTH
145-
label = "Pension for the elderly. Pension attribuée aux personnes âgées. تقاعد."
146-
reference = ["https://fr.wikipedia.org/wiki/Retraite_(économie)", "https://ar.wikipedia.org/wiki/تقاعد"]
147-
148-
def formula(person, period, parameters):
149-
"""
150-
Pension for the elderly.
151-
152-
A person's pension depends on their birth date.
153-
In French: retraite selon l'âge.
154-
In Arabic: تقاعد.
155-
"""
156-
age_condition = person("age", period) >= parameters(period).general.age_of_retirement
157-
return age_condition
158-
159-
###
160-
# Add the Variables above to the `test_tax_benefit_system` fixture
161-
test_tax_benefit_system.add_variable(birth)
162-
test_tax_benefit_system.add_variable(income_tax)
163-
test_tax_benefit_system.add_variable(age)
164-
test_tax_benefit_system.add_variable(housing_allowance)
165-
test_tax_benefit_system.add_variable(housing_occupancy_status)
166-
test_tax_benefit_system.add_variable(basic_income)
167-
test_tax_benefit_system.add_variable(pension)
168-
169-
###
17+
def test_client(tax_benefit_system):
18+
""" This module-scoped fixture creates an API client for the TBS defined in the `tax_benefit_system`
19+
fixture. This `tax_benefit_system` is mutable, so you can add/update variables. Example:
20+
21+
```
22+
from openfisca_country_template import entities
23+
from openfisca_core import periods
24+
from openfisca_core.variables import Variable
25+
...
26+
27+
class new_variable(Variable):
28+
value_type = float
29+
entity = entities.Person
30+
definition_period = periods.MONTH
31+
label = "New variable"
32+
reference = "https://law.gov.example/new_variable" # Always use the most official source
33+
34+
tax_benefit_system.add_variable(new_variable)
35+
flask_app = app.create_app(tax_benefit_system)
36+
```
37+
"""
38+
17039
# Create the test API client
171-
app = create_app(test_tax_benefit_system)
172-
return app.test_client()
40+
flask_app = app.create_app(tax_benefit_system)
41+
return flask_app.test_client()
17342

17443

17544
# /variables
@@ -182,7 +51,7 @@ def variables_response(test_client):
18251

18352

18453
def test_return_code(variables_response):
185-
assert variables_response.status_code == OK
54+
assert variables_response.status_code == client.OK
18655

18756

18857
def test_response_data(variables_response):
@@ -198,7 +67,7 @@ def test_response_data(variables_response):
19867

19968
def test_error_code_non_existing_variable(test_client):
20069
response = test_client.get('/variable/non_existing_variable')
201-
assert response.status_code == NOT_FOUND
70+
assert response.status_code == client.NOT_FOUND
20271

20372

20473
@pytest.fixture(scope="module")
@@ -208,7 +77,7 @@ def input_variable_response(test_client):
20877

20978

21079
def test_return_code_existing_input_variable(input_variable_response):
211-
assert input_variable_response.status_code == OK
80+
assert input_variable_response.status_code == client.OK
21281

21382

21483
def check_input_variable_value(key, expected_value, input_variable=None):
@@ -238,7 +107,7 @@ def test_input_variable_github_url(test_client):
238107

239108
def test_return_code_existing_variable(test_client):
240109
variable_response = test_client.get('/variable/income_tax')
241-
assert variable_response.status_code == OK
110+
assert variable_response.status_code == client.OK
242111

243112

244113
def check_variable_value(key, expected_value, variable=None):
@@ -306,7 +175,7 @@ def dated_variable_response(test_client):
306175

307176

308177
def test_return_code_existing_dated_variable(dated_variable_response):
309-
assert dated_variable_response.status_code == OK
178+
assert dated_variable_response.status_code == client.OK
310179

311180

312181
def test_dated_variable_formulas_dates(dated_variable_response):
@@ -327,7 +196,7 @@ def test_dated_variable_formulas_content(dated_variable_response):
327196

328197
def test_variable_encoding(test_client):
329198
variable_response = test_client.get('/variable/pension')
330-
assert variable_response.status_code == OK
199+
assert variable_response.status_code == client.OK
331200

332201

333202
def test_variable_documentation(test_client):

0 commit comments

Comments
 (0)