mirror of https://github.com/django/django.git
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.
This commit is contained in:
parent
6ed6a18a03
commit
088d3bc2f8
|
@ -767,6 +767,12 @@ class TransactionTestCase(SimpleTestCase):
|
||||||
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))
|
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)
|
return self.assertEqual(list(items), values)
|
||||||
|
|
||||||
def assertNumQueries(self, num, func=None, *args, **kwargs):
|
def assertNumQueries(self, num, func=None, *args, **kwargs):
|
||||||
|
|
|
@ -23,6 +23,11 @@ Minor features
|
||||||
* Authentication backends can raise ``PermissionDenied`` to immediately fail
|
* Authentication backends can raise ``PermissionDenied`` to immediately fail
|
||||||
the authentication chain.
|
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
|
Backwards incompatible changes in 1.6
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|
|
@ -1770,6 +1770,11 @@ your test suite.
|
||||||
via an explicit ``order_by()`` call on the queryset prior to
|
via an explicit ``order_by()`` call on the queryset prior to
|
||||||
comparison.
|
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)
|
.. method:: TestCase.assertNumQueries(num, func, *args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,7 @@ class ExpressionsTests(TestCase):
|
||||||
"Max Mustermann",
|
"Max Mustermann",
|
||||||
],
|
],
|
||||||
lambda c: six.text_type(c.point_of_contact),
|
lambda c: six.text_type(c.point_of_contact),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
c = Company.objects.all()[0]
|
c = Company.objects.all()[0]
|
||||||
|
@ -170,7 +171,8 @@ class ExpressionsTests(TestCase):
|
||||||
"Foobar Ltd.",
|
"Foobar Ltd.",
|
||||||
"Test GmbH",
|
"Test GmbH",
|
||||||
],
|
],
|
||||||
lambda c: c.name
|
lambda c: c.name,
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
Company.objects.exclude(
|
Company.objects.exclude(
|
||||||
|
|
|
@ -77,7 +77,8 @@ class CustomField(TestCase):
|
||||||
"12",
|
"12",
|
||||||
"23",
|
"23",
|
||||||
],
|
],
|
||||||
lambda m: str(m.data)
|
lambda m: str(m.data),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_field_subclassing(self):
|
def test_field_subclassing(self):
|
||||||
|
|
|
@ -96,8 +96,8 @@ class FixtureLoadingTests(TestCase):
|
||||||
management.call_command('loaddata', 'fixture6.json', verbosity=0, commit=False)
|
management.call_command('loaddata', 'fixture6.json', verbosity=0, commit=False)
|
||||||
self.assertQuerysetEqual(Tag.objects.all(), [
|
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 "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.
|
# Load fixture 7, XML file with dynamic ContentType fields. Testing ManyToOne.
|
||||||
management.call_command('loaddata', 'fixture7.xml', verbosity=0, commit=False)
|
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 "copyright">',
|
||||||
'<Tag: <Article: Copyright is fine the way it is> tagged "legal">',
|
'<Tag: <Article: Copyright is fine the way it is> tagged "legal">',
|
||||||
'<Tag: <Article: Django conquers world!> tagged "django">',
|
'<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.
|
# Load fixture 8, JSON file with dynamic Permission fields. Testing ManyToMany.
|
||||||
management.call_command('loaddata', 'fixture8.json', verbosity=0, commit=False)
|
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: Django Reinhardt Can add user, Can change user, Can delete user>',
|
||||||
'<Visa: Stephane Grappelli Can add user>',
|
'<Visa: Stephane Grappelli Can add user>',
|
||||||
'<Visa: Prince >'
|
'<Visa: Prince >'
|
||||||
])
|
], ordered=False)
|
||||||
|
|
||||||
# Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany.
|
# Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany.
|
||||||
management.call_command('loaddata', 'fixture9.xml', verbosity=0, commit=False)
|
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: Django Reinhardt Can add user, Can change user, Can delete user>',
|
||||||
'<Visa: Stephane Grappelli Can add user, Can delete user>',
|
'<Visa: Stephane Grappelli Can add user, Can delete user>',
|
||||||
'<Visa: Artist formerly known as "Prince" Can change user>'
|
'<Visa: Artist formerly known as "Prince" Can change user>'
|
||||||
])
|
], ordered=False)
|
||||||
|
|
||||||
self.assertQuerysetEqual(Book.objects.all(), [
|
self.assertQuerysetEqual(Book.objects.all(), [
|
||||||
'<Book: Achieving self-awareness of Python programs>',
|
'<Book: Achieving self-awareness of Python programs>',
|
||||||
|
@ -280,7 +280,7 @@ class FixtureLoadingTests(TestCase):
|
||||||
self.assertQuerysetEqual(Tag.objects.all(), [
|
self.assertQuerysetEqual(Tag.objects.all(), [
|
||||||
'<Tag: <Article: Time to reform copyright> tagged "copyright">',
|
'<Tag: <Article: Time to reform copyright> tagged "copyright">',
|
||||||
'<Tag: <Article: Time to reform copyright> tagged "law">'
|
'<Tag: <Article: Time to reform copyright> tagged "law">'
|
||||||
])
|
], ordered=False)
|
||||||
|
|
||||||
# Dump the current contents of the database as a JSON fixture
|
# 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)
|
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)
|
||||||
|
|
|
@ -169,8 +169,8 @@ class GenericRelationsTests(TestCase):
|
||||||
# Filtering works
|
# Filtering works
|
||||||
self.assertQuerysetEqual(tiger.comparisons.filter(comparative="cooler"), [
|
self.assertQuerysetEqual(tiger.comparisons.filter(comparative="cooler"), [
|
||||||
"<Comparison: tiger is cooler than cheetah>",
|
"<Comparison: tiger is cooler than cheetah>",
|
||||||
"<Comparison: tiger is cooler than bear>"
|
"<Comparison: tiger is cooler than bear>",
|
||||||
])
|
], ordered=False)
|
||||||
|
|
||||||
# Filtering and deleting works
|
# Filtering and deleting works
|
||||||
subjective = ["cooler"]
|
subjective = ["cooler"]
|
||||||
|
@ -178,7 +178,7 @@ class GenericRelationsTests(TestCase):
|
||||||
self.assertQuerysetEqual(Comparison.objects.all(), [
|
self.assertQuerysetEqual(Comparison.objects.all(), [
|
||||||
"<Comparison: cheetah is faster than tiger>",
|
"<Comparison: cheetah is faster than tiger>",
|
||||||
"<Comparison: tiger is stronger than cheetah>"
|
"<Comparison: tiger is stronger than cheetah>"
|
||||||
])
|
], ordered=False)
|
||||||
|
|
||||||
# If we delete cheetah, Comparisons with cheetah as 'first_obj' will be
|
# If we delete cheetah, Comparisons with cheetah as 'first_obj' will be
|
||||||
# deleted since Animal has an explicit GenericRelation to Comparison
|
# deleted since Animal has an explicit GenericRelation to Comparison
|
||||||
|
|
|
@ -28,7 +28,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Chuck",
|
"Chuck",
|
||||||
"David"
|
"David"
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Who is friends with Bill?
|
# Who is friends with Bill?
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -43,7 +44,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Anne",
|
"Anne",
|
||||||
"David"
|
"David"
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Who is friends with David?
|
# Who is friends with David?
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -51,7 +53,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Anne",
|
"Anne",
|
||||||
"Chuck",
|
"Chuck",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Bill is already friends with Anne - add Anne again, but in the
|
# Bill is already friends with Anne - add Anne again, but in the
|
||||||
# reverse direction
|
# reverse direction
|
||||||
|
@ -64,7 +67,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Chuck",
|
"Chuck",
|
||||||
"David",
|
"David",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Who is friends with Bill?
|
# Who is friends with Bill?
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -81,7 +85,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Chuck",
|
"Chuck",
|
||||||
"David",
|
"David",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Who is friends with Bill?
|
# Who is friends with Bill?
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -125,7 +130,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Chuck",
|
"Chuck",
|
||||||
"David",
|
"David",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Who is stalking Anne?
|
# Who is stalking Anne?
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -172,7 +178,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Anne",
|
"Anne",
|
||||||
"Chuck",
|
"Chuck",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Bill is already being stalked by Anne - add Anne again, but in the
|
# Bill is already being stalked by Anne - add Anne again, but in the
|
||||||
# reverse direction
|
# reverse direction
|
||||||
|
@ -184,7 +191,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Chuck",
|
"Chuck",
|
||||||
"David",
|
"David",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Who is stalking Anne?
|
# Who is stalking Anne?
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -215,7 +223,8 @@ class RecursiveM2MTests(TestCase):
|
||||||
"Chuck",
|
"Chuck",
|
||||||
"David",
|
"David",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
# Who is stalking Anne?
|
# Who is stalking Anne?
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
|
|
@ -267,7 +267,9 @@ class ManyToOneTests(TestCase):
|
||||||
["<Reporter: John Smith>"])
|
["<Reporter: John Smith>"])
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Reporter.objects.filter(article__headline__startswith='T'),
|
Reporter.objects.filter(article__headline__startswith='T'),
|
||||||
["<Reporter: John Smith>", "<Reporter: John Smith>"])
|
["<Reporter: John Smith>", "<Reporter: John Smith>"],
|
||||||
|
ordered=False
|
||||||
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Reporter.objects.filter(article__headline__startswith='T').distinct(),
|
Reporter.objects.filter(article__headline__startswith='T').distinct(),
|
||||||
["<Reporter: John Smith>"])
|
["<Reporter: John Smith>"])
|
||||||
|
@ -285,7 +287,9 @@ class ManyToOneTests(TestCase):
|
||||||
"<Reporter: John Smith>",
|
"<Reporter: John Smith>",
|
||||||
"<Reporter: John Smith>",
|
"<Reporter: John Smith>",
|
||||||
"<Reporter: John Smith>",
|
"<Reporter: John Smith>",
|
||||||
])
|
],
|
||||||
|
ordered=False
|
||||||
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct(),
|
Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct(),
|
||||||
["<Reporter: John Smith>"])
|
["<Reporter: John Smith>"])
|
||||||
|
|
|
@ -1044,9 +1044,12 @@ class OldFormForXTests(TestCase):
|
||||||
self.assertQuerysetEqual(f.clean([c1.id]), ["Entertainment"])
|
self.assertQuerysetEqual(f.clean([c1.id]), ["Entertainment"])
|
||||||
self.assertQuerysetEqual(f.clean([c2.id]), ["It's a test"])
|
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)]), ["Entertainment"])
|
||||||
self.assertQuerysetEqual(f.clean([str(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"],
|
||||||
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"])
|
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):
|
with self.assertRaises(ValidationError):
|
||||||
f.clean(['100'])
|
f.clean(['100'])
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
|
|
|
@ -26,12 +26,13 @@ class ExpressionsRegressTests(TestCase):
|
||||||
same object.
|
same object.
|
||||||
"""
|
"""
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.all(),
|
Number.objects.all(),
|
||||||
[
|
[
|
||||||
'<Number: -1, -1.000>',
|
'<Number: -1, -1.000>',
|
||||||
'<Number: 42, 42.000>',
|
'<Number: 42, 42.000>',
|
||||||
'<Number: 1337, 1337.000>'
|
'<Number: 1337, 1337.000>'
|
||||||
]
|
],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_increment_value(self):
|
def test_increment_value(self):
|
||||||
|
@ -44,12 +45,13 @@ class ExpressionsRegressTests(TestCase):
|
||||||
2)
|
2)
|
||||||
|
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.all(),
|
Number.objects.all(),
|
||||||
[
|
[
|
||||||
'<Number: -1, -1.000>',
|
'<Number: -1, -1.000>',
|
||||||
'<Number: 43, 42.000>',
|
'<Number: 43, 42.000>',
|
||||||
'<Number: 1338, 1337.000>'
|
'<Number: 1338, 1337.000>'
|
||||||
]
|
],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_filter_not_equals_other_field(self):
|
def test_filter_not_equals_other_field(self):
|
||||||
|
@ -62,11 +64,12 @@ class ExpressionsRegressTests(TestCase):
|
||||||
.update(integer=F('integer') + 1),
|
.update(integer=F('integer') + 1),
|
||||||
2)
|
2)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.exclude(float=F('integer')),
|
Number.objects.exclude(float=F('integer')),
|
||||||
[
|
[
|
||||||
'<Number: 43, 42.000>',
|
'<Number: 43, 42.000>',
|
||||||
'<Number: 1338, 1337.000>'
|
'<Number: 1338, 1337.000>'
|
||||||
]
|
],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_complex_expressions(self):
|
def test_complex_expressions(self):
|
||||||
|
|
|
@ -58,13 +58,15 @@ class ExtraRegressTests(TestCase):
|
||||||
('First Revision', 'First Revision'),
|
('First Revision', 'First Revision'),
|
||||||
('Second 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:
|
# Following queryset should return the most recent revision:
|
||||||
self.assertQuerysetEqual(qs & qs2,
|
self.assertQuerysetEqual(qs & qs2,
|
||||||
[('Second 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
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_extra_stay_tied(self):
|
def test_extra_stay_tied(self):
|
||||||
|
@ -342,5 +344,6 @@ class ExtraRegressTests(TestCase):
|
||||||
TestObject.objects.extra(
|
TestObject.objects.extra(
|
||||||
where=["first = 'a' OR second = 'a'", "third = 'a'"],
|
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
|
||||||
)
|
)
|
||||||
|
|
|
@ -74,7 +74,7 @@ class M2MRegressionTests(TestCase):
|
||||||
c1.tags = [t1, t2]
|
c1.tags = [t1, t2]
|
||||||
c1 = TagCollection.objects.get(name='c1')
|
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>"])
|
self.assertQuerysetEqual(t1.tag_collections.all(), ["<TagCollection: c1>"])
|
||||||
|
|
||||||
def test_manager_class_caching(self):
|
def test_manager_class_caching(self):
|
||||||
|
|
|
@ -28,7 +28,8 @@ class M2MThroughTestCase(TestCase):
|
||||||
bob.group_set.all(), [
|
bob.group_set.all(), [
|
||||||
"<Group: Rock>",
|
"<Group: Rock>",
|
||||||
"<Group: Roll>",
|
"<Group: Roll>",
|
||||||
]
|
],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -51,7 +52,8 @@ class M2MThroughTestCase(TestCase):
|
||||||
frank.group_set.all(), [
|
frank.group_set.all(), [
|
||||||
"<Group: Rock>",
|
"<Group: Rock>",
|
||||||
"<Group: Roll>",
|
"<Group: Roll>",
|
||||||
]
|
],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -190,7 +192,8 @@ class ToFieldThroughTests(TestCase):
|
||||||
self.driver.car_set._add_items('driver', 'car', car2)
|
self.driver.car_set._add_items('driver', 'car', car2)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
self.driver.car_set.all(),
|
self.driver.car_set.all(),
|
||||||
["<Car: Toyota>", "<Car: Honda>"]
|
["<Car: Toyota>", "<Car: Honda>"],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_null_reverse(self):
|
def test_add_null_reverse(self):
|
||||||
|
|
|
@ -61,7 +61,8 @@ class ManagersRegressionTests(TestCase):
|
||||||
self.assertQuerysetEqual(Child4.manager1.all(), [
|
self.assertQuerysetEqual(Child4.manager1.all(), [
|
||||||
"<Child4: d1>",
|
"<Child4: d1>",
|
||||||
"<Child4: f1>"
|
"<Child4: f1>"
|
||||||
]
|
],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(Child5._default_manager.all(), ["<Child5: fred>"])
|
self.assertQuerysetEqual(Child5._default_manager.all(), ["<Child5: fred>"])
|
||||||
self.assertQuerysetEqual(Child6._default_manager.all(), ["<Child6: f1>"])
|
self.assertQuerysetEqual(Child6._default_manager.all(), ["<Child6: f1>"])
|
||||||
|
|
|
@ -71,7 +71,8 @@ class ModelTests(TestCase):
|
||||||
datetime.date(1999, 12, 31),
|
datetime.date(1999, 12, 31),
|
||||||
datetime.date(1998, 12, 31),
|
datetime.date(1998, 12, 31),
|
||||||
],
|
],
|
||||||
attrgetter("when")
|
attrgetter("when"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Party.objects.filter(when__year=1998), [
|
Party.objects.filter(when__year=1998), [
|
||||||
|
@ -85,14 +86,16 @@ class ModelTests(TestCase):
|
||||||
datetime.date(1999, 12, 31),
|
datetime.date(1999, 12, 31),
|
||||||
datetime.date(1998, 12, 31),
|
datetime.date(1998, 12, 31),
|
||||||
],
|
],
|
||||||
attrgetter("when")
|
attrgetter("when"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Party.objects.filter(when__month="12"), [
|
Party.objects.filter(when__month="12"), [
|
||||||
datetime.date(1999, 12, 31),
|
datetime.date(1999, 12, 31),
|
||||||
datetime.date(1998, 12, 31),
|
datetime.date(1998, 12, 31),
|
||||||
],
|
],
|
||||||
attrgetter("when")
|
attrgetter("when"),
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Party.objects.filter(when__year="1998"), [
|
Party.objects.filter(when__year="1998"), [
|
||||||
|
|
|
@ -841,11 +841,14 @@ class Queries1Tests(BaseQuerysetTest):
|
||||||
"""
|
"""
|
||||||
original_ordering = Tag._meta.ordering
|
original_ordering = Tag._meta.ordering
|
||||||
Tag._meta.ordering = None
|
Tag._meta.ordering = None
|
||||||
self.assertQuerysetEqual(
|
try:
|
||||||
Tag.objects.all(),
|
self.assertQuerysetEqual(
|
||||||
['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'],
|
Tag.objects.all(),
|
||||||
)
|
['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'],
|
||||||
Tag._meta.ordering = original_ordering
|
ordered=False
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
Tag._meta.ordering = original_ordering
|
||||||
|
|
||||||
def test_exclude(self):
|
def test_exclude(self):
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
|
@ -925,15 +928,18 @@ class Queries2Tests(TestCase):
|
||||||
self.assertQuerysetEqual(Number.objects.filter(num__gt=12.1), [])
|
self.assertQuerysetEqual(Number.objects.filter(num__gt=12.1), [])
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lt=12),
|
Number.objects.filter(num__lt=12),
|
||||||
['<Number: 4>', '<Number: 8>']
|
['<Number: 4>', '<Number: 8>'],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lt=12.0),
|
Number.objects.filter(num__lt=12.0),
|
||||||
['<Number: 4>', '<Number: 8>']
|
['<Number: 4>', '<Number: 8>'],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lt=12.1),
|
Number.objects.filter(num__lt=12.1),
|
||||||
['<Number: 4>', '<Number: 8>', '<Number: 12>']
|
['<Number: 4>', '<Number: 8>', '<Number: 12>'],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__gte=11.9),
|
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__gte=12.9), [])
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lte=11.9),
|
Number.objects.filter(num__lte=11.9),
|
||||||
['<Number: 4>', '<Number: 8>']
|
['<Number: 4>', '<Number: 8>'],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lte=12),
|
Number.objects.filter(num__lte=12),
|
||||||
['<Number: 4>', '<Number: 8>', '<Number: 12>']
|
['<Number: 4>', '<Number: 8>', '<Number: 12>'],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lte=12.0),
|
Number.objects.filter(num__lte=12.0),
|
||||||
['<Number: 4>', '<Number: 8>', '<Number: 12>']
|
['<Number: 4>', '<Number: 8>', '<Number: 12>'],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lte=12.1),
|
Number.objects.filter(num__lte=12.1),
|
||||||
['<Number: 4>', '<Number: 8>', '<Number: 12>']
|
['<Number: 4>', '<Number: 8>', '<Number: 12>'],
|
||||||
|
ordered=False
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Number.objects.filter(num__lte=12.9),
|
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):
|
def test_ticket7411(self):
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
|
@ -54,6 +54,46 @@ class AssertNumQueriesTests(TestCase):
|
||||||
self.assertNumQueries(2, 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):
|
class AssertNumQueriesContextManagerTests(TestCase):
|
||||||
urls = 'regressiontests.test_utils.urls'
|
urls = 'regressiontests.test_utils.urls'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue