mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Reorganized text db function tests.
This commit is contained in:
		| @@ -6,8 +6,7 @@ from django.db import connection | ||||
| from django.db.models import CharField, TextField, Value as V | ||||
| from django.db.models.expressions import RawSQL | ||||
| from django.db.models.functions import ( | ||||
|     Coalesce, Concat, ConcatPair, Greatest, Least, Length, Lower, Now, | ||||
|     StrIndex, Substr, Upper, | ||||
|     Coalesce, Greatest, Least, Length, Lower, Now, Upper, | ||||
| ) | ||||
| from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature | ||||
| from django.utils import timezone | ||||
| @@ -311,214 +310,6 @@ class FunctionTests(TestCase): | ||||
|             [obj], | ||||
|         ) | ||||
|  | ||||
|     def test_concat(self): | ||||
|         Author.objects.create(name='Jayden') | ||||
|         Author.objects.create(name='John Smith', alias='smithj', goes_by='John') | ||||
|         Author.objects.create(name='Margaret', goes_by='Maggie') | ||||
|         Author.objects.create(name='Rhonda', alias='adnohR') | ||||
|  | ||||
|         authors = Author.objects.annotate(joined=Concat('alias', 'goes_by')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 '', | ||||
|                 'smithjJohn', | ||||
|                 'Maggie', | ||||
|                 'adnohR', | ||||
|             ], | ||||
|             lambda a: a.joined | ||||
|         ) | ||||
|  | ||||
|         with self.assertRaisesMessage(ValueError, 'Concat must take at least two expressions'): | ||||
|             Author.objects.annotate(joined=Concat('alias')) | ||||
|  | ||||
|     def test_concat_many(self): | ||||
|         Author.objects.create(name='Jayden') | ||||
|         Author.objects.create(name='John Smith', alias='smithj', goes_by='John') | ||||
|         Author.objects.create(name='Margaret', goes_by='Maggie') | ||||
|         Author.objects.create(name='Rhonda', alias='adnohR') | ||||
|  | ||||
|         authors = Author.objects.annotate( | ||||
|             joined=Concat('name', V(' ('), 'goes_by', V(')'), output_field=CharField()), | ||||
|         ) | ||||
|  | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'Jayden ()', | ||||
|                 'John Smith (John)', | ||||
|                 'Margaret (Maggie)', | ||||
|                 'Rhonda ()', | ||||
|             ], | ||||
|             lambda a: a.joined | ||||
|         ) | ||||
|  | ||||
|     def test_concat_mixed_char_text(self): | ||||
|         Article.objects.create(title='The Title', text=lorem_ipsum, written=timezone.now()) | ||||
|         article = Article.objects.annotate( | ||||
|             title_text=Concat('title', V(' - '), 'text', output_field=TextField()), | ||||
|         ).get(title='The Title') | ||||
|         self.assertEqual(article.title + ' - ' + article.text, article.title_text) | ||||
|  | ||||
|         # wrap the concat in something else to ensure that we're still | ||||
|         # getting text rather than bytes | ||||
|         article = Article.objects.annotate( | ||||
|             title_text=Upper(Concat('title', V(' - '), 'text', output_field=TextField())), | ||||
|         ).get(title='The Title') | ||||
|         expected = article.title + ' - ' + article.text | ||||
|         self.assertEqual(expected.upper(), article.title_text) | ||||
|  | ||||
|     @skipUnless(connection.vendor == 'sqlite', "sqlite specific implementation detail.") | ||||
|     def test_concat_coalesce_idempotent(self): | ||||
|         pair = ConcatPair(V('a'), V('b')) | ||||
|         # Check nodes counts | ||||
|         self.assertEqual(len(list(pair.flatten())), 3) | ||||
|         self.assertEqual(len(list(pair.coalesce().flatten())), 7)  # + 2 Coalesce + 2 Value() | ||||
|         self.assertEqual(len(list(pair.flatten())), 3) | ||||
|  | ||||
|     def test_concat_sql_generation_idempotency(self): | ||||
|         qs = Article.objects.annotate(description=Concat('title', V(': '), 'summary')) | ||||
|         # Multiple compilations should not alter the generated query. | ||||
|         self.assertEqual(str(qs.query), str(qs.all().query)) | ||||
|  | ||||
|     def test_lower(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate(lower_name=Lower('name')) | ||||
|  | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'john smith', | ||||
|                 'rhonda', | ||||
|             ], | ||||
|             lambda a: a.lower_name | ||||
|         ) | ||||
|  | ||||
|         Author.objects.update(name=Lower('name')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 ('john smith', 'john smith'), | ||||
|                 ('rhonda', 'rhonda'), | ||||
|             ], | ||||
|             lambda a: (a.lower_name, a.name) | ||||
|         ) | ||||
|  | ||||
|         with self.assertRaisesMessage(TypeError, "'Lower' takes exactly 1 argument (2 given)"): | ||||
|             Author.objects.update(name=Lower('name', 'name')) | ||||
|  | ||||
|     def test_upper(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate(upper_name=Upper('name')) | ||||
|  | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'JOHN SMITH', | ||||
|                 'RHONDA', | ||||
|             ], | ||||
|             lambda a: a.upper_name | ||||
|         ) | ||||
|  | ||||
|         Author.objects.update(name=Upper('name')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 ('JOHN SMITH', 'JOHN SMITH'), | ||||
|                 ('RHONDA', 'RHONDA'), | ||||
|             ], | ||||
|             lambda a: (a.upper_name, a.name) | ||||
|         ) | ||||
|  | ||||
|     def test_length(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate( | ||||
|             name_length=Length('name'), | ||||
|             alias_length=Length('alias')) | ||||
|  | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 (10, 6), | ||||
|                 (6, None), | ||||
|             ], | ||||
|             lambda a: (a.name_length, a.alias_length) | ||||
|         ) | ||||
|  | ||||
|         self.assertEqual(authors.filter(alias_length__lte=Length('name')).count(), 1) | ||||
|  | ||||
|     def test_length_ordering(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='John Smith', alias='smithj1') | ||||
|         Author.objects.create(name='Rhonda', alias='ronny') | ||||
|  | ||||
|         authors = Author.objects.order_by(Length('name'), Length('alias')) | ||||
|  | ||||
|         self.assertQuerysetEqual( | ||||
|             authors, [ | ||||
|                 ('Rhonda', 'ronny'), | ||||
|                 ('John Smith', 'smithj'), | ||||
|                 ('John Smith', 'smithj1'), | ||||
|             ], | ||||
|             lambda a: (a.name, a.alias) | ||||
|         ) | ||||
|  | ||||
|     def test_substr(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate(name_part=Substr('name', 5, 3)) | ||||
|  | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 ' Sm', | ||||
|                 'da', | ||||
|             ], | ||||
|             lambda a: a.name_part | ||||
|         ) | ||||
|  | ||||
|         authors = Author.objects.annotate(name_part=Substr('name', 2)) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'ohn Smith', | ||||
|                 'honda', | ||||
|             ], | ||||
|             lambda a: a.name_part | ||||
|         ) | ||||
|  | ||||
|         # if alias is null, set to first 5 lower characters of the name | ||||
|         Author.objects.filter(alias__isnull=True).update( | ||||
|             alias=Lower(Substr('name', 1, 5)), | ||||
|         ) | ||||
|  | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'smithj', | ||||
|                 'rhond', | ||||
|             ], | ||||
|             lambda a: a.alias | ||||
|         ) | ||||
|  | ||||
|     def test_substr_start(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         a = Author.objects.annotate( | ||||
|             name_part_1=Substr('name', 1), | ||||
|             name_part_2=Substr('name', 2), | ||||
|         ).get(alias='smithj') | ||||
|  | ||||
|         self.assertEqual(a.name_part_1[1:], a.name_part_2) | ||||
|  | ||||
|         with self.assertRaisesMessage(ValueError, "'pos' must be greater than 0"): | ||||
|             Author.objects.annotate(raises=Substr('name', 0)) | ||||
|  | ||||
|     def test_substr_with_expressions(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         substr = Substr(Upper('name'), StrIndex('name', V('h')), 5, output_field=CharField()) | ||||
|         authors = Author.objects.annotate(name_part=substr) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'HN SM', | ||||
|                 'HONDA', | ||||
|             ], | ||||
|             lambda a: a.name_part | ||||
|         ) | ||||
|  | ||||
|     def test_nested_function_ordering(self): | ||||
|         Author.objects.create(name='John Smith') | ||||
|         Author.objects.create(name='Rhonda Simpson', alias='ronny') | ||||
| @@ -578,51 +369,6 @@ class FunctionTests(TestCase): | ||||
|             lambda a: a.title | ||||
|         ) | ||||
|  | ||||
|     def test_length_transform(self): | ||||
|         try: | ||||
|             CharField.register_lookup(Length) | ||||
|             Author.objects.create(name='John Smith', alias='smithj') | ||||
|             Author.objects.create(name='Rhonda') | ||||
|             authors = Author.objects.filter(name__length__gt=7) | ||||
|             self.assertQuerysetEqual( | ||||
|                 authors.order_by('name'), [ | ||||
|                     'John Smith', | ||||
|                 ], | ||||
|                 lambda a: a.name | ||||
|             ) | ||||
|         finally: | ||||
|             CharField._unregister_lookup(Length) | ||||
|  | ||||
|     def test_lower_transform(self): | ||||
|         try: | ||||
|             CharField.register_lookup(Lower) | ||||
|             Author.objects.create(name='John Smith', alias='smithj') | ||||
|             Author.objects.create(name='Rhonda') | ||||
|             authors = Author.objects.filter(name__lower__exact='john smith') | ||||
|             self.assertQuerysetEqual( | ||||
|                 authors.order_by('name'), [ | ||||
|                     'John Smith', | ||||
|                 ], | ||||
|                 lambda a: a.name | ||||
|             ) | ||||
|         finally: | ||||
|             CharField._unregister_lookup(Lower) | ||||
|  | ||||
|     def test_upper_transform(self): | ||||
|         try: | ||||
|             CharField.register_lookup(Upper) | ||||
|             Author.objects.create(name='John Smith', alias='smithj') | ||||
|             Author.objects.create(name='Rhonda') | ||||
|             authors = Author.objects.filter(name__upper__exact='JOHN SMITH') | ||||
|             self.assertQuerysetEqual( | ||||
|                 authors.order_by('name'), [ | ||||
|                     'John Smith', | ||||
|                 ], | ||||
|                 lambda a: a.name | ||||
|             ) | ||||
|         finally: | ||||
|             CharField._unregister_lookup(Upper) | ||||
|  | ||||
|     def test_func_transform_bilateral(self): | ||||
|         class UpperBilateral(Upper): | ||||
|             bilateral = True | ||||
|   | ||||
							
								
								
									
										0
									
								
								tests/db_functions/text/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/db_functions/text/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -2,7 +2,7 @@ from django.db.models import IntegerField | ||||
| from django.db.models.functions import Chr, Left, Ord | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class ChrTests(TestCase): | ||||
							
								
								
									
										81
									
								
								tests/db_functions/text/test_concat.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								tests/db_functions/text/test_concat.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| from unittest import skipUnless | ||||
|  | ||||
| from django.db import connection | ||||
| from django.db.models import CharField, TextField, Value as V | ||||
| from django.db.models.functions import Concat, ConcatPair, Upper | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
|  | ||||
| from ..models import Article, Author | ||||
|  | ||||
| lorem_ipsum = """ | ||||
|     Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod | ||||
|     tempor incididunt ut labore et dolore magna aliqua.""" | ||||
|  | ||||
|  | ||||
| class ConcatTests(TestCase): | ||||
|  | ||||
|     def test_basic(self): | ||||
|         Author.objects.create(name='Jayden') | ||||
|         Author.objects.create(name='John Smith', alias='smithj', goes_by='John') | ||||
|         Author.objects.create(name='Margaret', goes_by='Maggie') | ||||
|         Author.objects.create(name='Rhonda', alias='adnohR') | ||||
|         authors = Author.objects.annotate(joined=Concat('alias', 'goes_by')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 '', | ||||
|                 'smithjJohn', | ||||
|                 'Maggie', | ||||
|                 'adnohR', | ||||
|             ], | ||||
|             lambda a: a.joined | ||||
|         ) | ||||
|  | ||||
|     def test_gt_two_expressions(self): | ||||
|         with self.assertRaisesMessage(ValueError, 'Concat must take at least two expressions'): | ||||
|             Author.objects.annotate(joined=Concat('alias')) | ||||
|  | ||||
|     def test_many(self): | ||||
|         Author.objects.create(name='Jayden') | ||||
|         Author.objects.create(name='John Smith', alias='smithj', goes_by='John') | ||||
|         Author.objects.create(name='Margaret', goes_by='Maggie') | ||||
|         Author.objects.create(name='Rhonda', alias='adnohR') | ||||
|         authors = Author.objects.annotate( | ||||
|             joined=Concat('name', V(' ('), 'goes_by', V(')'), output_field=CharField()), | ||||
|         ) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'Jayden ()', | ||||
|                 'John Smith (John)', | ||||
|                 'Margaret (Maggie)', | ||||
|                 'Rhonda ()', | ||||
|             ], | ||||
|             lambda a: a.joined | ||||
|         ) | ||||
|  | ||||
|     def test_mixed_char_text(self): | ||||
|         Article.objects.create(title='The Title', text=lorem_ipsum, written=timezone.now()) | ||||
|         article = Article.objects.annotate( | ||||
|             title_text=Concat('title', V(' - '), 'text', output_field=TextField()), | ||||
|         ).get(title='The Title') | ||||
|         self.assertEqual(article.title + ' - ' + article.text, article.title_text) | ||||
|         # Wrap the concat in something else to ensure that text is returned | ||||
|         # rather than bytes. | ||||
|         article = Article.objects.annotate( | ||||
|             title_text=Upper(Concat('title', V(' - '), 'text', output_field=TextField())), | ||||
|         ).get(title='The Title') | ||||
|         expected = article.title + ' - ' + article.text | ||||
|         self.assertEqual(expected.upper(), article.title_text) | ||||
|  | ||||
|     @skipUnless(connection.vendor == 'sqlite', "sqlite specific implementation detail.") | ||||
|     def test_coalesce_idempotent(self): | ||||
|         pair = ConcatPair(V('a'), V('b')) | ||||
|         # Check nodes counts | ||||
|         self.assertEqual(len(list(pair.flatten())), 3) | ||||
|         self.assertEqual(len(list(pair.coalesce().flatten())), 7)  # + 2 Coalesce + 2 Value() | ||||
|         self.assertEqual(len(list(pair.flatten())), 3) | ||||
|  | ||||
|     def test_sql_generation_idempotency(self): | ||||
|         qs = Article.objects.annotate(description=Concat('title', V(': '), 'summary')) | ||||
|         # Multiple compilations should not alter the generated query. | ||||
|         self.assertEqual(str(qs.query), str(qs.all().query)) | ||||
| @@ -2,7 +2,7 @@ from django.db.models import CharField, Value | ||||
| from django.db.models.functions import Left, Lower | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class LeftTests(TestCase): | ||||
							
								
								
									
										48
									
								
								tests/db_functions/text/test_length.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tests/db_functions/text/test_length.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| from django.db.models import CharField | ||||
| from django.db.models.functions import Length | ||||
| from django.test import TestCase | ||||
|  | ||||
| from ..models import Author | ||||
|  | ||||
|  | ||||
| class LengthTests(TestCase): | ||||
|  | ||||
|     def test_basic(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate( | ||||
|             name_length=Length('name'), | ||||
|             alias_length=Length('alias'), | ||||
|         ) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [(10, 6), (6, None)], | ||||
|             lambda a: (a.name_length, a.alias_length) | ||||
|         ) | ||||
|         self.assertEqual(authors.filter(alias_length__lte=Length('name')).count(), 1) | ||||
|  | ||||
|     def test_ordering(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='John Smith', alias='smithj1') | ||||
|         Author.objects.create(name='Rhonda', alias='ronny') | ||||
|         authors = Author.objects.order_by(Length('name'), Length('alias')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors, [ | ||||
|                 ('Rhonda', 'ronny'), | ||||
|                 ('John Smith', 'smithj'), | ||||
|                 ('John Smith', 'smithj1'), | ||||
|             ], | ||||
|             lambda a: (a.name, a.alias) | ||||
|         ) | ||||
|  | ||||
|     def test_transform(self): | ||||
|         try: | ||||
|             CharField.register_lookup(Length) | ||||
|             Author.objects.create(name='John Smith', alias='smithj') | ||||
|             Author.objects.create(name='Rhonda') | ||||
|             authors = Author.objects.filter(name__length__gt=7) | ||||
|             self.assertQuerysetEqual( | ||||
|                 authors.order_by('name'), ['John Smith'], | ||||
|                 lambda a: a.name | ||||
|             ) | ||||
|         finally: | ||||
|             CharField._unregister_lookup(Length) | ||||
							
								
								
									
										42
									
								
								tests/db_functions/text/test_lower.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								tests/db_functions/text/test_lower.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| from django.db.models import CharField | ||||
| from django.db.models.functions import Lower | ||||
| from django.test import TestCase | ||||
|  | ||||
| from ..models import Author | ||||
|  | ||||
|  | ||||
| class LowerTests(TestCase): | ||||
|  | ||||
|     def test_basic(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate(lower_name=Lower('name')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), ['john smith', 'rhonda'], | ||||
|             lambda a: a.lower_name | ||||
|         ) | ||||
|         Author.objects.update(name=Lower('name')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 ('john smith', 'john smith'), | ||||
|                 ('rhonda', 'rhonda'), | ||||
|             ], | ||||
|             lambda a: (a.lower_name, a.name) | ||||
|         ) | ||||
|  | ||||
|     def test_num_args(self): | ||||
|         with self.assertRaisesMessage(TypeError, "'Lower' takes exactly 1 argument (2 given)"): | ||||
|             Author.objects.update(name=Lower('name', 'name')) | ||||
|  | ||||
|     def test_transform(self): | ||||
|         try: | ||||
|             CharField.register_lookup(Lower) | ||||
|             Author.objects.create(name='John Smith', alias='smithj') | ||||
|             Author.objects.create(name='Rhonda') | ||||
|             authors = Author.objects.filter(name__lower__exact='john smith') | ||||
|             self.assertQuerysetEqual( | ||||
|                 authors.order_by('name'), ['John Smith'], | ||||
|                 lambda a: a.name | ||||
|             ) | ||||
|         finally: | ||||
|             CharField._unregister_lookup(Lower) | ||||
| @@ -2,7 +2,7 @@ from django.db.models import CharField, Value | ||||
| from django.db.models.functions import Left, Ord | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class OrdTests(TestCase): | ||||
| @@ -2,7 +2,7 @@ from django.db.models import CharField, Value | ||||
| from django.db.models.functions import Length, LPad, RPad | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class PadTests(TestCase): | ||||
| @@ -2,7 +2,7 @@ from django.db.models import CharField, Value | ||||
| from django.db.models.functions import Length, Repeat | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class RepeatTests(TestCase): | ||||
| @@ -2,7 +2,7 @@ from django.db.models import F, Value | ||||
| from django.db.models.functions import Concat, Replace | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class ReplaceTests(TestCase): | ||||
| @@ -2,7 +2,7 @@ from django.db.models import CharField, Value | ||||
| from django.db.models.functions import Lower, Right | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class RightTests(TestCase): | ||||
| @@ -3,7 +3,7 @@ from django.db.models.functions import StrIndex | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from .models import Article, Author | ||||
| from ..models import Article, Author | ||||
| 
 | ||||
| 
 | ||||
| class StrIndexTests(TestCase): | ||||
							
								
								
									
										53
									
								
								tests/db_functions/text/test_substr.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/db_functions/text/test_substr.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| from django.db.models import CharField, Value as V | ||||
| from django.db.models.functions import Lower, StrIndex, Substr, Upper | ||||
| from django.test import TestCase | ||||
|  | ||||
| from ..models import Author | ||||
|  | ||||
|  | ||||
| class SubstrTests(TestCase): | ||||
|  | ||||
|     def test_basic(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate(name_part=Substr('name', 5, 3)) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [' Sm', 'da'], | ||||
|             lambda a: a.name_part | ||||
|         ) | ||||
|         authors = Author.objects.annotate(name_part=Substr('name', 2)) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), ['ohn Smith', 'honda'], | ||||
|             lambda a: a.name_part | ||||
|         ) | ||||
|         # If alias is null, set to first 5 lower characters of the name. | ||||
|         Author.objects.filter(alias__isnull=True).update( | ||||
|             alias=Lower(Substr('name', 1, 5)), | ||||
|         ) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), ['smithj', 'rhond'], | ||||
|             lambda a: a.alias | ||||
|         ) | ||||
|  | ||||
|     def test_start(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         a = Author.objects.annotate( | ||||
|             name_part_1=Substr('name', 1), | ||||
|             name_part_2=Substr('name', 2), | ||||
|         ).get(alias='smithj') | ||||
|  | ||||
|         self.assertEqual(a.name_part_1[1:], a.name_part_2) | ||||
|  | ||||
|     def test_pos_gt_zero(self): | ||||
|         with self.assertRaisesMessage(ValueError, "'pos' must be greater than 0"): | ||||
|             Author.objects.annotate(raises=Substr('name', 0)) | ||||
|  | ||||
|     def test_expressions(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         substr = Substr(Upper('name'), StrIndex('name', V('h')), 5, output_field=CharField()) | ||||
|         authors = Author.objects.annotate(name_part=substr) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), ['HN SM', 'HONDA'], | ||||
|             lambda a: a.name_part | ||||
|         ) | ||||
| @@ -2,7 +2,7 @@ from django.db.models import CharField | ||||
| from django.db.models.functions import LTrim, RTrim, Trim | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from .models import Author | ||||
| from ..models import Author | ||||
| 
 | ||||
| 
 | ||||
| class TrimTests(TestCase): | ||||
							
								
								
									
										43
									
								
								tests/db_functions/text/test_upper.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								tests/db_functions/text/test_upper.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| from django.db.models import CharField | ||||
| from django.db.models.functions import Upper | ||||
| from django.test import TestCase | ||||
|  | ||||
| from ..models import Author | ||||
|  | ||||
|  | ||||
| class UpperTests(TestCase): | ||||
|  | ||||
|     def test_basic(self): | ||||
|         Author.objects.create(name='John Smith', alias='smithj') | ||||
|         Author.objects.create(name='Rhonda') | ||||
|         authors = Author.objects.annotate(upper_name=Upper('name')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 'JOHN SMITH', | ||||
|                 'RHONDA', | ||||
|             ], | ||||
|             lambda a: a.upper_name | ||||
|         ) | ||||
|         Author.objects.update(name=Upper('name')) | ||||
|         self.assertQuerysetEqual( | ||||
|             authors.order_by('name'), [ | ||||
|                 ('JOHN SMITH', 'JOHN SMITH'), | ||||
|                 ('RHONDA', 'RHONDA'), | ||||
|             ], | ||||
|             lambda a: (a.upper_name, a.name) | ||||
|         ) | ||||
|  | ||||
|     def test_transform(self): | ||||
|         try: | ||||
|             CharField.register_lookup(Upper) | ||||
|             Author.objects.create(name='John Smith', alias='smithj') | ||||
|             Author.objects.create(name='Rhonda') | ||||
|             authors = Author.objects.filter(name__upper__exact='JOHN SMITH') | ||||
|             self.assertQuerysetEqual( | ||||
|                 authors.order_by('name'), [ | ||||
|                     'John Smith', | ||||
|                 ], | ||||
|                 lambda a: a.name | ||||
|             ) | ||||
|         finally: | ||||
|             CharField._unregister_lookup(Upper) | ||||
		Reference in New Issue
	
	Block a user