From 1760ad4e8cdbf34a0f38deae300460a0b9c38eac Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Thu, 14 Apr 2022 12:12:13 +0200 Subject: [PATCH] Relaxed some query ordering assertions in various tests. It accounts for differences seen on MySQL with MyISAM storage engine. --- tests/admin_filters/tests.py | 2 +- tests/aggregation_regress/tests.py | 2 +- tests/annotations/tests.py | 2 +- tests/db_functions/comparison/test_nullif.py | 4 +- tests/expressions/test_queryset_values.py | 4 +- tests/filtered_relation/tests.py | 2 +- tests/m2m_recursive/tests.py | 2 +- tests/model_fields/test_durationfield.py | 2 +- tests/model_fields/test_jsonfield.py | 42 ++++++++++---------- tests/model_fields/tests.py | 2 +- tests/model_forms/test_modelchoicefield.py | 14 +++---- tests/model_forms/tests.py | 6 +-- tests/model_formsets_regress/tests.py | 10 ++++- tests/prefetch_related/tests.py | 2 +- tests/queries/tests.py | 4 +- tests/servers/tests.py | 4 +- 16 files changed, 55 insertions(+), 49 deletions(-) diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py index 45801503f1..1fcb506b51 100644 --- a/tests/admin_filters/tests.py +++ b/tests/admin_filters/tests.py @@ -874,7 +874,7 @@ class ListFiltersTests(TestCase): request.user = self.alfred changelist = modeladmin.get_changelist_instance(request) filterspec = changelist.get_filters(request)[0][0] - self.assertEqual( + self.assertCountEqual( filterspec.lookup_choices, [ (self.djangonaut_book.pk, "Djangonaut: an art of living"), diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index 92a66298e4..e15e7e41d9 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -502,7 +502,7 @@ class AggregationTests(TestCase): def test_sliced_conditional_aggregate(self): self.assertEqual( - Author.objects.all()[:5].aggregate( + Author.objects.order_by("pk")[:5].aggregate( test=Sum(Case(When(age__lte=35, then=1))) )["test"], 3, diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py index 52a268c4ae..8de2bf1998 100644 --- a/tests/annotations/tests.py +++ b/tests/annotations/tests.py @@ -212,7 +212,7 @@ class NonAggregateAnnotationTestCase(TestCase): with register_lookup(DecimalField, Floor): books = Book.objects.annotate(floor_price=F("price__floor")) - self.assertSequenceEqual( + self.assertCountEqual( books.values_list("pk", "floor_price"), [ (self.b1.pk, 30), diff --git a/tests/db_functions/comparison/test_nullif.py b/tests/db_functions/comparison/test_nullif.py index a65885a3ec..9839e6b4c5 100644 --- a/tests/db_functions/comparison/test_nullif.py +++ b/tests/db_functions/comparison/test_nullif.py @@ -18,7 +18,7 @@ class NullIfTests(TestCase): authors = Author.objects.annotate(nullif=NullIf("alias", "name")).values_list( "nullif" ) - self.assertSequenceEqual( + self.assertCountEqual( authors, [ ("smithj",), @@ -34,7 +34,7 @@ class NullIfTests(TestCase): authors = Author.objects.annotate( nullif=NullIf("name", Value(None)) ).values_list("nullif") - self.assertSequenceEqual(authors, [("John Smith",), ("Rhonda",)]) + self.assertCountEqual(authors, [("John Smith",), ("Rhonda",)]) def test_too_few_args(self): msg = "'NullIf' takes exactly 2 arguments (1 given)" diff --git a/tests/expressions/test_queryset_values.py b/tests/expressions/test_queryset_values.py index 0dba623167..80addef37b 100644 --- a/tests/expressions/test_queryset_values.py +++ b/tests/expressions/test_queryset_values.py @@ -73,10 +73,10 @@ class ValuesExpressionsTests(TestCase): def test_values_list_expression(self): companies = Company.objects.values_list("name", F("ceo__salary")) - self.assertSequenceEqual( + self.assertCountEqual( companies, [("Example Inc.", 10), ("Foobar Ltd.", 20), ("Test GmbH", 30)] ) def test_values_list_expression_flat(self): companies = Company.objects.values_list(F("ceo__salary"), flat=True) - self.assertSequenceEqual(companies, (10, 20, 30)) + self.assertCountEqual(companies, (10, 20, 30)) diff --git a/tests/filtered_relation/tests.py b/tests/filtered_relation/tests.py index fe7f84bcdb..7d77e31b51 100644 --- a/tests/filtered_relation/tests.py +++ b/tests/filtered_relation/tests.py @@ -155,7 +155,7 @@ class FilteredRelationTests(TestCase): ) def test_without_join(self): - self.assertSequenceEqual( + self.assertCountEqual( Author.objects.annotate( book_alice=FilteredRelation( "book", condition=Q(book__title__iexact="poem by alice") diff --git a/tests/m2m_recursive/tests.py b/tests/m2m_recursive/tests.py index d5ebb500c1..e018434327 100644 --- a/tests/m2m_recursive/tests.py +++ b/tests/m2m_recursive/tests.py @@ -104,7 +104,7 @@ class RecursiveSymmetricalM2MThroughTests(TestCase): "first_meet": datetime.date(2013, 1, 5), }, ) - self.assertSequenceEqual(self.a.colleagues.all(), [self.b, self.c, self.d]) + self.assertCountEqual(self.a.colleagues.all(), [self.b, self.c, self.d]) self.assertSequenceEqual(self.b.colleagues.all(), [self.a]) def test_recursive_m2m_remove(self): diff --git a/tests/model_fields/test_durationfield.py b/tests/model_fields/test_durationfield.py index 2fd9984613..c93b81ecf0 100644 --- a/tests/model_fields/test_durationfield.py +++ b/tests/model_fields/test_durationfield.py @@ -44,7 +44,7 @@ class TestQuerying(TestCase): ) def test_gt(self): - self.assertSequenceEqual( + self.assertCountEqual( DurationModel.objects.filter(field__gt=datetime.timedelta(days=0)), [self.objs[0], self.objs[1]], ) diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py index 60cc694843..25dfef7a24 100644 --- a/tests/model_fields/test_jsonfield.py +++ b/tests/model_fields/test_jsonfield.py @@ -326,7 +326,7 @@ class TestQuerying(TestCase): ) def test_icontains(self): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__icontains="BaX"), self.objs[6:8], ) @@ -495,7 +495,7 @@ class TestQuerying(TestCase): ) def test_expression_wrapper_key_transform(self): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.annotate( expr=ExpressionWrapper( KeyTransform("c", "value"), @@ -506,7 +506,7 @@ class TestQuerying(TestCase): ) def test_has_key(self): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__has_key="a"), [self.objs[3], self.objs[4]], ) @@ -570,7 +570,7 @@ class TestQuerying(TestCase): ) def test_has_any_keys(self): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__has_any_keys=["c", "l"]), [self.objs[3], self.objs[4], self.objs[6]], ) @@ -622,7 +622,7 @@ class TestQuerying(TestCase): for value, expected in tests: with self.subTest(value=value): qs = NullableJSONModel.objects.filter(value__contains=value) - self.assertSequenceEqual(qs, expected) + self.assertCountEqual(qs, expected) @skipIfDBFeature("supports_json_field_contains") def test_contains_unsupported(self): @@ -647,7 +647,7 @@ class TestQuerying(TestCase): qs = NullableJSONModel.objects.filter( value__contained_by={"a": "b", "c": 14, "h": True} ) - self.assertSequenceEqual(qs, self.objs[2:4]) + self.assertCountEqual(qs, self.objs[2:4]) @skipIfDBFeature("supports_json_field_contains") def test_contained_by_unsupported(self): @@ -656,7 +656,7 @@ class TestQuerying(TestCase): NullableJSONModel.objects.filter(value__contained_by={"a": "b"}).get() def test_deep_values(self): - qs = NullableJSONModel.objects.values_list("value__k__l") + qs = NullableJSONModel.objects.values_list("value__k__l").order_by("pk") expected_objs = [(None,)] * len(self.objs) expected_objs[4] = ("m",) self.assertSequenceEqual(qs, expected_objs) @@ -670,15 +670,15 @@ class TestQuerying(TestCase): def test_isnull_key(self): # key__isnull=False works the same as has_key='key'. - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__a__isnull=True), self.objs[:3] + self.objs[5:], ) - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__j__isnull=True), self.objs[:4] + self.objs[5:], ) - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__a__isnull=False), [self.objs[3], self.objs[4]], ) @@ -689,7 +689,7 @@ class TestQuerying(TestCase): def test_isnull_key_or_none(self): obj = NullableJSONModel.objects.create(value={"a": None}) - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter( Q(value__a__isnull=True) | Q(value__a=None) ), @@ -723,7 +723,7 @@ class TestQuerying(TestCase): ) def test_shallow_obj_lookup(self): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__a="b"), [self.objs[3], self.objs[4]], ) @@ -734,7 +734,7 @@ class TestQuerying(TestCase): NullableJSONModel.objects.filter(pk=OuterRef("pk")).values("value") ), ).filter(field__a="b") - self.assertSequenceEqual(qs, [self.objs[3], self.objs[4]]) + self.assertCountEqual(qs, [self.objs[3], self.objs[4]]) def test_deep_lookup_objs(self): self.assertSequenceEqual( @@ -761,11 +761,11 @@ class TestQuerying(TestCase): ) def test_deep_lookup_transform(self): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__c__gt=2), [self.objs[3], self.objs[4]], ) - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(value__c__gt=2.33), [self.objs[3], self.objs[4]], ) @@ -777,11 +777,11 @@ class TestQuerying(TestCase): (Q(value__foo="bax"), [self.objs[0], self.objs[7]]), ] for condition, expected in tests: - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.exclude(condition), expected, ) - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(~condition), expected, ) @@ -791,7 +791,7 @@ class TestQuerying(TestCase): condition = Q(value__foo="bax") objs_with_value = [self.objs[6]] objs_with_different_value = [self.objs[0], self.objs[7]] - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.exclude(condition), objs_with_different_value, ) @@ -808,7 +808,7 @@ class TestQuerying(TestCase): objs_with_value + objs_with_different_value, ) # Add the __isnull lookup to get an exhaustive set. - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.exclude(condition & Q(value__foo__isnull=False)), self.objs[0:6] + self.objs[7:], ) @@ -818,7 +818,7 @@ class TestQuerying(TestCase): ) def test_usage_in_subquery(self): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter( id__in=NullableJSONModel.objects.filter(value__c=14), ), @@ -876,7 +876,7 @@ class TestQuerying(TestCase): ] for lookup, value, expected in tests: with self.subTest(lookup=lookup, value=value): - self.assertSequenceEqual( + self.assertCountEqual( NullableJSONModel.objects.filter(**{lookup: value}), expected, ) diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py index eb21d436d8..6d4a91afa2 100644 --- a/tests/model_fields/tests.py +++ b/tests/model_fields/tests.py @@ -347,7 +347,7 @@ class GetChoicesLimitChoicesToTests(TestCase): cls.field = Bar._meta.get_field("a") def assertChoicesEqual(self, choices, objs): - self.assertEqual(choices, [(obj.pk, str(obj)) for obj in objs]) + self.assertCountEqual(choices, [(obj.pk, str(obj)) for obj in objs]) def test_get_choices(self): self.assertChoicesEqual( diff --git a/tests/model_forms/test_modelchoicefield.py b/tests/model_forms/test_modelchoicefield.py index 1ecba4437e..19e9db69a0 100644 --- a/tests/model_forms/test_modelchoicefield.py +++ b/tests/model_forms/test_modelchoicefield.py @@ -92,7 +92,7 @@ class ModelChoiceFieldTests(TestCase): self.assertEqual(len(f.choices), 2) # queryset can be changed after the field is created. - f.queryset = Category.objects.exclude(name="Third") + f.queryset = Category.objects.exclude(name="Third").order_by("pk") self.assertEqual( list(f.choices), [ @@ -119,7 +119,7 @@ class ModelChoiceFieldTests(TestCase): ) # Overriding label_from_instance() to print custom labels. - f.queryset = Category.objects.all() + f.queryset = Category.objects.order_by("pk") f.label_from_instance = lambda obj: "category " + str(obj) self.assertEqual( list(f.choices), @@ -132,7 +132,7 @@ class ModelChoiceFieldTests(TestCase): ) def test_choices_freshness(self): - f = forms.ModelChoiceField(Category.objects.all()) + f = forms.ModelChoiceField(Category.objects.order_by("pk")) self.assertEqual(len(f.choices), 4) self.assertEqual( list(f.choices), @@ -173,7 +173,7 @@ class ModelChoiceFieldTests(TestCase): (self.c2.pk, "A test"), (self.c3.pk, "Third"), ] - categories = Category.objects.all() + categories = Category.objects.order_by("pk") for widget in [forms.RadioSelect, forms.RadioSelect()]: for blank in [True, False]: with self.subTest(widget=widget, blank=blank): @@ -336,7 +336,7 @@ class ModelChoiceFieldTests(TestCase): class CustomModelMultipleChoiceField(forms.ModelMultipleChoiceField): widget = CustomCheckboxSelectMultiple - field = CustomModelMultipleChoiceField(Category.objects.all()) + field = CustomModelMultipleChoiceField(Category.objects.order_by("pk")) self.assertHTMLEqual( field.widget.render("name", []), ( @@ -382,7 +382,7 @@ class ModelChoiceFieldTests(TestCase): iterator = CustomModelChoiceIterator widget = CustomCheckboxSelectMultiple - field = CustomModelMultipleChoiceField(Category.objects.all()) + field = CustomModelMultipleChoiceField(Category.objects.order_by("pk")) self.assertHTMLEqual( field.widget.render("name", []), """ @@ -416,7 +416,7 @@ class ModelChoiceFieldTests(TestCase): def test_queryset_manager(self): f = forms.ModelChoiceField(Category.objects) self.assertEqual(len(f.choices), 4) - self.assertEqual( + self.assertCountEqual( list(f.choices), [ ("", "---------"), diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 0d54cead70..a8617444c5 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -2070,7 +2070,7 @@ class ModelMultipleChoiceFieldTests(TestCase): def test_model_multiple_choice_field(self): f = forms.ModelMultipleChoiceField(Category.objects.all()) - self.assertEqual( + self.assertCountEqual( list(f.choices), [ (self.c1.pk, "Entertainment"), @@ -2139,7 +2139,7 @@ class ModelMultipleChoiceFieldTests(TestCase): # queryset can be changed after the field is created. f.queryset = Category.objects.exclude(name="Third") - self.assertEqual( + self.assertCountEqual( list(f.choices), [(self.c1.pk, "Entertainment"), (self.c2.pk, "It's a test")], ) @@ -2151,7 +2151,7 @@ class ModelMultipleChoiceFieldTests(TestCase): f.queryset = Category.objects.all() f.label_from_instance = lambda obj: "multicategory " + str(obj) - self.assertEqual( + self.assertCountEqual( list(f.choices), [ (self.c1.pk, "multicategory Entertainment"), diff --git a/tests/model_formsets_regress/tests.py b/tests/model_formsets_regress/tests.py index e2ba34d6bf..21a3a9d868 100644 --- a/tests/model_formsets_regress/tests.py +++ b/tests/model_formsets_regress/tests.py @@ -482,7 +482,10 @@ class FormfieldShouldDeleteFormTests(TestCase): data = dict(self.data) data["form-INITIAL_FORMS"] = 4 data.update( - {"form-%d-id" % i: user.pk for i, user in enumerate(User.objects.all())} + { + "form-%d-id" % i: user.pk + for i, user in enumerate(User.objects.order_by("pk")) + } ) formset = self.NormalFormset(data, queryset=User.objects.all()) self.assertTrue(formset.is_valid()) @@ -516,7 +519,10 @@ class FormfieldShouldDeleteFormTests(TestCase): data = dict(self.data) data["form-INITIAL_FORMS"] = 4 data.update( - {"form-%d-id" % i: user.pk for i, user in enumerate(User.objects.all())} + { + "form-%d-id" % i: user.pk + for i, user in enumerate(User.objects.order_by("pk")) + } ) data.update(self.delete_all_ids) formset = self.DeleteFormset(data, queryset=User.objects.all()) diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index f485f26a80..1ac17fde73 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -1272,7 +1272,7 @@ class MultiTableInheritanceTest(TestCase): with self.assertNumQueries(2): qs = BookReview.objects.prefetch_related("book") titles = [obj.book.title for obj in qs] - self.assertEqual(titles, ["Poems", "More poems"]) + self.assertCountEqual(titles, ["Poems", "More poems"]) def test_m2m_to_inheriting_model(self): qs = AuthorWithAge.objects.prefetch_related("books_with_year") diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 77f0eb655c..00213f0dfc 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -1643,7 +1643,7 @@ class Queries4Tests(TestCase): qs = CategoryItem.objects.filter(category__specialcategory__isnull=False) self.assertEqual(qs.count(), 2) - self.assertSequenceEqual(qs, [ci2, ci3]) + self.assertCountEqual(qs, [ci2, ci3]) def test_ticket15316_exclude_false(self): c1 = SimpleCategory.objects.create(name="category1") @@ -1694,7 +1694,7 @@ class Queries4Tests(TestCase): qs = CategoryItem.objects.exclude(category__specialcategory__isnull=True) self.assertEqual(qs.count(), 2) - self.assertSequenceEqual(qs, [ci2, ci3]) + self.assertCountEqual(qs, [ci2, ci3]) def test_ticket15316_one2one_filter_false(self): c = SimpleCategory.objects.create(name="cat") diff --git a/tests/servers/tests.py b/tests/servers/tests.py index 720719ff17..480bc827c1 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -99,7 +99,7 @@ class LiveServerTestCloseConnectionTest(LiveServerBase): self.assertIsNotNone(conn.connection) with self.urlopen("/model_view/") as f: # The server can access the database. - self.assertEqual(f.read().splitlines(), [b"jane", b"robert"]) + self.assertCountEqual(f.read().splitlines(), [b"jane", b"robert"]) # Wait for the server's request thread to close the connection. # A timeout of 0.1 seconds should be more than enough. If the wait # times out, the assertion after should fail. @@ -320,7 +320,7 @@ class LiveServerDatabase(LiveServerBase): Fixtures are properly loaded and visible to the live server thread. """ with self.urlopen("/model_view/") as f: - self.assertEqual(f.read().splitlines(), [b"jane", b"robert"]) + self.assertCountEqual(f.read().splitlines(), [b"jane", b"robert"]) def test_database_writes(self): """