summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2019-11-15 00:08:36 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-11-21 11:56:35 +0100
commite9a0e1d4f6ecfc4227acff74e1f56f288a0b30aa (patch)
treedeecc4f80b577d47f03e8ade90f410aa4cf32e07 /tests
parent37e6c5b79bd0529a3c85b8c478e4002fd33a2a1d (diff)
Fixed #30484 -- Added conditional expressions support to CheckConstraint.
Diffstat (limited to 'tests')
-rw-r--r--tests/constraints/models.py13
-rw-r--r--tests/constraints/tests.py21
-rw-r--r--tests/queries/test_query.py19
3 files changed, 51 insertions, 2 deletions
diff --git a/tests/constraints/models.py b/tests/constraints/models.py
index d207de6e73..cadeea887e 100644
--- a/tests/constraints/models.py
+++ b/tests/constraints/models.py
@@ -18,6 +18,19 @@ class Product(models.Model):
check=models.Q(price__gt=0),
name='%(app_label)s_%(class)s_price_gt_0',
),
+ models.CheckConstraint(
+ check=models.expressions.RawSQL(
+ 'price < %s', (1000,), output_field=models.BooleanField()
+ ),
+ name='%(app_label)s_price_lt_1000_raw',
+ ),
+ models.CheckConstraint(
+ check=models.expressions.ExpressionWrapper(
+ models.Q(price__gt=500) | models.Q(price__lt=500),
+ output_field=models.BooleanField()
+ ),
+ name='%(app_label)s_price_neq_500_wrap',
+ ),
]
diff --git a/tests/constraints/tests.py b/tests/constraints/tests.py
index 8e2eb11e2a..136060eb07 100644
--- a/tests/constraints/tests.py
+++ b/tests/constraints/tests.py
@@ -61,6 +61,13 @@ class CheckConstraintTests(TestCase):
"<CheckConstraint: check='{}' name='{}'>".format(check, name),
)
+ def test_invalid_check_types(self):
+ msg = (
+ 'CheckConstraint.check must be a Q instance or boolean expression.'
+ )
+ with self.assertRaisesMessage(TypeError, msg):
+ models.CheckConstraint(check=models.F('discounted_price'), name='check')
+
def test_deconstruction(self):
check = models.Q(price__gt=models.F('discounted_price'))
name = 'price_gt_discounted_price'
@@ -76,11 +83,25 @@ class CheckConstraintTests(TestCase):
with self.assertRaises(IntegrityError):
Product.objects.create(price=10, discounted_price=20)
+ @skipUnlessDBFeature('supports_table_check_constraints')
+ def test_database_constraint_expression(self):
+ Product.objects.create(price=999, discounted_price=5)
+ with self.assertRaises(IntegrityError):
+ Product.objects.create(price=1000, discounted_price=5)
+
+ @skipUnlessDBFeature('supports_table_check_constraints')
+ def test_database_constraint_expressionwrapper(self):
+ Product.objects.create(price=499, discounted_price=5)
+ with self.assertRaises(IntegrityError):
+ Product.objects.create(price=500, discounted_price=5)
+
@skipUnlessDBFeature('supports_table_check_constraints', 'can_introspect_check_constraints')
def test_name(self):
constraints = get_constraints(Product._meta.db_table)
for expected_name in (
'price_gt_discounted_price',
+ 'constraints_price_lt_1000_raw',
+ 'constraints_price_neq_500_wrap',
'constraints_product_price_gt_0',
):
with self.subTest(expected_name):
diff --git a/tests/queries/test_query.py b/tests/queries/test_query.py
index ecd9c96d8c..9d18b15f3c 100644
--- a/tests/queries/test_query.py
+++ b/tests/queries/test_query.py
@@ -1,8 +1,8 @@
from datetime import datetime
from django.core.exceptions import FieldError
-from django.db.models import CharField, F, Q
-from django.db.models.expressions import Col
+from django.db.models import BooleanField, CharField, F, Q
+from django.db.models.expressions import Col, Func
from django.db.models.fields.related_lookups import RelatedIsNull
from django.db.models.functions import Lower
from django.db.models.lookups import Exact, GreaterThan, IsNull, LessThan
@@ -129,3 +129,18 @@ class TestQuery(SimpleTestCase):
name_exact = where.children[0]
self.assertIsInstance(name_exact, Exact)
self.assertEqual(name_exact.rhs, "['a', 'b']")
+
+ def test_filter_conditional(self):
+ query = Query(Item)
+ where = query.build_where(Func(output_field=BooleanField()))
+ exact = where.children[0]
+ self.assertIsInstance(exact, Exact)
+ self.assertIsInstance(exact.lhs, Func)
+ self.assertIs(exact.rhs, True)
+
+ def test_filter_conditional_join(self):
+ query = Query(Item)
+ filter_expr = Func('note__note', output_field=BooleanField())
+ msg = 'Joined field references are not permitted in this query'
+ with self.assertRaisesMessage(FieldError, msg):
+ query.build_where(filter_expr)