Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 4 commits
  • 19 files changed
  • 0 commit comments
  • 1 contributor
View
6 django/test/testcases.py
@@ -767,6 +767,12 @@ def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True):
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):
View
5 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
=====================================
View
5 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 order is seens 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)
View
4 tests/modeltests/expressions/tests.py
@@ -158,6 +158,7 @@ def test_filter(self):
"Max Mustermann",
],
lambda c: six.text_type(c.point_of_contact),
+ ordered=False
)
c = Company.objects.all()[0]
@@ -170,7 +171,8 @@ def test_filter(self):
"Foobar Ltd.",
"Test GmbH",
],
- lambda c: c.name
+ lambda c: c.name,
+ ordered=False
)
Company.objects.exclude(
View
3 tests/modeltests/field_subclassing/tests.py
@@ -77,7 +77,8 @@ def test_custom_field(self):
"12",
"23",
],
- lambda m: str(m.data)
+ lambda m: str(m.data),
+ ordered=False
)
def test_field_subclassing(self):
View
14 tests/modeltests/fixtures/tests.py
@@ -96,8 +96,8 @@ def test_loading_and_dumping(self):
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 @@ def test_loading_and_dumping(self):
'<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 @@ def test_loading_and_dumping(self):
'<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 @@ def test_loading_and_dumping(self):
'<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 @@ def test_output_formats(self):
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)
View
6 tests/modeltests/generic_relations/tests.py
@@ -169,8 +169,8 @@ def test_multiple_gfk(self):
# 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 @@ def test_multiple_gfk(self):
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
View
27 tests/modeltests/m2m_recursive/tests.py
@@ -28,7 +28,8 @@ def test_recursive_m2m(self):
"Chuck",
"David"
],
- attrgetter("name")
+ attrgetter("name"),
+ ordered=False
)
# Who is friends with Bill?
self.assertQuerysetEqual(
@@ -43,7 +44,8 @@ def test_recursive_m2m(self):
"Anne",
"David"
],
- attrgetter("name")
+ attrgetter("name"),
+ ordered=False
)
# Who is friends with David?
self.assertQuerysetEqual(
@@ -51,7 +53,8 @@ def test_recursive_m2m(self):
"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 @@ def test_recursive_m2m(self):
"Chuck",
"David",
],
- attrgetter("name")
+ attrgetter("name"),
+ ordered=False
)
# Who is friends with Bill?
self.assertQuerysetEqual(
@@ -81,7 +85,8 @@ def test_recursive_m2m(self):
"Chuck",
"David",
],
- attrgetter("name")
+ attrgetter("name"),
+ ordered=False
)
# Who is friends with Bill?
self.assertQuerysetEqual(
@@ -125,7 +130,8 @@ def test_recursive_m2m(self):
"Chuck",
"David",
],
- attrgetter("name")
+ attrgetter("name"),
+ ordered=False
)
# Who is stalking Anne?
self.assertQuerysetEqual(
@@ -172,7 +178,8 @@ def test_recursive_m2m(self):
"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 @@ def test_recursive_m2m(self):
"Chuck",
"David",
],
- attrgetter("name")
+ attrgetter("name"),
+ ordered=False
)
# Who is stalking Anne?
self.assertQuerysetEqual(
@@ -215,7 +223,8 @@ def test_recursive_m2m(self):
"Chuck",
"David",
],
- attrgetter("name")
+ attrgetter("name"),
+ ordered=False
)
# Who is stalking Anne?
self.assertQuerysetEqual(
View
8 tests/modeltests/many_to_one/tests.py
@@ -267,7 +267,9 @@ def test_reverse_selects(self):
["<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 @@ def test_reverse_selects(self):
"<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>"])
View
9 tests/modeltests/model_forms/tests.py
@@ -1044,9 +1044,12 @@ def test_with_data(self):
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):
View
37 tests/regressiontests/expressions_regress/tests.py
@@ -26,12 +26,13 @@ def test_fill_with_value_from_same_object(self):
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 @@ def test_increment_value(self):
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 @@ def test_filter_not_equals_other_field(self):
.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):
View
9 tests/regressiontests/extra_regress/tests.py
@@ -58,13 +58,15 @@ def test_regression_7314_7372(self):
('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 @@ def test_regression_17877(self):
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
)
View
2 tests/regressiontests/m2m_regress/tests.py
@@ -74,7 +74,7 @@ def test_add_m2m_with_base_class(self):
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):
View
9 tests/regressiontests/m2m_through_regress/tests.py
@@ -28,7 +28,8 @@ def test_everything(self):
bob.group_set.all(), [
"<Group: Rock>",
"<Group: Roll>",
- ]
+ ],
+ ordered=False
)
self.assertQuerysetEqual(
@@ -51,7 +52,8 @@ def test_everything(self):
frank.group_set.all(), [
"<Group: Rock>",
"<Group: Roll>",
- ]
+ ],
+ ordered=False
)
self.assertQuerysetEqual(
@@ -190,7 +192,8 @@ def test_add_reverse(self):
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):
View
3 tests/regressiontests/managers_regress/tests.py
@@ -61,7 +61,8 @@ def test_managers(self):
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>"])
View
9 tests/regressiontests/model_regress/tests.py
@@ -71,7 +71,8 @@ def test_date_lookup(self):
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 @@ def test_date_lookup(self):
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"), [
View
37 tests/regressiontests/queries/tests.py
@@ -841,11 +841,14 @@ def test_ticket17429(self):
"""
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 @@ def test_ticket12239(self):
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 @@ def test_ticket12239(self):
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):
View
6 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
View
40 tests/regressiontests/test_utils/tests.py
@@ -54,6 +54,46 @@ def test_func():
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'

No commit comments for this range

Something went wrong with that request. Please try again.