From adcd94a469dde857a9a57620cee5d38f4eb59b9f Mon Sep 17 00:00:00 2001 From: Reed Martz Date: Fri, 23 Dec 2016 16:40:20 -0500 Subject: [PATCH] Add unit tests for query range generation --- .../indicators/query_ranges.py | 19 ++++-- .../indicators/tests/test_query_ranges.py | 68 +++++++++++++++++++ 2 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 django/climate_change_api/indicators/tests/test_query_ranges.py diff --git a/django/climate_change_api/indicators/query_ranges.py b/django/climate_change_api/indicators/query_ranges.py index 3d947422..5826ac01 100644 --- a/django/climate_change_api/indicators/query_ranges.py +++ b/django/climate_change_api/indicators/query_ranges.py @@ -70,7 +70,7 @@ def cases(cls): for config in cls.range_config: case_whens = [When(**{ 'day_of_year__gte': case.start, - 'day_of_year__lte': case.start + case.length, + 'day_of_year__lt': case.start + case.length, 'then': Value(case.index) }) for case in config['ranges']] year_whens.append(When(data_source__year__in=config['years'], then=Case(*case_whens))) @@ -88,7 +88,7 @@ class LengthRangeConfig(QueryRangeConfig): @classmethod def get_intervals(cls, label): lengths = cls.lengths[label] - return [(sum(lengths[:i]), lengths[i]) for i in range(len(lengths))] + return [(sum(lengths[:i]) + 1, lengths[i]) for i in range(len(lengths))] class MonthRangeConfig(LengthRangeConfig): @@ -130,9 +130,16 @@ def day_of_year_from_date(cls, date, label): @classmethod def get_intervals(cls, label): - for span in cls.custom_spans: + spans = [tuple(tuple(int(v) for v in date.split('-')) + for date in span.split(':')) + for span in cls.custom_spans.split(',')] + + for span in spans: start, end = (cls.day_of_year_from_date(date, label) for date in span) - yield (start, end - start) + assert (start <= end), "Dates must be paired start:end" + + # Add one to end date because the end point is inclusive + yield (start, end - start + 1) @classmethod def cases(cls, intervals): @@ -141,8 +148,6 @@ def cases(cls, intervals): if cls.custom_spans != intervals: cls.range_config = None # Spans are in the format MM-DD:MM-DD, so break those into nested tuples - cls.custom_spans = [tuple(tuple(int(v) for v in date.split('-')) - for date in span.split(':')) - for span in intervals.split(',')] + cls.custom_spans = intervals return super(CustomRangeConfig, cls).cases() diff --git a/django/climate_change_api/indicators/tests/test_query_ranges.py b/django/climate_change_api/indicators/tests/test_query_ranges.py new file mode 100644 index 00000000..3227179d --- /dev/null +++ b/django/climate_change_api/indicators/tests/test_query_ranges.py @@ -0,0 +1,68 @@ +from django.test import TestCase +from indicators.query_ranges import MonthRangeConfig, QuarterRangeConfig, CustomRangeConfig + + +class QuarterQueryRangeTestCase(TestCase): + def test_non_leap_year(self): + intervals = QuarterRangeConfig.get_intervals('noleap') + self.assertEqual(intervals, [(1, 90), (91, 91), (182, 92), (274, 92)]) + + def test_leap_year(self): + intervals = QuarterRangeConfig.get_intervals('leap') + self.assertEqual(intervals, [(1, 91), (92, 91), (183, 92), (275, 92)]) + + +class MonthQueryRangeTestCase(TestCase): + def test_non_leap_year(self): + intervals = MonthRangeConfig.get_intervals('noleap') + self.assertEqual(intervals, [(1, 31), + (32, 28), + (60, 31), + (91, 30), + (121, 31), + (152, 30), + (182, 31), + (213, 31), + (244, 30), + (274, 31), + (305, 30), + (335, 31)]) + + def test_leap_year(self): + intervals = MonthRangeConfig.get_intervals('leap') + self.assertEqual(intervals, [(1, 31), + (32, 29), + (61, 31), + (92, 30), + (122, 31), + (153, 30), + (183, 31), + (214, 31), + (245, 30), + (275, 31), + (306, 30), + (336, 31)]) + + +class CustomQueryRangeTestCase(TestCase): + def test_non_leap_year(self): + CustomRangeConfig.custom_spans = "1-1:12-31" + intervals = list(CustomRangeConfig.get_intervals('noleap')) + self.assertEqual(intervals, [(1, 365)]) + + CustomRangeConfig.custom_spans = "5-13:5-31,7-8:12-14" + intervals = list(CustomRangeConfig.get_intervals('noleap')) + self.assertEqual(intervals, [(133, 19), (189, 160)]) + + def test_invalid(self): + with self.assertRaises(AssertionError): + CustomRangeConfig.custom_spans = "1-56:1-57" + list(CustomRangeConfig.get_intervals('noleap')) + + with self.assertRaises(AssertionError): + CustomRangeConfig.custom_spans = "7-0:9-2" + list(CustomRangeConfig.get_intervals('noleap')) + + with self.assertRaises(AssertionError): + CustomRangeConfig.custom_spans = "7-1:5-1" + list(CustomRangeConfig.get_intervals('noleap'))