summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2011-03-03 13:53:12 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2011-03-03 13:53:12 +0000
commit113a8c1f1c8de50b3192c3adbefd26b0067b1750 (patch)
tree9d82598f0b37e626c1a55985c33c3c5638ad1fb2 /tests
parenta97396948bdc68561a46229f8440b68a2ab79960 (diff)
[1.2.X] Fixed #12252 -- Ensure that queryset unions are commutative. Thanks to benreynwar for the report, and draft patch, and to Karen and Ramiro for the review eyeballs and patch updates.
Backport of r15726 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15727 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
-rw-r--r--tests/regressiontests/queries/models.py23
-rw-r--r--tests/regressiontests/queries/tests.py63
2 files changed, 85 insertions, 1 deletions
diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py
index 3b7a08aba2..d441433ba1 100644
--- a/tests/regressiontests/queries/models.py
+++ b/tests/regressiontests/queries/models.py
@@ -294,3 +294,26 @@ class Node(models.Model):
def __unicode__(self):
return u"%s" % self.num
+
+# Bug #12252
+class ObjectA(models.Model):
+ name = models.CharField(max_length=50)
+
+ def __unicode__(self):
+ return self.name
+
+class ObjectB(models.Model):
+ name = models.CharField(max_length=50)
+ objecta = models.ForeignKey(ObjectA)
+ number = models.PositiveSmallIntegerField()
+
+ def __unicode__(self):
+ return self.name
+
+class ObjectC(models.Model):
+ name = models.CharField(max_length=50)
+ objecta = models.ForeignKey(ObjectA)
+ objectb = models.ForeignKey(ObjectB)
+
+ def __unicode__(self):
+ return self.name
diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py
index a37d4fae11..ae1bdd36ee 100644
--- a/tests/regressiontests/queries/tests.py
+++ b/tests/regressiontests/queries/tests.py
@@ -14,7 +14,8 @@ from django.utils.datastructures import SortedDict
from models import (Annotation, Article, Author, Celebrity, Child, Cover, Detail,
DumbCategory, ExtraInfo, Fan, Item, LeafA, LoopX, LoopZ, ManagedModel,
Member, NamedCategory, Note, Number, Plaything, PointerA, Ranking, Related,
- Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten, Node)
+ Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten, Node, ObjectA, ObjectB,
+ ObjectC)
class BaseQuerysetTest(TestCase):
@@ -1566,6 +1567,66 @@ class ToFieldTests(TestCase):
[node1]
)
+class UnionTests(unittest.TestCase):
+ """
+ Tests for the union of two querysets. Bug #12252.
+ """
+ def setUp(self):
+ objectas = []
+ objectbs = []
+ objectcs = []
+ a_info = ['one', 'two', 'three']
+ for name in a_info:
+ o = ObjectA(name=name)
+ o.save()
+ objectas.append(o)
+ b_info = [('un', 1, objectas[0]), ('deux', 2, objectas[0]), ('trois', 3, objectas[2])]
+ for name, number, objecta in b_info:
+ o = ObjectB(name=name, number=number, objecta=objecta)
+ o.save()
+ objectbs.append(o)
+ c_info = [('ein', objectas[2], objectbs[2]), ('zwei', objectas[1], objectbs[1])]
+ for name, objecta, objectb in c_info:
+ o = ObjectC(name=name, objecta=objecta, objectb=objectb)
+ o.save()
+ objectcs.append(o)
+
+ def check_union(self, model, Q1, Q2):
+ filter = model.objects.filter
+ self.assertEqual(set(filter(Q1) | filter(Q2)), set(filter(Q1 | Q2)))
+ self.assertEqual(set(filter(Q2) | filter(Q1)), set(filter(Q1 | Q2)))
+
+ def test_A_AB(self):
+ Q1 = Q(name='two')
+ Q2 = Q(objectb__name='deux')
+ self.check_union(ObjectA, Q1, Q2)
+
+ def test_A_AB2(self):
+ Q1 = Q(name='two')
+ Q2 = Q(objectb__name='deux', objectb__number=2)
+ self.check_union(ObjectA, Q1, Q2)
+
+ def test_AB_ACB(self):
+ Q1 = Q(objectb__name='deux')
+ Q2 = Q(objectc__objectb__name='deux')
+ self.check_union(ObjectA, Q1, Q2)
+
+ def test_BAB_BAC(self):
+ Q1 = Q(objecta__objectb__name='deux')
+ Q2 = Q(objecta__objectc__name='ein')
+ self.check_union(ObjectB, Q1, Q2)
+
+ def test_BAB_BACB(self):
+ Q1 = Q(objecta__objectb__name='deux')
+ Q2 = Q(objecta__objectc__objectb__name='trois')
+ self.check_union(ObjectB, Q1, Q2)
+
+ def test_BA_BCA__BAB_BAC_BCA(self):
+ Q1 = Q(objecta__name='one', objectc__objecta__name='two')
+ Q2 = Q(objecta__objectc__name='ein', objectc__objecta__name='three', objecta__objectb__name='trois')
+ self.check_union(ObjectB, Q1, Q2)
+
+
# In Python 2.6 beta releases, exceptions raised in __len__ are swallowed
# (Python issue 1242657), so these cases return an empty list, rather than