diff options
| author | Simon Charette <charette.s@gmail.com> | 2016-06-18 23:38:24 -0400 |
|---|---|---|
| committer | Simon Charette <charette.s@gmail.com> | 2016-07-08 12:35:34 -0400 |
| commit | 082c52dbedd76c312cebf3b23e04c449a94c20b6 (patch) | |
| tree | 0ae566d52a61ac42f5a918931684fd3779f045af /tests/db_functions/test_datetime.py | |
| parent | 90468079ec6f72a1b8b6a908d81d3201a3204b24 (diff) | |
Refs #25774, #26348 -- Allowed Trunc functions to operate with time fields.
Thanks Josh for the amazing testing setup and Tim for the review.
Diffstat (limited to 'tests/db_functions/test_datetime.py')
| -rw-r--r-- | tests/db_functions/test_datetime.py | 91 |
1 files changed, 88 insertions, 3 deletions
diff --git a/tests/db_functions/test_datetime.py b/tests/db_functions/test_datetime.py index 011db8bb88..e727ea5b7d 100644 --- a/tests/db_functions/test_datetime.py +++ b/tests/db_functions/test_datetime.py @@ -5,7 +5,7 @@ from unittest import skipIf from django.conf import settings from django.db import connection -from django.db.models import DateField, DateTimeField, IntegerField +from django.db.models import DateField, DateTimeField, IntegerField, TimeField from django.db.models.functions import ( Extract, ExtractDay, ExtractHour, ExtractMinute, ExtractMonth, ExtractSecond, ExtractWeekDay, ExtractYear, Trunc, TruncDate, TruncDay, @@ -353,18 +353,25 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) - with self.assertRaisesMessage(ValueError, 'output_field must be either DateField or DateTimeField'): + msg = 'output_field must be either DateField, TimeField, or DateTimeField' + with self.assertRaisesMessage(ValueError, msg): list(DTModel.objects.annotate(truncated=Trunc('start_datetime', 'year', output_field=IntegerField()))) - with self.assertRaisesMessage(AssertionError, "'name' isn't a DateField or DateTimeField."): + with self.assertRaisesMessage(AssertionError, "'name' isn't a DateField, TimeField, or DateTimeField."): list(DTModel.objects.annotate(truncated=Trunc('name', 'year', output_field=DateTimeField()))) with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): list(DTModel.objects.annotate(truncated=Trunc('start_date', 'second'))) + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=Trunc('start_time', 'month'))) + with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): list(DTModel.objects.annotate(truncated=Trunc('start_date', 'month', output_field=DateTimeField()))) + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=Trunc('start_time', 'second', output_field=DateTimeField()))) + def test_datetime_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( @@ -389,9 +396,24 @@ class DateFunctionTests(TestCase): lambda m: (m.start_datetime, m.truncated) ) + def test_time_kind(kind): + self.assertQuerysetEqual( + DTModel.objects.annotate( + truncated=Trunc('start_time', kind, output_field=TimeField()) + ).order_by('start_datetime'), + [ + (start_datetime, truncate_to(start_datetime.time(), kind)), + (end_datetime, truncate_to(end_datetime.time(), kind)) + ], + lambda m: (m.start_datetime, m.truncated) + ) + test_date_kind('year') test_date_kind('month') test_date_kind('day') + test_time_kind('hour') + test_time_kind('minute') + test_time_kind('second') test_datetime_kind('year') test_datetime_kind('month') test_datetime_kind('day') @@ -428,6 +450,12 @@ class DateFunctionTests(TestCase): ) self.assertEqual(DTModel.objects.filter(start_datetime=TruncYear('start_datetime')).count(), 1) + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=TruncYear('start_time'))) + + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=TruncYear('start_time', output_field=TimeField()))) + def test_trunc_month_func(self): start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321)) end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'month') @@ -454,6 +482,12 @@ class DateFunctionTests(TestCase): ) self.assertEqual(DTModel.objects.filter(start_datetime=TruncMonth('start_datetime')).count(), 1) + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=TruncMonth('start_time'))) + + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=TruncMonth('start_time', output_field=TimeField()))) + def test_trunc_date_func(self): start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321)) end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)) @@ -472,6 +506,12 @@ class DateFunctionTests(TestCase): ) self.assertEqual(DTModel.objects.filter(start_datetime__date=TruncDate('start_datetime')).count(), 2) + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateField"): + list(DTModel.objects.annotate(truncated=TruncDate('start_time'))) + + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateField"): + list(DTModel.objects.annotate(truncated=TruncDate('start_time', output_field=TimeField()))) + def test_trunc_day_func(self): start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321)) end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'day') @@ -490,6 +530,12 @@ class DateFunctionTests(TestCase): ) self.assertEqual(DTModel.objects.filter(start_datetime=TruncDay('start_datetime')).count(), 1) + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=TruncDay('start_time'))) + + with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): + list(DTModel.objects.annotate(truncated=TruncDay('start_time', output_field=TimeField()))) + def test_trunc_hour_func(self): start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321)) end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'hour') @@ -506,6 +552,14 @@ class DateFunctionTests(TestCase): ], lambda m: (m.start_datetime, m.extracted) ) + self.assertQuerysetEqual( + DTModel.objects.annotate(extracted=TruncHour('start_time')).order_by('start_datetime'), + [ + (start_datetime, truncate_to(start_datetime.time(), 'hour')), + (end_datetime, truncate_to(end_datetime.time(), 'hour')), + ], + lambda m: (m.start_datetime, m.extracted) + ) self.assertEqual(DTModel.objects.filter(start_datetime=TruncHour('start_datetime')).count(), 1) with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): @@ -530,6 +584,14 @@ class DateFunctionTests(TestCase): ], lambda m: (m.start_datetime, m.extracted) ) + self.assertQuerysetEqual( + DTModel.objects.annotate(extracted=TruncMinute('start_time')).order_by('start_datetime'), + [ + (start_datetime, truncate_to(start_datetime.time(), 'minute')), + (end_datetime, truncate_to(end_datetime.time(), 'minute')), + ], + lambda m: (m.start_datetime, m.extracted) + ) self.assertEqual(DTModel.objects.filter(start_datetime=TruncMinute('start_datetime')).count(), 1) with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): @@ -554,6 +616,14 @@ class DateFunctionTests(TestCase): ], lambda m: (m.start_datetime, m.extracted) ) + self.assertQuerysetEqual( + DTModel.objects.annotate(extracted=TruncSecond('start_time')).order_by('start_datetime'), + [ + (start_datetime, truncate_to(start_datetime.time(), 'second')), + (end_datetime, truncate_to(end_datetime.time(), 'second')) + ], + lambda m: (m.start_datetime, m.extracted) + ) result = 1 if connection.features.supports_microsecond_precision else 2 self.assertEqual(DTModel.objects.filter(start_datetime=TruncSecond('start_datetime')).count(), result) @@ -680,9 +750,24 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): lambda m: (m.start_datetime, m.truncated) ) + def test_time_kind(kind, tzinfo=melb): + self.assertQuerysetEqual( + DTModel.objects.annotate( + truncated=Trunc('start_time', kind, output_field=TimeField(), tzinfo=melb) + ).order_by('start_datetime'), + [ + (start_datetime, truncate_to(start_datetime.time(), kind)), + (end_datetime, truncate_to(end_datetime.time(), kind)) + ], + lambda m: (m.start_datetime, m.truncated) + ) + test_date_kind('year') test_date_kind('month') test_date_kind('day') + test_time_kind('hour') + test_time_kind('minute') + test_time_kind('second') test_datetime_kind('year') test_datetime_kind('month') test_datetime_kind('day') |
