1. from django.db import connection
    
  2. from django.db.models import F, Value
    
  3. from django.db.models.functions import Collate
    
  4. from django.test import TestCase
    
  5. 
    
  6. from ..models import Author
    
  7. 
    
  8. 
    
  9. class CollateTests(TestCase):
    
  10.     @classmethod
    
  11.     def setUpTestData(cls):
    
  12.         cls.author1 = Author.objects.create(alias="a", name="Jones 1")
    
  13.         cls.author2 = Author.objects.create(alias="A", name="Jones 2")
    
  14. 
    
  15.     def test_collate_filter_ci(self):
    
  16.         collation = connection.features.test_collations.get("ci")
    
  17.         if not collation:
    
  18.             self.skipTest("This backend does not support case-insensitive collations.")
    
  19.         qs = Author.objects.filter(alias=Collate(Value("a"), collation))
    
  20.         self.assertEqual(qs.count(), 2)
    
  21. 
    
  22.     def test_collate_order_by_cs(self):
    
  23.         collation = connection.features.test_collations.get("cs")
    
  24.         if not collation:
    
  25.             self.skipTest("This backend does not support case-sensitive collations.")
    
  26.         qs = Author.objects.order_by(Collate("alias", collation))
    
  27.         self.assertSequenceEqual(qs, [self.author2, self.author1])
    
  28. 
    
  29.     def test_language_collation_order_by(self):
    
  30.         collation = connection.features.test_collations.get("swedish_ci")
    
  31.         if not collation:
    
  32.             self.skipTest("This backend does not support language collations.")
    
  33.         author3 = Author.objects.create(alias="O", name="Jones")
    
  34.         author4 = Author.objects.create(alias="Ö", name="Jones")
    
  35.         author5 = Author.objects.create(alias="P", name="Jones")
    
  36.         qs = Author.objects.order_by(Collate(F("alias"), collation), "name")
    
  37.         self.assertSequenceEqual(
    
  38.             qs,
    
  39.             [self.author1, self.author2, author3, author5, author4],
    
  40.         )
    
  41. 
    
  42.     def test_invalid_collation(self):
    
  43.         tests = [
    
  44.             None,
    
  45.             "",
    
  46.             'et-x-icu" OR ',
    
  47.             '"schema"."collation"',
    
  48.         ]
    
  49.         msg = "Invalid collation name: %r."
    
  50.         for value in tests:
    
  51.             with self.subTest(value), self.assertRaisesMessage(ValueError, msg % value):
    
  52.                 Collate(F("alias"), value)