summaryrefslogtreecommitdiff
path: root/tests/model_fields/test_booleanfield.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/model_fields/test_booleanfield.py')
-rw-r--r--tests/model_fields/test_booleanfield.py119
1 files changed, 119 insertions, 0 deletions
diff --git a/tests/model_fields/test_booleanfield.py b/tests/model_fields/test_booleanfield.py
new file mode 100644
index 0000000000..2975f4723c
--- /dev/null
+++ b/tests/model_fields/test_booleanfield.py
@@ -0,0 +1,119 @@
+from django.core.exceptions import ValidationError
+from django.db import IntegrityError, connection, models, transaction
+from django.test import SimpleTestCase, TestCase
+
+from .models import BooleanModel, FksToBooleans, NullBooleanModel
+
+
+class BooleanFieldTests(TestCase):
+ def _test_get_db_prep_lookup(self, f):
+ 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_to_python(self, f):
+ self.assertIs(f.to_python(1), True)
+ self.assertIs(f.to_python(0), False)
+
+ 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_to_python(self):
+ self._test_to_python(models.BooleanField())
+
+ def test_nullbooleanfield_to_python(self):
+ self._test_to_python(models.NullBooleanField())
+
+ def test_booleanfield_choices_blank(self):
+ """
+ BooleanField with choices and defaults doesn't generate a formfield
+ with the blank option (#9640, #10549).
+ """
+ choices = [(1, 'Si'), (2, 'No')]
+ f = models.BooleanField(choices=choices, default=1, null=False)
+ self.assertEqual(f.formfield().choices, choices)
+
+ def test_return_type(self):
+ b = BooleanModel.objects.create(bfield=True)
+ b.refresh_from_db()
+ self.assertEqual(b.bfield, True)
+
+ b2 = BooleanModel.objects.create(bfield=False)
+ b2.refresh_from_db()
+ self.assertEqual(b2.bfield, False)
+
+ b3 = NullBooleanModel.objects.create(nbfield=True)
+ b3.refresh_from_db()
+ self.assertEqual(b3.nbfield, True)
+
+ b4 = NullBooleanModel.objects.create(nbfield=False)
+ b4.refresh_from_db()
+ self.assertEqual(b4.nbfield, False)
+
+ # When an extra clause exists, the boolean conversions are applied with
+ # an offset (#13293).
+ b5 = BooleanModel.objects.all().extra(select={'string_col': 'string'})[0]
+ self.assertNotIsInstance(b5.pk, bool)
+
+ def test_select_related(self):
+ """
+ Boolean fields retrieved via select_related() should return booleans.
+ """
+ bmt = BooleanModel.objects.create(bfield=True)
+ bmf = BooleanModel.objects.create(bfield=False)
+ nbmt = NullBooleanModel.objects.create(nbfield=True)
+ nbmf = NullBooleanModel.objects.create(nbfield=False)
+ m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
+ m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
+
+ # select_related('fk_field_name')
+ ma = FksToBooleans.objects.select_related('bf').get(pk=m1.id)
+ self.assertEqual(ma.bf.bfield, True)
+ self.assertEqual(ma.nbf.nbfield, True)
+
+ # select_related()
+ mb = FksToBooleans.objects.select_related().get(pk=m1.id)
+ mc = FksToBooleans.objects.select_related().get(pk=m2.id)
+ self.assertEqual(mb.bf.bfield, True)
+ self.assertEqual(mb.nbf.nbfield, True)
+ self.assertEqual(mc.bf.bfield, False)
+ self.assertEqual(mc.nbf.nbfield, False)
+
+ def test_null_default(self):
+ """
+ A BooleanField defaults to None, which isn't a valid value (#15124).
+ """
+ boolean_field = BooleanModel._meta.get_field('bfield')
+ self.assertFalse(boolean_field.has_default())
+ b = BooleanModel()
+ self.assertIsNone(b.bfield)
+ with transaction.atomic():
+ with self.assertRaises(IntegrityError):
+ b.save()
+
+ nb = NullBooleanModel()
+ self.assertIsNone(nb.nbfield)
+ nb.save() # no error
+
+
+class ValidationTest(SimpleTestCase):
+
+ def test_boolean_field_doesnt_accept_empty_input(self):
+ f = models.BooleanField()
+ with self.assertRaises(ValidationError):
+ f.clean(None, None)
+
+ def test_nullbooleanfield_blank(self):
+ """
+ NullBooleanField shouldn't throw a validation error when given a value
+ of None.
+ """
+ nullboolean = NullBooleanModel(nbfield=None)
+ nullboolean.full_clean()