1. import datetime
    
  2. import json
    
  3. 
    
  4. from django import forms
    
  5. from django.core import exceptions, serializers
    
  6. from django.db import models
    
  7. from django.test import SimpleTestCase, TestCase
    
  8. 
    
  9. from .models import DurationModel, NullDurationModel
    
  10. 
    
  11. 
    
  12. class TestSaveLoad(TestCase):
    
  13.     def test_simple_roundtrip(self):
    
  14.         duration = datetime.timedelta(microseconds=8999999999999999)
    
  15.         DurationModel.objects.create(field=duration)
    
  16.         loaded = DurationModel.objects.get()
    
  17.         self.assertEqual(loaded.field, duration)
    
  18. 
    
  19.     def test_create_empty(self):
    
  20.         NullDurationModel.objects.create()
    
  21.         loaded = NullDurationModel.objects.get()
    
  22.         self.assertIsNone(loaded.field)
    
  23. 
    
  24.     def test_fractional_seconds(self):
    
  25.         value = datetime.timedelta(seconds=2.05)
    
  26.         d = DurationModel.objects.create(field=value)
    
  27.         d.refresh_from_db()
    
  28.         self.assertEqual(d.field, value)
    
  29. 
    
  30. 
    
  31. class TestQuerying(TestCase):
    
  32.     @classmethod
    
  33.     def setUpTestData(cls):
    
  34.         cls.objs = [
    
  35.             DurationModel.objects.create(field=datetime.timedelta(days=1)),
    
  36.             DurationModel.objects.create(field=datetime.timedelta(seconds=1)),
    
  37.             DurationModel.objects.create(field=datetime.timedelta(seconds=-1)),
    
  38.         ]
    
  39. 
    
  40.     def test_exact(self):
    
  41.         self.assertSequenceEqual(
    
  42.             DurationModel.objects.filter(field=datetime.timedelta(days=1)),
    
  43.             [self.objs[0]],
    
  44.         )
    
  45. 
    
  46.     def test_gt(self):
    
  47.         self.assertCountEqual(
    
  48.             DurationModel.objects.filter(field__gt=datetime.timedelta(days=0)),
    
  49.             [self.objs[0], self.objs[1]],
    
  50.         )
    
  51. 
    
  52. 
    
  53. class TestSerialization(SimpleTestCase):
    
  54.     test_data = (
    
  55.         '[{"fields": {"field": "1 01:00:00"}, "model": "model_fields.durationmodel", '
    
  56.         '"pk": null}]'
    
  57.     )
    
  58. 
    
  59.     def test_dumping(self):
    
  60.         instance = DurationModel(field=datetime.timedelta(days=1, hours=1))
    
  61.         data = serializers.serialize("json", [instance])
    
  62.         self.assertEqual(json.loads(data), json.loads(self.test_data))
    
  63. 
    
  64.     def test_loading(self):
    
  65.         instance = list(serializers.deserialize("json", self.test_data))[0].object
    
  66.         self.assertEqual(instance.field, datetime.timedelta(days=1, hours=1))
    
  67. 
    
  68. 
    
  69. class TestValidation(SimpleTestCase):
    
  70.     def test_invalid_string(self):
    
  71.         field = models.DurationField()
    
  72.         with self.assertRaises(exceptions.ValidationError) as cm:
    
  73.             field.clean("not a datetime", None)
    
  74.         self.assertEqual(cm.exception.code, "invalid")
    
  75.         self.assertEqual(
    
  76.             cm.exception.message % cm.exception.params,
    
  77.             "“not a datetime” value has an invalid format. "
    
  78.             "It must be in [DD] [[HH:]MM:]ss[.uuuuuu] format.",
    
  79.         )
    
  80. 
    
  81. 
    
  82. class TestFormField(SimpleTestCase):
    
  83.     # Tests for forms.DurationField are in the forms_tests app.
    
  84. 
    
  85.     def test_formfield(self):
    
  86.         field = models.DurationField()
    
  87.         self.assertIsInstance(field.formfield(), forms.DurationField)