summaryrefslogtreecommitdiff
path: root/tests/regressiontests/model_fields/tests.py
blob: f31193e2690ec5f6495f295128736eec1e8810f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import datetime
import unittest

import django.test
from django import forms
from django.db import models
from django.core.exceptions import ValidationError

from models import Foo, Bar, Whiz, BigD, BigS, Image, BigInt

try:
    from decimal import Decimal
except ImportError:
    from django.utils._decimal import Decimal


# If PIL available, do these tests.
if Image:
    from imagefield import \
            ImageFieldTests, \
            ImageFieldTwoDimensionsTests, \
            ImageFieldNoDimensionsTests, \
            ImageFieldOneDimensionTests, \
            ImageFieldDimensionsFirstTests, \
            ImageFieldUsingFileTests, \
            TwoImageFieldTests


class DecimalFieldTests(django.test.TestCase):
    def test_to_python(self):
        f = models.DecimalField(max_digits=4, decimal_places=2)
        self.assertEqual(f.to_python(3), Decimal("3"))
        self.assertEqual(f.to_python("3.14"), Decimal("3.14"))
        self.assertRaises(ValidationError, f.to_python, "abc")

    def test_default(self):
        f = models.DecimalField(default=Decimal("0.00"))
        self.assertEqual(f.get_default(), Decimal("0.00"))

    def test_format(self):
        f = models.DecimalField(max_digits=5, decimal_places=1)
        self.assertEqual(f._format(f.to_python(2)), u'2.0')
        self.assertEqual(f._format(f.to_python('2.6')), u'2.6')
        self.assertEqual(f._format(None), None)

    def test_get_db_prep_lookup(self):
        from django.db import connection
        f = models.DecimalField(max_digits=5, decimal_places=1)
        self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])

    def test_filter_with_strings(self):
        """
        We should be able to filter decimal fields using strings (#8023)
        """
        Foo.objects.create(id=1, a='abc', d=Decimal("12.34"))
        self.assertEqual(list(Foo.objects.filter(d=u'1.23')), [])

    def test_save_without_float_conversion(self):
        """
        Ensure decimals don't go through a corrupting float conversion during
        save (#5079).
        """
        bd = BigD(d="12.9")
        bd.save()
        bd = BigD.objects.get(pk=bd.pk)
        self.assertEqual(bd.d, Decimal("12.9"))

    def test_lookup_really_big_value(self):
        """
        Ensure that really big values can be used in a filter statement, even
        with older Python versions.
        """
        # This should not crash. That counts as a win for our purposes.
        Foo.objects.filter(d__gte=100000000000)

class ForeignKeyTests(django.test.TestCase):
    def test_callable_default(self):
        """Test the use of a lazy callable for ForeignKey.default"""
        a = Foo.objects.create(id=1, a='abc', d=Decimal("12.34"))
        b = Bar.objects.create(b="bcd")
        self.assertEqual(b.a, a)

class DateTimeFieldTests(unittest.TestCase):
    def test_datetimefield_to_python_usecs(self):
        """DateTimeField.to_python should support usecs"""
        f = models.DateTimeField()
        self.assertEqual(f.to_python('2001-01-02 03:04:05.000006'),
                         datetime.datetime(2001, 1, 2, 3, 4, 5, 6))
        self.assertEqual(f.to_python('2001-01-02 03:04:05.999999'),
                         datetime.datetime(2001, 1, 2, 3, 4, 5, 999999))

    def test_timefield_to_python_usecs(self):
        """TimeField.to_python should support usecs"""
        f = models.TimeField()
        self.assertEqual(f.to_python('01:02:03.000004'),
                         datetime.time(1, 2, 3, 4))
        self.assertEqual(f.to_python('01:02:03.999999'),
                         datetime.time(1, 2, 3, 999999))

class BooleanFieldTests(unittest.TestCase):
    def _test_get_db_prep_lookup(self, f):
        from django.db import connection
        self.assertEqual(f.get_db_prep_lookup('exact', True, connection=connection), [True])
        self.assertEqual(f.get_db_prep_lookup('exact', '1', connection=connection), [True])
        self.assertEqual(f.get_db_prep_lookup('exact', 1, connection=connection), [True])
        self.assertEqual(f.get_db_prep_lookup('exact', False, connection=connection), [False])
        self.assertEqual(f.get_db_prep_lookup('exact', '0', connection=connection), [False])
        self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False])
        self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])

    def test_booleanfield_get_db_prep_lookup(self):
        self._test_get_db_prep_lookup(models.BooleanField())

    def test_nullbooleanfield_get_db_prep_lookup(self):
        self._test_get_db_prep_lookup(models.NullBooleanField())

    def test_booleanfield_choices_blank(self):
        """
        Test that BooleanField with choices and defaults doesn't generate a
        formfield with the blank option (#9640, #10549).
        """
        choices = [(1, u'Si'), (2, 'No')]
        f = models.BooleanField(choices=choices, default=1, null=True)
        self.assertEqual(f.formfield().choices, [('', '---------')] + choices)

        f = models.BooleanField(choices=choices, default=1, null=False)
        self.assertEqual(f.formfield().choices, choices)

class ChoicesTests(django.test.TestCase):
    def test_choices_and_field_display(self):
        """
        Check that get_choices and get_flatchoices interact with
        get_FIELD_display to return the expected values (#7913).
        """
        self.assertEqual(Whiz(c=1).get_c_display(), 'First')    # A nested value
        self.assertEqual(Whiz(c=0).get_c_display(), 'Other')    # A top level value
        self.assertEqual(Whiz(c=9).get_c_display(), 9)          # Invalid value
        self.assertEqual(Whiz(c=None).get_c_display(), None)    # Blank value
        self.assertEqual(Whiz(c='').get_c_display(), '')        # Empty value

class SlugFieldTests(django.test.TestCase):
    def test_slugfield_max_length(self):
        """
        Make sure SlugField honors max_length (#9706)
        """
        bs = BigS.objects.create(s = 'slug'*50)
        bs = BigS.objects.get(pk=bs.pk)
        self.assertEqual(bs.s, 'slug'*50)

class BigIntegerFieldTests(django.test.TestCase):
    def test_limits(self):
        # Ensure that values that are right at the limits can be saved
        # and then retrieved without corruption. 
        maxval = 9223372036854775807
        minval = -maxval - 1
        BigInt.objects.create(value=maxval)
        qs = BigInt.objects.filter(value__gte=maxval)
        self.assertEqual(qs.count(), 1)
        self.assertEqual(qs[0].value, maxval)
        BigInt.objects.create(value=minval)
        qs = BigInt.objects.filter(value__lte=minval)
        self.assertEqual(qs.count(), 1)
        self.assertEqual(qs[0].value, minval)

    def test_types(self):
        b = BigInt(value = 0)
        self.assertTrue(isinstance(b.value, (int, long)))
        b.save()
        self.assertTrue(isinstance(b.value, (int, long)))
        b = BigInt.objects.all()[0]
        self.assertTrue(isinstance(b.value, (int, long)))

    def test_coercing(self):
        BigInt.objects.create(value ='10')
        b = BigInt.objects.get(value = '10')
        self.assertEqual(b.value, 10)