Fixed #23567 -- Made assertQuerysetEqual check Counter equality when ordered=False

This commit is contained in:
Thomas Chaumeny 2014-09-29 17:17:44 +02:00 committed by Simon Charette
parent df578bf175
commit 311b3ad9db
3 changed files with 47 additions and 4 deletions

View File

@ -1,5 +1,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from collections import Counter
from copy import copy from copy import copy
import difflib import difflib
import errno import errno
@ -871,7 +872,7 @@ class TransactionTestCase(SimpleTestCase):
def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True, msg=None): def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True, msg=None):
items = six.moves.map(transform, qs) items = six.moves.map(transform, qs)
if not ordered: if not ordered:
return self.assertEqual(set(items), set(values), msg=msg) return self.assertEqual(Counter(items), Counter(values), msg=msg)
values = list(values) values = list(values)
# For example qs.iterator() could be passed as qs, but it does not # For example qs.iterator() could be passed as qs, but it does not
# have 'ordered' attribute. # have 'ordered' attribute.

View File

@ -1,10 +1,25 @@
from django.db import models from django.db import models
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible @python_2_unicode_compatible
class Person(models.Model): class Car(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
def __str__(self): def __str__(self):
return self.name return self.name
@python_2_unicode_compatible
class Person(models.Model):
name = models.CharField(max_length=100)
cars = models.ManyToManyField(Car, through='PossessedCar')
def __str__(self):
return self.name
@python_2_unicode_compatible
class PossessedCar(models.Model):
car = models.ForeignKey(Car)
belongs_to = models.ForeignKey(Person)
def __str__(self):
return self.color

View File

@ -14,7 +14,7 @@ from django.test.html import HTMLParseError, parse_html
from django.test.utils import CaptureQueriesContext, override_settings from django.test.utils import CaptureQueriesContext, override_settings
from django.utils import six from django.utils import six
from .models import Person from .models import Car, Person, PossessedCar
from .views import empty_response from .views import empty_response
@ -178,6 +178,33 @@ class AssertQuerysetEqualTests(TestCase):
[repr(self.p1)] [repr(self.p1)]
) )
def test_repeated_values(self):
"""
Test that assertQuerysetEqual checks the number of appearance of each item
when used with option ordered=False.
"""
batmobile = Car.objects.create(name='Batmobile')
k2000 = Car.objects.create(name='K 2000')
PossessedCar.objects.bulk_create([
PossessedCar(car=batmobile, belongs_to=self.p1),
PossessedCar(car=batmobile, belongs_to=self.p1),
PossessedCar(car=k2000, belongs_to=self.p1),
PossessedCar(car=k2000, belongs_to=self.p1),
PossessedCar(car=k2000, belongs_to=self.p1),
PossessedCar(car=k2000, belongs_to=self.p1),
])
with self.assertRaises(AssertionError):
self.assertQuerysetEqual(
self.p1.cars.all(),
[repr(batmobile), repr(k2000)],
ordered=False
)
self.assertQuerysetEqual(
self.p1.cars.all(),
[repr(batmobile)] * 2 + [repr(k2000)] * 4,
ordered=False
)
@override_settings(ROOT_URLCONF='test_utils.urls') @override_settings(ROOT_URLCONF='test_utils.urls')
class CaptureQueriesContextManagerTests(TestCase): class CaptureQueriesContextManagerTests(TestCase):