Skip to content

Commit

Permalink
fix age tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dhuser committed Apr 29, 2018
2 parents 605bc6d + eb57890 commit a59d9e1
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 115 deletions.
2 changes: 1 addition & 1 deletion smartvadhis2/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@ def days_to_years(days):

def years_to_days(years):
"""Convert years to days"""
return int(round((years * DAYS_IN_YEAR)))
return years * DAYS_IN_YEAR
50 changes: 17 additions & 33 deletions smartvadhis2/core/verbalautopsy.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
InterviewDateMissingWarning,
InterviewDateParseWarning
)
from .helpers import sanitize, is_uid, days_to_years, years_to_days, DAYS_IN_YEAR
from .helpers import sanitize, is_uid, years_to_days
from .mapping import Mapping, Sex, AgeCategory, Icd10, cause_of_death_option_code
from ..__version__ import __version__

Expand Down Expand Up @@ -103,6 +103,9 @@ def __getattr__(self, _):
"""Return None if instance attribute does not exist"""
return None

def keys(self):
return [k for k in dir(self) if not k.startswith('_') and not callable(self[k])]

def __str__(self):
"""Print VerbalAutopsy instance as JSON"""
return json.dumps(dict(self))
Expand All @@ -116,40 +119,21 @@ def age(self, value):
lower_limit = 0
upper_limit = 131
if value:
if 'days' in value:
try:
days = int(value.replace('days', '').strip())
except ValueError:
raise AgeParseError()
else:
if days < 0 or days > years_to_days(upper_limit):
raise AgeParseError()
self._age_days = days
self._age_years = days_to_years(days)
self._age = None

elif 'years' in value:
try:
years = int(value.replace('years', '').strip())
except ValueError:
raise AgeParseError()
else:
if years not in range(lower_limit, upper_limit):
raise AgeOutOfBoundsError()
else:
self._age_years = years
self._age_days = years_to_days(years)
self._age = None
else:
try:
f = float(value)
except ValueError:
raise AgeParseError()

if self._age_days <= 28:
self._age_category = AgeCategory.options['Neonate']
elif self._age_years <= 12:
self._age_category = AgeCategory.options['Child']
else:
self._age_category = AgeCategory.options['Adult']

if int(f) not in range(lower_limit, upper_limit):
raise AgeOutOfBoundsError()
else:
self._age = round(f, 2)
if years_to_days(f) <= 28:
self._age_category = AgeCategory.options['Neonate']
elif int(f) < 12:
self._age_category = AgeCategory.options['Child']
else:
self._age_category = AgeCategory.options['Adult']
else:
raise AgeMissingWarning()

Expand Down
15 changes: 3 additions & 12 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,14 @@ def test_csv_with_content_headers_only():


@pytest.mark.parametrize("years, expected", [
(1, 365),
(10, 3652),
(15, 5479)
(0.01, 3.652425),
(1, 365.2425),
(10, 3652.425)
])
def test_years_to_days(years, expected):
assert years_to_days(years) == expected


@pytest.mark.parametrize("days, expected", [
(365, 1),
(3652, 10),
(5479, 15)
])
def test_years_to_days(days, expected):
assert days_to_years(days) == expected


def test_read_csv():
data = file_testdata('smartva_test.csv')
assert os.path.exists(data)
Expand Down
117 changes: 48 additions & 69 deletions tests/test_verbalautopsy.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from smartvadhis2.core.exceptions.warnings import *
from smartvadhis2.core.mapping import *
from smartvadhis2.core.config import ODKConfig, SmartVAConfig
from smartvadhis2.core.verbalautopsy import VerbalAutopsy, Event, process_row_data, verbal_autopsy_factory, DAYS_IN_YEAR
from smartvadhis2.core.verbalautopsy import VerbalAutopsy, Event, process_row_data, verbal_autopsy_factory


class VaAbstractClass(object):
Expand All @@ -19,76 +19,54 @@ def va(self):

class TestAge(VaAbstractClass):

def test_va_age_years(self, va):
va.age = '22 years'
assert va.age_years == 22
assert va.age_days == 8035
assert va.age is None
def test_va_age(self, va):
va.age = '0.0273972602739726'
assert va.age == 0.03

def test_va_age_number_without_indicator(self, va):
with pytest.raises(AgeParseError):
va.age = '22'
def test_va_age_inaccurate(self, va):
va.age = '0.3'
assert va.age == 0.3

def test_va_age_days(self, va):
va.age = '12 days'
assert va.age_years == 0
assert va.age_days == 12
assert va.age is None
def test_va_age_int(self, va):
va.age = '12'
assert va.age == 12

def test_va_age_days_parse_error(self, va):
with pytest.raises(AgeParseError):
va.age = '12 days butrestiswrong'
va.age = '0.0273972602739726 butrestiswrong'

def test_va_age_years_out_of_bounds(self, va):
def test_va_age_out_of_bounds(self, va):
with pytest.raises(AgeOutOfBoundsError):
va.age = '140 years'
va.age = '140.021'
with pytest.raises(AgeOutOfBoundsError):
va.age = '-10 years'

def test_va_age_days_out_of_bounds(self, va):
with pytest.raises(AgeParseError):
va.age = '50000 days'
with pytest.raises(AgeParseError):
va.age = '-2 days'

def test_va_age_days_to_years(self, va):
va.age = '400 days'
assert va.age_years == 1
assert va.age_days == 400
assert va.age is None
va.age = '-10'

def test_va_age_invalid(self, va):
with pytest.raises(AgeParseError):
va.age = 'not an age'

with pytest.raises(AgeParseError):
va.age = 'not an age days'

with pytest.raises(AgeParseError):
va.age = 'not an age years'

with pytest.raises(AgeOutOfBoundsError):
va.age = '135 years'

def test_va_age_missing(self, va):
with pytest.raises(AgeMissingWarning):
va.age = ''

def test_va_age_category_adult(self, va):
va.age = '13 years'
assert va.age_years == 13
assert va.age_days == int(round(13 * DAYS_IN_YEAR))
def test_va_age_category_adult_lower(self, va):
va.age = '12.0'
assert va.age == 12.0
assert va.age_category == AgeCategory.options['Adult']

def test_va_age_category_child(self, va):
va.age = '10 years'
assert va.age_years == 10
assert va.age_days == int(round(10 * DAYS_IN_YEAR))
def test_va_age_category_child_upper(self, va):
va.age = '0.07939930320266672'
assert va.age == 0.08
assert va.age_category == AgeCategory.options['Child']

def test_va_age_category_child_lower(self, va):
va.age = '11.0111'
assert va.age == 11.01
assert va.age_category == AgeCategory.options['Child']

def test_va_age_category_neonate(self, va):
va.age = '12 days'
assert va.age_years == 0
assert va.age_days == 12
va.age = '0.07666139619567822'
assert va.age == 0.08
assert va.age_category == AgeCategory.options['Neonate']


Expand All @@ -107,7 +85,7 @@ class TestCauseOfDeath(VaAbstractClass):

def test_va_cause_of_death(self, va):
va.icd10 = 'B24'
va.age_in_years = 90
va.age = 90.34
va.age_category = 1
assert va.icd10 == 12
assert va.age_category == 1
Expand Down Expand Up @@ -267,30 +245,34 @@ def test_questionnaire_version(self, va):
class TestVAClassMethods(VaAbstractClass):

def test_getitem(self, va):
va.age = '22 years'
assert va['age_years'] == 22
va.age = '22.0'
assert va['age'] == 22.0

def test_setitem(self, va):
va['age'] = '22 years'
assert va.age_years == 22
va['age'] = '22.0'
assert va.age == 22.0

def test_getattr(self, va):
assert va.notexistent is None

"""
TODO
def test_str(self, capsys, va):
va.age = '22.0'
expected = {'age': 22.0}
va.icd10 = 'C16'
expected = {
'age': 22.0,
'age_category': 1,
'icd10': 15,
'cause_of_death': 131
}
print(va)
captured = capsys.readouterr()
assert captured.out == expected
"""
removed_nulls = {k: v for k, v in json.loads(captured.out).items() if v is not None}
assert removed_nulls == expected


def test_process_row_data():
data = {
'age': '22 years',
'age': '22.999',
'death_date': '2018-01-01',
'interview_date': '2018-02-01'
}
Expand All @@ -299,7 +281,7 @@ def test_process_row_data():

from collections import OrderedDict
exp = OrderedDict(sorted({
Age.code_name: '22 years',
Age.code_name: '22.999',
BirthDate.code_name: None,
FirstName.code_name: None,
FirstName2nd.code_name: None,
Expand All @@ -321,7 +303,7 @@ def test_process_row_data():

def test_verbal_autopsy_factory_full():
data = {
Age.csv_name: '22 years',
Age.csv_name: '22.01231',
BirthDate.csv_name: '1990-01-01',
CauseCode.csv_name: '23',
CauseOfDeath.csv_name: '1',
Expand All @@ -338,10 +320,8 @@ def test_verbal_autopsy_factory_full():
}
va, exc, w = verbal_autopsy_factory(data)
assert isinstance(va, VerbalAutopsy)
assert va.age_years == 22
assert va.age_days == 8035
assert va.age == 22.01
assert va.age_category == 1
assert va.age is None
assert va.birth_date == '1990-01-01'
assert va.cause_of_death == 101
assert va.first_name == 'Toni'
Expand Down Expand Up @@ -386,7 +366,7 @@ class TestEvent(object):
@pytest.fixture
def va(self):
va_instance = VerbalAutopsy()
va_instance.age_years = 22
va_instance.age = 22.03
va_instance.age_category = 1
va_instance.birth_date = '1990-01-01'
va_instance.icd10 = 'B24'
Expand Down Expand Up @@ -415,8 +395,7 @@ def test_event_datavalues(self, va):
ev = Event(va)

expected = [
{"dataElement": AgeInYears.dhis_uid, "value": 22},
{"dataElement": AgeInDays.dhis_uid, "value": 8035},
{"dataElement": Age.dhis_uid, "value": 22.03},
{"dataElement": AgeCategory.dhis_uid, "value": AgeCategory.options["Adult"]},
{"dataElement": CauseOfDeath.dhis_uid, "value": 101},
{"dataElement": BirthDate.dhis_uid, "value": "1990-01-01"},
Expand Down

0 comments on commit a59d9e1

Please sign in to comment.