diff options
| author | Anssi Kääriäinen <akaariai@gmail.com> | 2012-12-13 13:33:11 +0200 |
|---|---|---|
| committer | Anssi Kääriäinen <akaariai@gmail.com> | 2012-12-13 13:33:11 +0200 |
| commit | 088d3bc2f84b6b68fee7e5de053b58049bd110e7 (patch) | |
| tree | ecb350eeba16a0b05c131008a552a91f23644e95 | |
| parent | 6ed6a18a033ba78de9418f5b56b80f8b3d3aaf11 (diff) | |
Fixed #19462 -- Made assertQuerysetEqual detect undefined ordering
If there are more than one values to compare against and the qs isn't
ordered then assertQuerysetEqual will raise a ValueError.
| -rw-r--r-- | django/test/testcases.py | 6 | ||||
| -rw-r--r-- | docs/releases/1.6.txt | 5 | ||||
| -rw-r--r-- | docs/topics/testing.txt | 5 | ||||
| -rw-r--r-- | tests/modeltests/expressions/tests.py | 4 | ||||
| -rw-r--r-- | tests/modeltests/field_subclassing/tests.py | 3 | ||||
| -rw-r--r-- | tests/modeltests/fixtures/tests.py | 14 | ||||
| -rw-r--r-- | tests/modeltests/generic_relations/tests.py | 6 | ||||
| -rw-r--r-- | tests/modeltests/m2m_recursive/tests.py | 27 | ||||
| -rw-r--r-- | tests/modeltests/many_to_one/tests.py | 8 | ||||
| -rw-r--r-- | tests/modeltests/model_forms/tests.py | 9 | ||||
| -rw-r--r-- | tests/regressiontests/expressions_regress/tests.py | 37 | ||||
| -rw-r--r-- | tests/regressiontests/extra_regress/tests.py | 9 | ||||
| -rw-r--r-- | tests/regressiontests/m2m_regress/tests.py | 2 | ||||
| -rw-r--r-- | tests/regressiontests/m2m_through_regress/tests.py | 9 | ||||
| -rw-r--r-- | tests/regressiontests/managers_regress/tests.py | 3 | ||||
| -rw-r--r-- | tests/regressiontests/model_regress/tests.py | 9 | ||||
| -rw-r--r-- | tests/regressiontests/queries/tests.py | 37 | ||||
| -rw-r--r-- | tests/regressiontests/test_utils/models.py | 6 | ||||
| -rw-r--r-- | tests/regressiontests/test_utils/tests.py | 40 |
19 files changed, 171 insertions, 68 deletions
diff --git a/django/test/testcases.py b/django/test/testcases.py index f673a10d08..3af6b8c346 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -767,6 +767,12 @@ class TransactionTestCase(SimpleTestCase): items = six.moves.map(transform, qs) if not ordered: return self.assertEqual(set(items), set(values)) + values = list(values) + # For example qs.iterator() could be passed as qs, but it does not + # have 'ordered' attribute. + if len(values) > 1 and hasattr(qs, 'ordered') and not qs.ordered: + raise ValueError("Trying to compare non-ordered queryset " + "against more than one ordered values") return self.assertEqual(list(items), values) def assertNumQueries(self, num, func=None, *args, **kwargs): diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 49649bc6b8..1f57913397 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -23,6 +23,11 @@ Minor features * Authentication backends can raise ``PermissionDenied`` to immediately fail the authentication chain. +* The ``assertQuerysetEqual()`` now checks for undefined order and raises + ``ValueError`` if undefined order is spotted. The order is seen as + undefined if the given ``QuerySet`` isn't ordered and there are more than + one ordered values to compare against. + Backwards incompatible changes in 1.6 ===================================== diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt index a1524e4f15..a52e4fe169 100644 --- a/docs/topics/testing.txt +++ b/docs/topics/testing.txt @@ -1770,6 +1770,11 @@ your test suite. via an explicit ``order_by()`` call on the queryset prior to comparison. + .. versionchanged:: 1.6 + The method now checks for undefined order and raises ``ValueError`` + if undefined order is spotted. The ordering is seen as undefined if + the given ``qs`` isn't ordered and the comparison is against more + than one ordered values. .. method:: TestCase.assertNumQueries(num, func, *args, **kwargs) diff --git a/tests/modeltests/expressions/tests.py b/tests/modeltests/expressions/tests.py index ca47521ccd..a351496442 100644 --- a/tests/modeltests/expressions/tests.py +++ b/tests/modeltests/expressions/tests.py @@ -158,6 +158,7 @@ class ExpressionsTests(TestCase): "Max Mustermann", ], lambda c: six.text_type(c.point_of_contact), + ordered=False ) c = Company.objects.all()[0] @@ -170,7 +171,8 @@ class ExpressionsTests(TestCase): "Foobar Ltd.", "Test GmbH", ], - lambda c: c.name + lambda c: c.name, + ordered=False ) Company.objects.exclude( diff --git a/tests/modeltests/field_subclassing/tests.py b/tests/modeltests/field_subclassing/tests.py index 48755123f2..0ec317dea5 100644 --- a/tests/modeltests/field_subclassing/tests.py +++ b/tests/modeltests/field_subclassing/tests.py @@ -77,7 +77,8 @@ class CustomField(TestCase): "12", "23", ], - lambda m: str(m.data) + lambda m: str(m.data), + ordered=False ) def test_field_subclassing(self): diff --git a/tests/modeltests/fixtures/tests.py b/tests/modeltests/fixtures/tests.py index b667c8c6d4..415ed6dcf2 100644 --- a/tests/modeltests/fixtures/tests.py +++ b/tests/modeltests/fixtures/tests.py @@ -96,8 +96,8 @@ class FixtureLoadingTests(TestCase): management.call_command('loaddata', 'fixture6.json', verbosity=0, commit=False) self.assertQuerysetEqual(Tag.objects.all(), [ '<Tag: <Article: Copyright is fine the way it is> tagged "copyright">', - '<Tag: <Article: Copyright is fine the way it is> tagged "law">' - ]) + '<Tag: <Article: Copyright is fine the way it is> tagged "law">', + ], ordered=False) # Load fixture 7, XML file with dynamic ContentType fields. Testing ManyToOne. management.call_command('loaddata', 'fixture7.xml', verbosity=0, commit=False) @@ -105,8 +105,8 @@ class FixtureLoadingTests(TestCase): '<Tag: <Article: Copyright is fine the way it is> tagged "copyright">', '<Tag: <Article: Copyright is fine the way it is> tagged "legal">', '<Tag: <Article: Django conquers world!> tagged "django">', - '<Tag: <Article: Django conquers world!> tagged "world domination">' - ]) + '<Tag: <Article: Django conquers world!> tagged "world domination">', + ], ordered=False) # Load fixture 8, JSON file with dynamic Permission fields. Testing ManyToMany. management.call_command('loaddata', 'fixture8.json', verbosity=0, commit=False) @@ -114,7 +114,7 @@ class FixtureLoadingTests(TestCase): '<Visa: Django Reinhardt Can add user, Can change user, Can delete user>', '<Visa: Stephane Grappelli Can add user>', '<Visa: Prince >' - ]) + ], ordered=False) # Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany. management.call_command('loaddata', 'fixture9.xml', verbosity=0, commit=False) @@ -122,7 +122,7 @@ class FixtureLoadingTests(TestCase): '<Visa: Django Reinhardt Can add user, Can change user, Can delete user>', '<Visa: Stephane Grappelli Can add user, Can delete user>', '<Visa: Artist formerly known as "Prince" Can change user>' - ]) + ], ordered=False) self.assertQuerysetEqual(Book.objects.all(), [ '<Book: Achieving self-awareness of Python programs>', @@ -280,7 +280,7 @@ class FixtureLoadingTests(TestCase): self.assertQuerysetEqual(Tag.objects.all(), [ '<Tag: <Article: Time to reform copyright> tagged "copyright">', '<Tag: <Article: Time to reform copyright> tagged "law">' - ]) + ], ordered=False) # Dump the current contents of the database as a JSON fixture self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16T12:00:00"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16T13:00:00"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "law", "tagged_id": 3}}, {"pk": 1, "model": "fixtures.person", "fields": {"name": "Django Reinhardt"}}, {"pk": 2, "model": "fixtures.person", "fields": {"name": "Stephane Grappelli"}}, {"pk": 3, "model": "fixtures.person", "fields": {"name": "Prince"}}, {"pk": 10, "model": "fixtures.book", "fields": {"name": "Achieving self-awareness of Python programs", "authors": []}}]', natural_keys=True) diff --git a/tests/modeltests/generic_relations/tests.py b/tests/modeltests/generic_relations/tests.py index 14871e4e09..73b0a483a2 100644 --- a/tests/modeltests/generic_relations/tests.py +++ b/tests/modeltests/generic_relations/tests.py @@ -169,8 +169,8 @@ class GenericRelationsTests(TestCase): # Filtering works self.assertQuerysetEqual(tiger.comparisons.filter(comparative="cooler"), [ "<Comparison: tiger is cooler than cheetah>", - "<Comparison: tiger is cooler than bear>" - ]) + "<Comparison: tiger is cooler than bear>", + ], ordered=False) # Filtering and deleting works subjective = ["cooler"] @@ -178,7 +178,7 @@ class GenericRelationsTests(TestCase): self.assertQuerysetEqual(Comparison.objects.all(), [ "<Comparison: cheetah is faster than tiger>", "<Comparison: tiger is stronger than cheetah>" - ]) + ], ordered=False) # If we delete cheetah, Comparisons with cheetah as 'first_obj' will be # deleted since Animal has an explicit GenericRelation to Comparison diff --git a/tests/modeltests/m2m_recursive/tests.py b/tests/modeltests/m2m_recursive/tests.py index 5742836929..a3f2c670d6 100644 --- a/tests/modeltests/m2m_recursive/tests.py +++ b/tests/modeltests/m2m_recursive/tests.py @@ -28,7 +28,8 @@ class RecursiveM2MTests(TestCase): "Chuck", "David" ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Who is friends with Bill? self.assertQuerysetEqual( @@ -43,7 +44,8 @@ class RecursiveM2MTests(TestCase): "Anne", "David" ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Who is friends with David? self.assertQuerysetEqual( @@ -51,7 +53,8 @@ class RecursiveM2MTests(TestCase): "Anne", "Chuck", ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Bill is already friends with Anne - add Anne again, but in the # reverse direction @@ -64,7 +67,8 @@ class RecursiveM2MTests(TestCase): "Chuck", "David", ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Who is friends with Bill? self.assertQuerysetEqual( @@ -81,7 +85,8 @@ class RecursiveM2MTests(TestCase): "Chuck", "David", ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Who is friends with Bill? self.assertQuerysetEqual( @@ -125,7 +130,8 @@ class RecursiveM2MTests(TestCase): "Chuck", "David", ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Who is stalking Anne? self.assertQuerysetEqual( @@ -172,7 +178,8 @@ class RecursiveM2MTests(TestCase): "Anne", "Chuck", ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Bill is already being stalked by Anne - add Anne again, but in the # reverse direction @@ -184,7 +191,8 @@ class RecursiveM2MTests(TestCase): "Chuck", "David", ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Who is stalking Anne? self.assertQuerysetEqual( @@ -215,7 +223,8 @@ class RecursiveM2MTests(TestCase): "Chuck", "David", ], - attrgetter("name") + attrgetter("name"), + ordered=False ) # Who is stalking Anne? self.assertQuerysetEqual( diff --git a/tests/modeltests/many_to_one/tests.py b/tests/modeltests/many_to_one/tests.py index 4fb19dbc69..44ae689dd4 100644 --- a/tests/modeltests/many_to_one/tests.py +++ b/tests/modeltests/many_to_one/tests.py @@ -267,7 +267,9 @@ class ManyToOneTests(TestCase): ["<Reporter: John Smith>"]) self.assertQuerysetEqual( Reporter.objects.filter(article__headline__startswith='T'), - ["<Reporter: John Smith>", "<Reporter: John Smith>"]) + ["<Reporter: John Smith>", "<Reporter: John Smith>"], + ordered=False + ) self.assertQuerysetEqual( Reporter.objects.filter(article__headline__startswith='T').distinct(), ["<Reporter: John Smith>"]) @@ -285,7 +287,9 @@ class ManyToOneTests(TestCase): "<Reporter: John Smith>", "<Reporter: John Smith>", "<Reporter: John Smith>", - ]) + ], + ordered=False + ) self.assertQuerysetEqual( Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct(), ["<Reporter: John Smith>"]) diff --git a/tests/modeltests/model_forms/tests.py b/tests/modeltests/model_forms/tests.py index 47d72abdc2..9699b155c0 100644 --- a/tests/modeltests/model_forms/tests.py +++ b/tests/modeltests/model_forms/tests.py @@ -1044,9 +1044,12 @@ class OldFormForXTests(TestCase): self.assertQuerysetEqual(f.clean([c1.id]), ["Entertainment"]) self.assertQuerysetEqual(f.clean([c2.id]), ["It's a test"]) self.assertQuerysetEqual(f.clean([str(c1.id)]), ["Entertainment"]) - self.assertQuerysetEqual(f.clean([str(c1.id), str(c2.id)]), ["Entertainment", "It's a test"]) - self.assertQuerysetEqual(f.clean([c1.id, str(c2.id)]), ["Entertainment", "It's a test"]) - self.assertQuerysetEqual(f.clean((c1.id, str(c2.id))), ["Entertainment", "It's a test"]) + self.assertQuerysetEqual(f.clean([str(c1.id), str(c2.id)]), ["Entertainment", "It's a test"], + ordered=False) + self.assertQuerysetEqual(f.clean([c1.id, str(c2.id)]), ["Entertainment", "It's a test"], + ordered=False) + self.assertQuerysetEqual(f.clean((c1.id, str(c2.id))), ["Entertainment", "It's a test"], + ordered=False) with self.assertRaises(ValidationError): f.clean(['100']) with self.assertRaises(ValidationError): diff --git a/tests/regressiontests/expressions_regress/tests.py b/tests/regressiontests/expressions_regress/tests.py index 508a497151..ddb2c83b4f 100644 --- a/tests/regressiontests/expressions_regress/tests.py +++ b/tests/regressiontests/expressions_regress/tests.py @@ -26,12 +26,13 @@ class ExpressionsRegressTests(TestCase): same object. """ self.assertQuerysetEqual( - Number.objects.all(), - [ - '<Number: -1, -1.000>', - '<Number: 42, 42.000>', - '<Number: 1337, 1337.000>' - ] + Number.objects.all(), + [ + '<Number: -1, -1.000>', + '<Number: 42, 42.000>', + '<Number: 1337, 1337.000>' + ], + ordered=False ) def test_increment_value(self): @@ -44,12 +45,13 @@ class ExpressionsRegressTests(TestCase): 2) self.assertQuerysetEqual( - Number.objects.all(), - [ - '<Number: -1, -1.000>', - '<Number: 43, 42.000>', - '<Number: 1338, 1337.000>' - ] + Number.objects.all(), + [ + '<Number: -1, -1.000>', + '<Number: 43, 42.000>', + '<Number: 1338, 1337.000>' + ], + ordered=False ) def test_filter_not_equals_other_field(self): @@ -62,11 +64,12 @@ class ExpressionsRegressTests(TestCase): .update(integer=F('integer') + 1), 2) self.assertQuerysetEqual( - Number.objects.exclude(float=F('integer')), - [ - '<Number: 43, 42.000>', - '<Number: 1338, 1337.000>' - ] + Number.objects.exclude(float=F('integer')), + [ + '<Number: 43, 42.000>', + '<Number: 1338, 1337.000>' + ], + ordered=False ) def test_complex_expressions(self): diff --git a/tests/regressiontests/extra_regress/tests.py b/tests/regressiontests/extra_regress/tests.py index f591900afe..1bc6789edd 100644 --- a/tests/regressiontests/extra_regress/tests.py +++ b/tests/regressiontests/extra_regress/tests.py @@ -58,13 +58,15 @@ class ExtraRegressTests(TestCase): ('First Revision', 'First Revision'), ('Second Revision', 'First Revision'), ], - transform=lambda r: (r.title, r.base.title) + transform=lambda r: (r.title, r.base.title), + ordered=False ) # Following queryset should return the most recent revision: self.assertQuerysetEqual(qs & qs2, [('Second Revision', 'First Revision')], - transform=lambda r: (r.title, r.base.title) + transform=lambda r: (r.title, r.base.title), + ordered=False ) def test_extra_stay_tied(self): @@ -342,5 +344,6 @@ class ExtraRegressTests(TestCase): TestObject.objects.extra( where=["first = 'a' OR second = 'a'", "third = 'a'"], ), - ['<TestObject: TestObject: a,a,a>', '<TestObject: TestObject: b,a,a>'] + ['<TestObject: TestObject: a,a,a>', '<TestObject: TestObject: b,a,a>'], + ordered=False ) diff --git a/tests/regressiontests/m2m_regress/tests.py b/tests/regressiontests/m2m_regress/tests.py index c39d883de4..3dc1d2417c 100644 --- a/tests/regressiontests/m2m_regress/tests.py +++ b/tests/regressiontests/m2m_regress/tests.py @@ -74,7 +74,7 @@ class M2MRegressionTests(TestCase): c1.tags = [t1, t2] c1 = TagCollection.objects.get(name='c1') - self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"]) + self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"], ordered=False) self.assertQuerysetEqual(t1.tag_collections.all(), ["<TagCollection: c1>"]) def test_manager_class_caching(self): diff --git a/tests/regressiontests/m2m_through_regress/tests.py b/tests/regressiontests/m2m_through_regress/tests.py index eba956b3ba..17a4525442 100644 --- a/tests/regressiontests/m2m_through_regress/tests.py +++ b/tests/regressiontests/m2m_through_regress/tests.py @@ -28,7 +28,8 @@ class M2MThroughTestCase(TestCase): bob.group_set.all(), [ "<Group: Rock>", "<Group: Roll>", - ] + ], + ordered=False ) self.assertQuerysetEqual( @@ -51,7 +52,8 @@ class M2MThroughTestCase(TestCase): frank.group_set.all(), [ "<Group: Rock>", "<Group: Roll>", - ] + ], + ordered=False ) self.assertQuerysetEqual( @@ -190,7 +192,8 @@ class ToFieldThroughTests(TestCase): self.driver.car_set._add_items('driver', 'car', car2) self.assertQuerysetEqual( self.driver.car_set.all(), - ["<Car: Toyota>", "<Car: Honda>"] + ["<Car: Toyota>", "<Car: Honda>"], + ordered=False ) def test_add_null_reverse(self): diff --git a/tests/regressiontests/managers_regress/tests.py b/tests/regressiontests/managers_regress/tests.py index f3721a4c01..45059be4e5 100644 --- a/tests/regressiontests/managers_regress/tests.py +++ b/tests/regressiontests/managers_regress/tests.py @@ -61,7 +61,8 @@ class ManagersRegressionTests(TestCase): self.assertQuerysetEqual(Child4.manager1.all(), [ "<Child4: d1>", "<Child4: f1>" - ] + ], + ordered=False ) self.assertQuerysetEqual(Child5._default_manager.all(), ["<Child5: fred>"]) self.assertQuerysetEqual(Child6._default_manager.all(), ["<Child6: f1>"]) diff --git a/tests/regressiontests/model_regress/tests.py b/tests/regressiontests/model_regress/tests.py index 6a45a83052..c90fe98658 100644 --- a/tests/regressiontests/model_regress/tests.py +++ b/tests/regressiontests/model_regress/tests.py @@ -71,7 +71,8 @@ class ModelTests(TestCase): datetime.date(1999, 12, 31), datetime.date(1998, 12, 31), ], - attrgetter("when") + attrgetter("when"), + ordered=False ) self.assertQuerysetEqual( Party.objects.filter(when__year=1998), [ @@ -85,14 +86,16 @@ class ModelTests(TestCase): datetime.date(1999, 12, 31), datetime.date(1998, 12, 31), ], - attrgetter("when") + attrgetter("when"), + ordered=False ) self.assertQuerysetEqual( Party.objects.filter(when__month="12"), [ datetime.date(1999, 12, 31), datetime.date(1998, 12, 31), ], - attrgetter("when") + attrgetter("when"), + ordered=False ) self.assertQuerysetEqual( Party.objects.filter(when__year="1998"), [ diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py index eea5fead55..e4009cdf20 100644 --- a/tests/regressiontests/queries/tests.py +++ b/tests/regressiontests/queries/tests.py @@ -841,11 +841,14 @@ class Queries1Tests(BaseQuerysetTest): """ original_ordering = Tag._meta.ordering Tag._meta.ordering = None - self.assertQuerysetEqual( - Tag.objects.all(), - ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'], - ) - Tag._meta.ordering = original_ordering + try: + self.assertQuerysetEqual( + Tag.objects.all(), + ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'], + ordered=False + ) + finally: + Tag._meta.ordering = original_ordering def test_exclude(self): self.assertQuerysetEqual( @@ -925,15 +928,18 @@ class Queries2Tests(TestCase): self.assertQuerysetEqual(Number.objects.filter(num__gt=12.1), []) self.assertQuerysetEqual( Number.objects.filter(num__lt=12), - ['<Number: 4>', '<Number: 8>'] + ['<Number: 4>', '<Number: 8>'], + ordered=False ) self.assertQuerysetEqual( Number.objects.filter(num__lt=12.0), - ['<Number: 4>', '<Number: 8>'] + ['<Number: 4>', '<Number: 8>'], + ordered=False ) self.assertQuerysetEqual( Number.objects.filter(num__lt=12.1), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] + ['<Number: 4>', '<Number: 8>', '<Number: 12>'], + ordered=False ) self.assertQuerysetEqual( Number.objects.filter(num__gte=11.9), @@ -951,23 +957,28 @@ class Queries2Tests(TestCase): self.assertQuerysetEqual(Number.objects.filter(num__gte=12.9), []) self.assertQuerysetEqual( Number.objects.filter(num__lte=11.9), - ['<Number: 4>', '<Number: 8>'] + ['<Number: 4>', '<Number: 8>'], + ordered=False ) self.assertQuerysetEqual( Number.objects.filter(num__lte=12), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] + ['<Number: 4>', '<Number: 8>', '<Number: 12>'], + ordered=False ) self.assertQuerysetEqual( Number.objects.filter(num__lte=12.0), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] + ['<Number: 4>', '<Number: 8>', '<Number: 12>'], + ordered=False ) self.assertQuerysetEqual( Number.objects.filter(num__lte=12.1), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] + ['<Number: 4>', '<Number: 8>', '<Number: 12>'], + ordered=False ) self.assertQuerysetEqual( Number.objects.filter(num__lte=12.9), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] + ['<Number: 4>', '<Number: 8>', '<Number: 12>'], + ordered=False ) def test_ticket7411(self): diff --git a/tests/regressiontests/test_utils/models.py b/tests/regressiontests/test_utils/models.py index 4da7a07bbf..85a1031c02 100644 --- a/tests/regressiontests/test_utils/models.py +++ b/tests/regressiontests/test_utils/models.py @@ -1,5 +1,9 @@ from django.db import models +from django.utils.encoding import python_2_unicode_compatible - +@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=100) + + def __str__(self): + return self.name diff --git a/tests/regressiontests/test_utils/tests.py b/tests/regressiontests/test_utils/tests.py index 95913b5aab..d5d49b2104 100644 --- a/tests/regressiontests/test_utils/tests.py +++ b/tests/regressiontests/test_utils/tests.py @@ -54,6 +54,46 @@ class AssertNumQueriesTests(TestCase): self.assertNumQueries(2, test_func) +class AssertQuerysetEqualTests(TestCase): + def setUp(self): + self.p1 = Person.objects.create(name='p1') + self.p2 = Person.objects.create(name='p2') + + def test_ordered(self): + self.assertQuerysetEqual( + Person.objects.all().order_by('name'), + [repr(self.p1), repr(self.p2)] + ) + + def test_unordered(self): + self.assertQuerysetEqual( + Person.objects.all().order_by('name'), + [repr(self.p2), repr(self.p1)], + ordered=False + ) + + def test_transform(self): + self.assertQuerysetEqual( + Person.objects.all().order_by('name'), + [self.p1.pk, self.p2.pk], + transform=lambda x: x.pk + ) + + def test_undefined_order(self): + # Using an unordered queryset with more than one ordered value + # is an error. + with self.assertRaises(ValueError): + self.assertQuerysetEqual( + Person.objects.all(), + [repr(self.p1), repr(self.p2)] + ) + # No error for one value. + self.assertQuerysetEqual( + Person.objects.filter(name='p1'), + [repr(self.p1)] + ) + + class AssertNumQueriesContextManagerTests(TestCase): urls = 'regressiontests.test_utils.urls' |
