diff options
author | django-bot <ops@djangoproject.com> | 2022-02-03 20:24:19 +0100 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-02-07 20:37:05 +0100 |
commit | 9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch) | |
tree | f0506b668a013d0063e5fba3dbf4863b466713ba /tests/db_functions | |
parent | f68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff) | |
download | django-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz |
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/db_functions')
56 files changed, 2192 insertions, 1448 deletions
diff --git a/tests/db_functions/comparison/test_cast.py b/tests/db_functions/comparison/test_cast.py index ffba8af316..afb6b473b9 100644 --- a/tests/db_functions/comparison/test_cast.py +++ b/tests/db_functions/comparison/test_cast.py @@ -13,40 +13,52 @@ from ..models import Author, DTModel, Fan, FloatModel class CastTests(TestCase): @classmethod def setUpTestData(self): - Author.objects.create(name='Bob', age=1, alias='1') + Author.objects.create(name="Bob", age=1, alias="1") def test_cast_from_value(self): - numbers = Author.objects.annotate(cast_integer=Cast(models.Value('0'), models.IntegerField())) + numbers = Author.objects.annotate( + cast_integer=Cast(models.Value("0"), models.IntegerField()) + ) self.assertEqual(numbers.get().cast_integer, 0) def test_cast_from_field(self): - numbers = Author.objects.annotate(cast_string=Cast('age', models.CharField(max_length=255)),) - self.assertEqual(numbers.get().cast_string, '1') + numbers = Author.objects.annotate( + cast_string=Cast("age", models.CharField(max_length=255)), + ) + self.assertEqual(numbers.get().cast_string, "1") def test_cast_to_char_field_without_max_length(self): - numbers = Author.objects.annotate(cast_string=Cast('age', models.CharField())) - self.assertEqual(numbers.get().cast_string, '1') + numbers = Author.objects.annotate(cast_string=Cast("age", models.CharField())) + self.assertEqual(numbers.get().cast_string, "1") # Silence "Truncated incorrect CHAR(1) value: 'Bob'". - @ignore_warnings(module='django.db.backends.mysql.base') - @skipUnlessDBFeature('supports_cast_with_precision') + @ignore_warnings(module="django.db.backends.mysql.base") + @skipUnlessDBFeature("supports_cast_with_precision") def test_cast_to_char_field_with_max_length(self): - names = Author.objects.annotate(cast_string=Cast('name', models.CharField(max_length=1))) - self.assertEqual(names.get().cast_string, 'B') + names = Author.objects.annotate( + cast_string=Cast("name", models.CharField(max_length=1)) + ) + self.assertEqual(names.get().cast_string, "B") - @skipUnlessDBFeature('supports_cast_with_precision') + @skipUnlessDBFeature("supports_cast_with_precision") def test_cast_to_decimal_field(self): FloatModel.objects.create(f1=-1.934, f2=3.467) float_obj = FloatModel.objects.annotate( - cast_f1_decimal=Cast('f1', models.DecimalField(max_digits=8, decimal_places=2)), - cast_f2_decimal=Cast('f2', models.DecimalField(max_digits=8, decimal_places=1)), + cast_f1_decimal=Cast( + "f1", models.DecimalField(max_digits=8, decimal_places=2) + ), + cast_f2_decimal=Cast( + "f2", models.DecimalField(max_digits=8, decimal_places=1) + ), ).get() - self.assertEqual(float_obj.cast_f1_decimal, decimal.Decimal('-1.93')) - self.assertEqual(float_obj.cast_f2_decimal, decimal.Decimal('3.5')) + self.assertEqual(float_obj.cast_f1_decimal, decimal.Decimal("-1.93")) + self.assertEqual(float_obj.cast_f2_decimal, decimal.Decimal("3.5")) author_obj = Author.objects.annotate( - cast_alias_decimal=Cast('alias', models.DecimalField(max_digits=8, decimal_places=2)), + cast_alias_decimal=Cast( + "alias", models.DecimalField(max_digits=8, decimal_places=2) + ), ).get() - self.assertEqual(author_obj.cast_alias_decimal, decimal.Decimal('1')) + self.assertEqual(author_obj.cast_alias_decimal, decimal.Decimal("1")) def test_cast_to_integer(self): for field_class in ( @@ -61,14 +73,14 @@ class CastTests(TestCase): models.PositiveSmallIntegerField, ): with self.subTest(field_class=field_class): - numbers = Author.objects.annotate(cast_int=Cast('alias', field_class())) + numbers = Author.objects.annotate(cast_int=Cast("alias", field_class())) self.assertEqual(numbers.get().cast_int, 1) def test_cast_to_duration(self): duration = datetime.timedelta(days=1, seconds=2, microseconds=3) DTModel.objects.create(duration=duration) dtm = DTModel.objects.annotate( - cast_duration=Cast('duration', models.DurationField()), + cast_duration=Cast("duration", models.DurationField()), cast_neg_duration=Cast(-duration, models.DurationField()), ).get() self.assertEqual(dtm.cast_duration, duration) @@ -78,7 +90,7 @@ class CastTests(TestCase): dt_value = datetime.datetime(2018, 9, 28, 12, 42, 10, 234567) DTModel.objects.create(start_datetime=dt_value) dtm = DTModel.objects.annotate( - start_datetime_as_date=Cast('start_datetime', models.DateField()) + start_datetime_as_date=Cast("start_datetime", models.DateField()) ).first() self.assertEqual(dtm.start_datetime_as_date, datetime.date(2018, 9, 28)) @@ -86,27 +98,39 @@ class CastTests(TestCase): dt_value = datetime.datetime(2018, 9, 28, 12, 42, 10, 234567) DTModel.objects.create(start_datetime=dt_value) dtm = DTModel.objects.annotate( - start_datetime_as_time=Cast('start_datetime', models.TimeField()) + start_datetime_as_time=Cast("start_datetime", models.TimeField()) ).first() - rounded_ms = int(round(.234567, connection.features.time_cast_precision) * 10**6) - self.assertEqual(dtm.start_datetime_as_time, datetime.time(12, 42, 10, rounded_ms)) + rounded_ms = int( + round(0.234567, connection.features.time_cast_precision) * 10**6 + ) + self.assertEqual( + dtm.start_datetime_as_time, datetime.time(12, 42, 10, rounded_ms) + ) def test_cast_from_db_date_to_datetime(self): dt_value = datetime.date(2018, 9, 28) DTModel.objects.create(start_date=dt_value) - dtm = DTModel.objects.annotate(start_as_datetime=Cast('start_date', models.DateTimeField())).first() - self.assertEqual(dtm.start_as_datetime, datetime.datetime(2018, 9, 28, 0, 0, 0, 0)) + dtm = DTModel.objects.annotate( + start_as_datetime=Cast("start_date", models.DateTimeField()) + ).first() + self.assertEqual( + dtm.start_as_datetime, datetime.datetime(2018, 9, 28, 0, 0, 0, 0) + ) def test_cast_from_db_datetime_to_date_group_by(self): - author = Author.objects.create(name='John Smith', age=45) + author = Author.objects.create(name="John Smith", age=45) dt_value = datetime.datetime(2018, 9, 28, 12, 42, 10, 234567) - Fan.objects.create(name='Margaret', age=50, author=author, fan_since=dt_value) - fans = Fan.objects.values('author').annotate( - fan_for_day=Cast('fan_since', models.DateField()), - fans=models.Count('*') - ).values() - self.assertEqual(fans[0]['fan_for_day'], datetime.date(2018, 9, 28)) - self.assertEqual(fans[0]['fans'], 1) + Fan.objects.create(name="Margaret", age=50, author=author, fan_since=dt_value) + fans = ( + Fan.objects.values("author") + .annotate( + fan_for_day=Cast("fan_since", models.DateField()), + fans=models.Count("*"), + ) + .values() + ) + self.assertEqual(fans[0]["fan_for_day"], datetime.date(2018, 9, 28)) + self.assertEqual(fans[0]["fans"], 1) def test_cast_from_python_to_date(self): today = datetime.date.today() @@ -117,30 +141,39 @@ class CastTests(TestCase): now = datetime.datetime.now() dates = Author.objects.annotate(cast_datetime=Cast(now, models.DateTimeField())) time_precision = datetime.timedelta( - microseconds=10**(6 - connection.features.time_cast_precision) + microseconds=10 ** (6 - connection.features.time_cast_precision) ) self.assertAlmostEqual(dates.get().cast_datetime, now, delta=time_precision) def test_cast_from_python(self): - numbers = Author.objects.annotate(cast_float=Cast(decimal.Decimal(0.125), models.FloatField())) + numbers = Author.objects.annotate( + cast_float=Cast(decimal.Decimal(0.125), models.FloatField()) + ) cast_float = numbers.get().cast_float self.assertIsInstance(cast_float, float) self.assertEqual(cast_float, 0.125) - @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL test') + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL test") def test_expression_wrapped_with_parentheses_on_postgresql(self): """ The SQL for the Cast expression is wrapped with parentheses in case it's a complex expression. """ with CaptureQueriesContext(connection) as captured_queries: - list(Author.objects.annotate( - cast_float=Cast(models.Avg('age'), models.FloatField()), - )) + list( + Author.objects.annotate( + cast_float=Cast(models.Avg("age"), models.FloatField()), + ) + ) self.assertIn( '(AVG("db_functions_author"."age"))::double precision', - captured_queries[0]['sql'], + captured_queries[0]["sql"], ) def test_cast_to_text_field(self): - self.assertEqual(Author.objects.values_list(Cast('age', models.TextField()), flat=True).get(), '1') + self.assertEqual( + Author.objects.values_list( + Cast("age", models.TextField()), flat=True + ).get(), + "1", + ) diff --git a/tests/db_functions/comparison/test_coalesce.py b/tests/db_functions/comparison/test_coalesce.py index 1093079d68..9125923847 100644 --- a/tests/db_functions/comparison/test_coalesce.py +++ b/tests/db_functions/comparison/test_coalesce.py @@ -11,25 +11,25 @@ lorem_ipsum = """ class CoalesceTests(TestCase): - def test_basic(self): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') - authors = Author.objects.annotate(display_name=Coalesce('alias', 'name')) + Author.objects.create(name="John Smith", alias="smithj") + Author.objects.create(name="Rhonda") + authors = Author.objects.annotate(display_name=Coalesce("alias", "name")) self.assertQuerysetEqual( - authors.order_by('name'), ['smithj', 'Rhonda'], - lambda a: a.display_name + authors.order_by("name"), ["smithj", "Rhonda"], lambda a: a.display_name ) def test_gt_two_expressions(self): - with self.assertRaisesMessage(ValueError, 'Coalesce must take at least two expressions'): - Author.objects.annotate(display_name=Coalesce('alias')) + with self.assertRaisesMessage( + ValueError, "Coalesce must take at least two expressions" + ): + Author.objects.annotate(display_name=Coalesce("alias")) def test_mixed_values(self): - a1 = Author.objects.create(name='John Smith', alias='smithj') - a2 = Author.objects.create(name='Rhonda') + a1 = Author.objects.create(name="John Smith", alias="smithj") + a2 = Author.objects.create(name="Rhonda") ar1 = Article.objects.create( - title='How to Django', + title="How to Django", text=lorem_ipsum, written=timezone.now(), ) @@ -37,42 +37,33 @@ class CoalesceTests(TestCase): ar1.authors.add(a2) # mixed Text and Char article = Article.objects.annotate( - headline=Coalesce('summary', 'text', output_field=TextField()), + headline=Coalesce("summary", "text", output_field=TextField()), ) self.assertQuerysetEqual( - article.order_by('title'), [lorem_ipsum], - lambda a: a.headline + article.order_by("title"), [lorem_ipsum], lambda a: a.headline ) # mixed Text and Char wrapped article = Article.objects.annotate( - headline=Coalesce(Lower('summary'), Lower('text'), output_field=TextField()), + headline=Coalesce( + Lower("summary"), Lower("text"), output_field=TextField() + ), ) self.assertQuerysetEqual( - article.order_by('title'), [lorem_ipsum.lower()], - lambda a: a.headline + article.order_by("title"), [lorem_ipsum.lower()], lambda a: a.headline ) def test_ordering(self): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') - authors = Author.objects.order_by(Coalesce('alias', 'name')) - self.assertQuerysetEqual( - authors, ['Rhonda', 'John Smith'], - lambda a: a.name - ) - authors = Author.objects.order_by(Coalesce('alias', 'name').asc()) - self.assertQuerysetEqual( - authors, ['Rhonda', 'John Smith'], - lambda a: a.name - ) - authors = Author.objects.order_by(Coalesce('alias', 'name').desc()) - self.assertQuerysetEqual( - authors, ['John Smith', 'Rhonda'], - lambda a: a.name - ) + Author.objects.create(name="John Smith", alias="smithj") + Author.objects.create(name="Rhonda") + authors = Author.objects.order_by(Coalesce("alias", "name")) + self.assertQuerysetEqual(authors, ["Rhonda", "John Smith"], lambda a: a.name) + authors = Author.objects.order_by(Coalesce("alias", "name").asc()) + self.assertQuerysetEqual(authors, ["Rhonda", "John Smith"], lambda a: a.name) + authors = Author.objects.order_by(Coalesce("alias", "name").desc()) + self.assertQuerysetEqual(authors, ["John Smith", "Rhonda"], lambda a: a.name) def test_empty_queryset(self): - Author.objects.create(name='John Smith') + Author.objects.create(name="John Smith") tests = [ Author.objects.none(), Subquery(Author.objects.none()), diff --git a/tests/db_functions/comparison/test_collate.py b/tests/db_functions/comparison/test_collate.py index b680ed9a05..25f55f6b2d 100644 --- a/tests/db_functions/comparison/test_collate.py +++ b/tests/db_functions/comparison/test_collate.py @@ -9,35 +9,31 @@ from ..models import Author class CollateTests(TestCase): @classmethod def setUpTestData(cls): - cls.author1 = Author.objects.create(alias='a', name='Jones 1') - cls.author2 = Author.objects.create(alias='A', name='Jones 2') + cls.author1 = Author.objects.create(alias="a", name="Jones 1") + cls.author2 = Author.objects.create(alias="A", name="Jones 2") def test_collate_filter_ci(self): - collation = connection.features.test_collations.get('ci') + collation = connection.features.test_collations.get("ci") if not collation: - self.skipTest( - 'This backend does not support case-insensitive collations.' - ) - qs = Author.objects.filter(alias=Collate(Value('a'), collation)) + self.skipTest("This backend does not support case-insensitive collations.") + qs = Author.objects.filter(alias=Collate(Value("a"), collation)) self.assertEqual(qs.count(), 2) def test_collate_order_by_cs(self): - collation = connection.features.test_collations.get('cs') + collation = connection.features.test_collations.get("cs") if not collation: - self.skipTest( - 'This backend does not support case-sensitive collations.' - ) - qs = Author.objects.order_by(Collate('alias', collation)) + self.skipTest("This backend does not support case-sensitive collations.") + qs = Author.objects.order_by(Collate("alias", collation)) self.assertSequenceEqual(qs, [self.author2, self.author1]) def test_language_collation_order_by(self): - collation = connection.features.test_collations.get('swedish_ci') + collation = connection.features.test_collations.get("swedish_ci") if not collation: - self.skipTest('This backend does not support language collations.') - author3 = Author.objects.create(alias='O', name='Jones') - author4 = Author.objects.create(alias='Ö', name='Jones') - author5 = Author.objects.create(alias='P', name='Jones') - qs = Author.objects.order_by(Collate(F('alias'), collation), 'name') + self.skipTest("This backend does not support language collations.") + author3 = Author.objects.create(alias="O", name="Jones") + author4 = Author.objects.create(alias="Ö", name="Jones") + author5 = Author.objects.create(alias="P", name="Jones") + qs = Author.objects.order_by(Collate(F("alias"), collation), "name") self.assertSequenceEqual( qs, [self.author1, self.author2, author3, author5, author4], @@ -46,11 +42,11 @@ class CollateTests(TestCase): def test_invalid_collation(self): tests = [ None, - '', + "", 'et-x-icu" OR ', '"schema"."collation"', ] msg = "Invalid collation name: %r." for value in tests: with self.subTest(value), self.assertRaisesMessage(ValueError, msg % value): - Collate(F('alias'), value) + Collate(F("alias"), value) diff --git a/tests/db_functions/comparison/test_greatest.py b/tests/db_functions/comparison/test_greatest.py index f11e7b824c..c37514adf7 100644 --- a/tests/db_functions/comparison/test_greatest.py +++ b/tests/db_functions/comparison/test_greatest.py @@ -12,79 +12,90 @@ from ..models import Article, Author, DecimalModel, Fan class GreatestTests(TestCase): - def test_basic(self): now = timezone.now() before = now - timedelta(hours=1) - Article.objects.create(title='Testing with Django', written=before, published=now) - articles = Article.objects.annotate(last_updated=Greatest('written', 'published')) + Article.objects.create( + title="Testing with Django", written=before, published=now + ) + articles = Article.objects.annotate( + last_updated=Greatest("written", "published") + ) self.assertEqual(articles.first().last_updated, now) - @skipUnlessDBFeature('greatest_least_ignores_nulls') + @skipUnlessDBFeature("greatest_least_ignores_nulls") def test_ignores_null(self): now = timezone.now() - Article.objects.create(title='Testing with Django', written=now) - articles = Article.objects.annotate(last_updated=Greatest('written', 'published')) + Article.objects.create(title="Testing with Django", written=now) + articles = Article.objects.annotate( + last_updated=Greatest("written", "published") + ) self.assertEqual(articles.first().last_updated, now) - @skipIfDBFeature('greatest_least_ignores_nulls') + @skipIfDBFeature("greatest_least_ignores_nulls") def test_propagates_null(self): - Article.objects.create(title='Testing with Django', written=timezone.now()) - articles = Article.objects.annotate(last_updated=Greatest('written', 'published')) + Article.objects.create(title="Testing with Django", written=timezone.now()) + articles = Article.objects.annotate( + last_updated=Greatest("written", "published") + ) self.assertIsNone(articles.first().last_updated) def test_coalesce_workaround(self): past = datetime(1900, 1, 1) now = timezone.now() - Article.objects.create(title='Testing with Django', written=now) + Article.objects.create(title="Testing with Django", written=now) articles = Article.objects.annotate( last_updated=Greatest( - Coalesce('written', past), - Coalesce('published', past), + Coalesce("written", past), + Coalesce("published", past), ), ) self.assertEqual(articles.first().last_updated, now) - @skipUnless(connection.vendor == 'mysql', "MySQL-specific workaround") + @skipUnless(connection.vendor == "mysql", "MySQL-specific workaround") def test_coalesce_workaround_mysql(self): past = datetime(1900, 1, 1) now = timezone.now() - Article.objects.create(title='Testing with Django', written=now) + Article.objects.create(title="Testing with Django", written=now) past_sql = RawSQL("cast(%s as datetime)", (past,)) articles = Article.objects.annotate( last_updated=Greatest( - Coalesce('written', past_sql), - Coalesce('published', past_sql), + Coalesce("written", past_sql), + Coalesce("published", past_sql), ), ) self.assertEqual(articles.first().last_updated, now) def test_all_null(self): - Article.objects.create(title='Testing with Django', written=timezone.now()) - articles = Article.objects.annotate(last_updated=Greatest('published', 'updated')) + Article.objects.create(title="Testing with Django", written=timezone.now()) + articles = Article.objects.annotate( + last_updated=Greatest("published", "updated") + ) self.assertIsNone(articles.first().last_updated) def test_one_expressions(self): - with self.assertRaisesMessage(ValueError, 'Greatest must take at least two expressions'): - Greatest('written') + with self.assertRaisesMessage( + ValueError, "Greatest must take at least two expressions" + ): + Greatest("written") def test_related_field(self): - author = Author.objects.create(name='John Smith', age=45) - Fan.objects.create(name='Margaret', age=50, author=author) - authors = Author.objects.annotate(highest_age=Greatest('age', 'fans__age')) + author = Author.objects.create(name="John Smith", age=45) + Fan.objects.create(name="Margaret", age=50, author=author) + authors = Author.objects.annotate(highest_age=Greatest("age", "fans__age")) self.assertEqual(authors.first().highest_age, 50) def test_update(self): - author = Author.objects.create(name='James Smith', goes_by='Jim') - Author.objects.update(alias=Greatest('name', 'goes_by')) + author = Author.objects.create(name="James Smith", goes_by="Jim") + Author.objects.update(alias=Greatest("name", "goes_by")) author.refresh_from_db() - self.assertEqual(author.alias, 'Jim') + self.assertEqual(author.alias, "Jim") def test_decimal_filter(self): - obj = DecimalModel.objects.create(n1=Decimal('1.1'), n2=Decimal('1.2')) + obj = DecimalModel.objects.create(n1=Decimal("1.1"), n2=Decimal("1.2")) self.assertCountEqual( DecimalModel.objects.annotate( - greatest=Greatest('n1', 'n2'), - ).filter(greatest=Decimal('1.2')), + greatest=Greatest("n1", "n2"), + ).filter(greatest=Decimal("1.2")), [obj], ) diff --git a/tests/db_functions/comparison/test_json_object.py b/tests/db_functions/comparison/test_json_object.py index 2c7c1beae9..7a10657317 100644 --- a/tests/db_functions/comparison/test_json_object.py +++ b/tests/db_functions/comparison/test_json_object.py @@ -8,75 +8,90 @@ from django.utils import timezone from ..models import Article, Author -@skipUnlessDBFeature('has_json_object_function') +@skipUnlessDBFeature("has_json_object_function") class JSONObjectTests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.create(name='Ivan Ivanov', alias='iivanov') + Author.objects.create(name="Ivan Ivanov", alias="iivanov") def test_empty(self): obj = Author.objects.annotate(json_object=JSONObject()).first() self.assertEqual(obj.json_object, {}) def test_basic(self): - obj = Author.objects.annotate(json_object=JSONObject(name='name')).first() - self.assertEqual(obj.json_object, {'name': 'Ivan Ivanov'}) + obj = Author.objects.annotate(json_object=JSONObject(name="name")).first() + self.assertEqual(obj.json_object, {"name": "Ivan Ivanov"}) def test_expressions(self): - obj = Author.objects.annotate(json_object=JSONObject( - name=Lower('name'), - alias='alias', - goes_by='goes_by', - salary=Value(30000.15), - age=F('age') * 2, - )).first() - self.assertEqual(obj.json_object, { - 'name': 'ivan ivanov', - 'alias': 'iivanov', - 'goes_by': None, - 'salary': 30000.15, - 'age': 60, - }) + obj = Author.objects.annotate( + json_object=JSONObject( + name=Lower("name"), + alias="alias", + goes_by="goes_by", + salary=Value(30000.15), + age=F("age") * 2, + ) + ).first() + self.assertEqual( + obj.json_object, + { + "name": "ivan ivanov", + "alias": "iivanov", + "goes_by": None, + "salary": 30000.15, + "age": 60, + }, + ) def test_nested_json_object(self): - obj = Author.objects.annotate(json_object=JSONObject( - name='name', - nested_json_object=JSONObject( - alias='alias', - age='age', - ), - )).first() - self.assertEqual(obj.json_object, { - 'name': 'Ivan Ivanov', - 'nested_json_object': { - 'alias': 'iivanov', - 'age': 30, + obj = Author.objects.annotate( + json_object=JSONObject( + name="name", + nested_json_object=JSONObject( + alias="alias", + age="age", + ), + ) + ).first() + self.assertEqual( + obj.json_object, + { + "name": "Ivan Ivanov", + "nested_json_object": { + "alias": "iivanov", + "age": 30, + }, }, - }) + ) def test_nested_empty_json_object(self): - obj = Author.objects.annotate(json_object=JSONObject( - name='name', - nested_json_object=JSONObject(), - )).first() - self.assertEqual(obj.json_object, { - 'name': 'Ivan Ivanov', - 'nested_json_object': {}, - }) + obj = Author.objects.annotate( + json_object=JSONObject( + name="name", + nested_json_object=JSONObject(), + ) + ).first() + self.assertEqual( + obj.json_object, + { + "name": "Ivan Ivanov", + "nested_json_object": {}, + }, + ) def test_textfield(self): Article.objects.create( - title='The Title', - text='x' * 4000, + title="The Title", + text="x" * 4000, written=timezone.now(), ) - obj = Article.objects.annotate(json_object=JSONObject(text=F('text'))).first() - self.assertEqual(obj.json_object, {'text': 'x' * 4000}) + obj = Article.objects.annotate(json_object=JSONObject(text=F("text"))).first() + self.assertEqual(obj.json_object, {"text": "x" * 4000}) -@skipIfDBFeature('has_json_object_function') +@skipIfDBFeature("has_json_object_function") class JSONObjectNotSupportedTests(TestCase): def test_not_supported(self): - msg = 'JSONObject() is not supported on this database backend.' + msg = "JSONObject() is not supported on this database backend." with self.assertRaisesMessage(NotSupportedError, msg): Author.objects.annotate(json_object=JSONObject()).get() diff --git a/tests/db_functions/comparison/test_least.py b/tests/db_functions/comparison/test_least.py index e0318e25c6..eb7514187a 100644 --- a/tests/db_functions/comparison/test_least.py +++ b/tests/db_functions/comparison/test_least.py @@ -12,81 +12,84 @@ from ..models import Article, Author, DecimalModel, Fan class LeastTests(TestCase): - def test_basic(self): now = timezone.now() before = now - timedelta(hours=1) - Article.objects.create(title='Testing with Django', written=before, published=now) - articles = Article.objects.annotate(first_updated=Least('written', 'published')) + Article.objects.create( + title="Testing with Django", written=before, published=now + ) + articles = Article.objects.annotate(first_updated=Least("written", "published")) self.assertEqual(articles.first().first_updated, before) - @skipUnlessDBFeature('greatest_least_ignores_nulls') + @skipUnlessDBFeature("greatest_least_ignores_nulls") def test_ignores_null(self): now = timezone.now() - Article.objects.create(title='Testing with Django', written=now) + Article.objects.create(title="Testing with Django", written=now) articles = Article.objects.annotate( - first_updated=Least('written', 'published'), + first_updated=Least("written", "published"), ) self.assertEqual(articles.first().first_updated, now) - @skipIfDBFeature('greatest_least_ignores_nulls') + @skipIfDBFeature("greatest_least_ignores_nulls") def test_propagates_null(self): - Article.objects.create(title='Testing with Django', written=timezone.now()) - articles = Article.objects.annotate(first_updated=Least('written', 'published')) + Article.objects.create(title="Testing with Django", written=timezone.now()) + articles = Article.objects.annotate(first_updated=Least("written", "published")) self.assertIsNone(articles.first().first_updated) def test_coalesce_workaround(self): future = datetime(2100, 1, 1) now = timezone.now() - Article.objects.create(title='Testing with Django', written=now) + Article.objects.create(title="Testing with Django", written=now) articles = Article.objects.annotate( last_updated=Least( - Coalesce('written', future), - Coalesce('published', future), + Coalesce("written", future), + Coalesce("published", future), ), ) self.assertEqual(articles.first().last_updated, now) - @skipUnless(connection.vendor == 'mysql', "MySQL-specific workaround") + @skipUnless(connection.vendor == "mysql", "MySQL-specific workaround") def test_coalesce_workaround_mysql(self): future = datetime(2100, 1, 1) now = timezone.now() - Article.objects.create(title='Testing with Django', written=now) + Article.objects.create(title="Testing with Django", written=now) future_sql = RawSQL("cast(%s as datetime)", (future,)) articles = Article.objects.annotate( last_updated=Least( - Coalesce('written', future_sql), - Coalesce('published', future_sql), + Coalesce("written", future_sql), + Coalesce("published", future_sql), ), ) self.assertEqual(articles.first().last_updated, now) def test_all_null(self): - Article.objects.create(title='Testing with Django', written=timezone.now()) - articles = Article.objects.annotate(first_updated=Least('published', 'updated')) + Article.objects.create(title="Testing with Django", written=timezone.now()) + articles = Article.objects.annotate(first_updated=Least("published", "updated")) self.assertIsNone(articles.first().first_updated) def test_one_expressions(self): - with self.assertRaisesMessage(ValueError, 'Least must take at least two expressions'): - Least('written') + with self.assertRaisesMessage( + ValueError, "Least must take at least two expressions" + ): + Least("written") def test_related_field(self): - author = Author.objects.create(name='John Smith', age=45) - Fan.objects.create(name='Margaret', age=50, author=author) - authors = Author.objects.annotate(lowest_age=Least('age', 'fans__age')) + author = Author.objects.create(name="John Smith", age=45) + Fan.objects.create(name="Margaret", age=50, author=author) + authors = Author.objects.annotate(lowest_age=Least("age", "fans__age")) self.assertEqual(authors.first().lowest_age, 45) def test_update(self): - author = Author.objects.create(name='James Smith', goes_by='Jim') - Author.objects.update(alias=Least('name', 'goes_by')) + author = Author.objects.create(name="James Smith", goes_by="Jim") + Author.objects.update(alias=Least("name", "goes_by")) author.refresh_from_db() - self.assertEqual(author.alias, 'James Smith') + self.assertEqual(author.alias, "James Smith") def test_decimal_filter(self): - obj = DecimalModel.objects.create(n1=Decimal('1.1'), n2=Decimal('1.2')) + obj = DecimalModel.objects.create(n1=Decimal("1.1"), n2=Decimal("1.2")) self.assertCountEqual( DecimalModel.objects.annotate( - least=Least('n1', 'n2'), - ).filter(least=Decimal('1.1')), + least=Least("n1", "n2"), + ).filter(least=Decimal("1.1")), [obj], ) diff --git a/tests/db_functions/comparison/test_nullif.py b/tests/db_functions/comparison/test_nullif.py index 36f881ed57..a65885a3ec 100644 --- a/tests/db_functions/comparison/test_nullif.py +++ b/tests/db_functions/comparison/test_nullif.py @@ -9,32 +9,44 @@ from ..models import Author class NullIfTests(TestCase): - @classmethod def setUpTestData(cls): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda', alias='Rhonda') + Author.objects.create(name="John Smith", alias="smithj") + Author.objects.create(name="Rhonda", alias="Rhonda") def test_basic(self): - authors = Author.objects.annotate(nullif=NullIf('alias', 'name')).values_list('nullif') + authors = Author.objects.annotate(nullif=NullIf("alias", "name")).values_list( + "nullif" + ) self.assertSequenceEqual( - authors, [ - ('smithj',), - ('' if connection.features.interprets_empty_strings_as_nulls else None,) - ] + authors, + [ + ("smithj",), + ( + "" + if connection.features.interprets_empty_strings_as_nulls + else None, + ), + ], ) def test_null_argument(self): - authors = Author.objects.annotate(nullif=NullIf('name', Value(None))).values_list('nullif') - self.assertSequenceEqual(authors, [('John Smith',), ('Rhonda',)]) + authors = Author.objects.annotate( + nullif=NullIf("name", Value(None)) + ).values_list("nullif") + self.assertSequenceEqual(authors, [("John Smith",), ("Rhonda",)]) def test_too_few_args(self): msg = "'NullIf' takes exactly 2 arguments (1 given)" with self.assertRaisesMessage(TypeError, msg): - NullIf('name') + NullIf("name") - @skipUnless(connection.vendor == 'oracle', 'Oracle specific test for NULL-literal') + @skipUnless(connection.vendor == "oracle", "Oracle specific test for NULL-literal") def test_null_literal(self): - msg = 'Oracle does not allow Value(None) for expression1.' + msg = "Oracle does not allow Value(None) for expression1." with self.assertRaisesMessage(ValueError, msg): - list(Author.objects.annotate(nullif=NullIf(Value(None), 'name')).values_list('nullif')) + list( + Author.objects.annotate(nullif=NullIf(Value(None), "name")).values_list( + "nullif" + ) + ) diff --git a/tests/db_functions/datetime/test_extract_trunc.py b/tests/db_functions/datetime/test_extract_trunc.py index aa242b90fe..5a92993912 100644 --- a/tests/db_functions/datetime/test_extract_trunc.py +++ b/tests/db_functions/datetime/test_extract_trunc.py @@ -1,5 +1,6 @@ import unittest -from datetime import datetime, timedelta, timezone as datetime_timezone +from datetime import datetime, timedelta +from datetime import timezone as datetime_timezone try: import zoneinfo @@ -13,18 +14,45 @@ except ImportError: from django.conf import settings from django.db.models import ( - DateField, DateTimeField, F, IntegerField, Max, OuterRef, Subquery, + DateField, + DateTimeField, + F, + IntegerField, + Max, + OuterRef, + Subquery, TimeField, ) from django.db.models.functions import ( - Extract, ExtractDay, ExtractHour, ExtractIsoWeekDay, ExtractIsoYear, - ExtractMinute, ExtractMonth, ExtractQuarter, ExtractSecond, ExtractWeek, - ExtractWeekDay, ExtractYear, Trunc, TruncDate, TruncDay, TruncHour, - TruncMinute, TruncMonth, TruncQuarter, TruncSecond, TruncTime, TruncWeek, + Extract, + ExtractDay, + ExtractHour, + ExtractIsoWeekDay, + ExtractIsoYear, + ExtractMinute, + ExtractMonth, + ExtractQuarter, + ExtractSecond, + ExtractWeek, + ExtractWeekDay, + ExtractYear, + Trunc, + TruncDate, + TruncDay, + TruncHour, + TruncMinute, + TruncMonth, + TruncQuarter, + TruncSecond, + TruncTime, + TruncWeek, TruncYear, ) from django.test import ( - TestCase, ignore_warnings, override_settings, skipIfDBFeature, + TestCase, + ignore_warnings, + override_settings, + skipIfDBFeature, skipUnlessDBFeature, ) from django.utils import timezone @@ -34,11 +62,13 @@ from ..models import Author, DTModel, Fan HAS_PYTZ = pytz is not None if not HAS_PYTZ: - needs_pytz = unittest.skip('Test requires pytz') + needs_pytz = unittest.skip("Test requires pytz") else: + def needs_pytz(f): return f + ZONE_CONSTRUCTORS = (zoneinfo.ZoneInfo,) if HAS_PYTZ: ZONE_CONSTRUCTORS += (pytz.timezone,) @@ -50,32 +80,43 @@ def truncate_to(value, kind, tzinfo=None): value = value.astimezone(tzinfo) def truncate(value, kind): - if kind == 'second': + if kind == "second": return value.replace(microsecond=0) - if kind == 'minute': + if kind == "minute": return value.replace(second=0, microsecond=0) - if kind == 'hour': + if kind == "hour": return value.replace(minute=0, second=0, microsecond=0) - if kind == 'day': + if kind == "day": if isinstance(value, datetime): return value.replace(hour=0, minute=0, second=0, microsecond=0) return value - if kind == 'week': + if kind == "week": if isinstance(value, datetime): - return (value - timedelta(days=value.weekday())).replace(hour=0, minute=0, second=0, microsecond=0) + return (value - timedelta(days=value.weekday())).replace( + hour=0, minute=0, second=0, microsecond=0 + ) return value - timedelta(days=value.weekday()) - if kind == 'month': + if kind == "month": if isinstance(value, datetime): return value.replace(day=1, hour=0, minute=0, second=0, microsecond=0) return value.replace(day=1) - if kind == 'quarter': + if kind == "quarter": month_in_quarter = value.month - (value.month - 1) % 3 if isinstance(value, datetime): - return value.replace(month=month_in_quarter, day=1, hour=0, minute=0, second=0, microsecond=0) + return value.replace( + month=month_in_quarter, + day=1, + hour=0, + minute=0, + second=0, + microsecond=0, + ) return value.replace(month=month_in_quarter, day=1) # otherwise, truncate to year if isinstance(value, datetime): - return value.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0) + return value.replace( + month=1, day=1, hour=0, minute=0, second=0, microsecond=0 + ) return value.replace(month=1, day=1) value = truncate(value, kind) @@ -87,17 +128,18 @@ def truncate_to(value, kind, tzinfo=None): @override_settings(USE_TZ=False) class DateFunctionTests(TestCase): - def create_model(self, start_datetime, end_datetime): return DTModel.objects.create( - name=start_datetime.isoformat() if start_datetime else 'None', + name=start_datetime.isoformat() if start_datetime else "None", start_datetime=start_datetime, end_datetime=end_datetime, start_date=start_datetime.date() if start_datetime else None, end_date=end_datetime.date() if end_datetime else None, start_time=start_datetime.time() if start_datetime else None, end_time=end_datetime.time() if end_datetime else None, - duration=(end_datetime - start_datetime) if start_datetime and end_datetime else None, + duration=(end_datetime - start_datetime) + if start_datetime and end_datetime + else None, ) def test_extract_year_exact_lookup(self): @@ -113,33 +155,35 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) - for lookup in ('year', 'iso_year'): + for lookup in ("year", "iso_year"): with self.subTest(lookup): - qs = DTModel.objects.filter(**{'start_datetime__%s__exact' % lookup: 2015}) + qs = DTModel.objects.filter( + **{"start_datetime__%s__exact" % lookup: 2015} + ) self.assertEqual(qs.count(), 1) query_string = str(qs.query).lower() - self.assertEqual(query_string.count(' between '), 1) - self.assertEqual(query_string.count('extract'), 0) + self.assertEqual(query_string.count(" between "), 1) + self.assertEqual(query_string.count("extract"), 0) # exact is implied and should be the same - qs = DTModel.objects.filter(**{'start_datetime__%s' % lookup: 2015}) + qs = DTModel.objects.filter(**{"start_datetime__%s" % lookup: 2015}) self.assertEqual(qs.count(), 1) query_string = str(qs.query).lower() - self.assertEqual(query_string.count(' between '), 1) - self.assertEqual(query_string.count('extract'), 0) + self.assertEqual(query_string.count(" between "), 1) + self.assertEqual(query_string.count("extract"), 0) # date and datetime fields should behave the same - qs = DTModel.objects.filter(**{'start_date__%s' % lookup: 2015}) + qs = DTModel.objects.filter(**{"start_date__%s" % lookup: 2015}) self.assertEqual(qs.count(), 1) query_string = str(qs.query).lower() - self.assertEqual(query_string.count(' between '), 1) - self.assertEqual(query_string.count('extract'), 0) + self.assertEqual(query_string.count(" between "), 1) + self.assertEqual(query_string.count("extract"), 0) # an expression rhs cannot use the between optimization. qs = DTModel.objects.annotate( - start_year=ExtractYear('start_datetime'), - ).filter(end_datetime__year=F('start_year') + 1) + start_year=ExtractYear("start_datetime"), + ).filter(end_datetime__year=F("start_year") + 1) self.assertEqual(qs.count(), 1) query_string = str(qs.query).lower() - self.assertEqual(query_string.count(' between '), 0) - self.assertEqual(query_string.count('extract'), 3) + self.assertEqual(query_string.count(" between "), 0) + self.assertEqual(query_string.count("extract"), 3) def test_extract_year_greaterthan_lookup(self): start_datetime = datetime(2015, 6, 15, 14, 10) @@ -150,19 +194,21 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) - for lookup in ('year', 'iso_year'): + for lookup in ("year", "iso_year"): with self.subTest(lookup): - qs = DTModel.objects.filter(**{'start_datetime__%s__gt' % lookup: 2015}) + qs = DTModel.objects.filter(**{"start_datetime__%s__gt" % lookup: 2015}) self.assertEqual(qs.count(), 1) - self.assertEqual(str(qs.query).lower().count('extract'), 0) - qs = DTModel.objects.filter(**{'start_datetime__%s__gte' % lookup: 2015}) + self.assertEqual(str(qs.query).lower().count("extract"), 0) + qs = DTModel.objects.filter( + **{"start_datetime__%s__gte" % lookup: 2015} + ) self.assertEqual(qs.count(), 2) - self.assertEqual(str(qs.query).lower().count('extract'), 0) + self.assertEqual(str(qs.query).lower().count("extract"), 0) qs = DTModel.objects.annotate( - start_year=ExtractYear('start_datetime'), - ).filter(**{'end_datetime__%s__gte' % lookup: F('start_year')}) + start_year=ExtractYear("start_datetime"), + ).filter(**{"end_datetime__%s__gte" % lookup: F("start_year")}) self.assertEqual(qs.count(), 1) - self.assertGreaterEqual(str(qs.query).lower().count('extract'), 2) + self.assertGreaterEqual(str(qs.query).lower().count("extract"), 2) def test_extract_year_lessthan_lookup(self): start_datetime = datetime(2015, 6, 15, 14, 10) @@ -173,19 +219,21 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) - for lookup in ('year', 'iso_year'): + for lookup in ("year", "iso_year"): with self.subTest(lookup): - qs = DTModel.objects.filter(**{'start_datetime__%s__lt' % lookup: 2016}) + qs = DTModel.objects.filter(**{"start_datetime__%s__lt" % lookup: 2016}) self.assertEqual(qs.count(), 1) - self.assertEqual(str(qs.query).count('extract'), 0) - qs = DTModel.objects.filter(**{'start_datetime__%s__lte' % lookup: 2016}) + self.assertEqual(str(qs.query).count("extract"), 0) + qs = DTModel.objects.filter( + **{"start_datetime__%s__lte" % lookup: 2016} + ) self.assertEqual(qs.count(), 2) - self.assertEqual(str(qs.query).count('extract'), 0) + self.assertEqual(str(qs.query).count("extract"), 0) qs = DTModel.objects.annotate( - end_year=ExtractYear('end_datetime'), - ).filter(**{'start_datetime__%s__lte' % lookup: F('end_year')}) + end_year=ExtractYear("end_datetime"), + ).filter(**{"start_datetime__%s__lte" % lookup: F("end_year")}) self.assertEqual(qs.count(), 1) - self.assertGreaterEqual(str(qs.query).lower().count('extract'), 2) + self.assertGreaterEqual(str(qs.query).lower().count("extract"), 2) def test_extract_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -196,96 +244,151 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) - with self.assertRaisesMessage(ValueError, 'lookup_name must be provided'): - Extract('start_datetime') + with self.assertRaisesMessage(ValueError, "lookup_name must be provided"): + Extract("start_datetime") - msg = 'Extract input expression must be DateField, DateTimeField, TimeField, or DurationField.' + msg = "Extract input expression must be DateField, DateTimeField, TimeField, or DurationField." with self.assertRaisesMessage(ValueError, msg): - list(DTModel.objects.annotate(extracted=Extract('name', 'hour'))) + list(DTModel.objects.annotate(extracted=Extract("name", "hour"))) with self.assertRaisesMessage( - ValueError, "Cannot extract time component 'second' from DateField 'start_date'."): - list(DTModel.objects.annotate(extracted=Extract('start_date', 'second'))) + ValueError, + "Cannot extract time component 'second' from DateField 'start_date'.", + ): + list(DTModel.objects.annotate(extracted=Extract("start_date", "second"))) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'year')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=Extract("start_datetime", "year") + ).order_by("start_datetime"), [(start_datetime, start_datetime.year), (end_datetime, end_datetime.year)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'quarter')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=Extract("start_datetime", "quarter") + ).order_by("start_datetime"), [(start_datetime, 2), (end_datetime, 2)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'month')).order_by('start_datetime'), - [(start_datetime, start_datetime.month), (end_datetime, end_datetime.month)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate( + extracted=Extract("start_datetime", "month") + ).order_by("start_datetime"), + [ + (start_datetime, start_datetime.month), + (end_datetime, end_datetime.month), + ], + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'day')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=Extract("start_datetime", "day") + ).order_by("start_datetime"), [(start_datetime, start_datetime.day), (end_datetime, end_datetime.day)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'week')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=Extract("start_datetime", "week") + ).order_by("start_datetime"), [(start_datetime, 25), (end_datetime, 24)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'week_day')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=Extract("start_datetime", "week_day") + ).order_by("start_datetime"), [ (start_datetime, (start_datetime.isoweekday() % 7) + 1), - (end_datetime, (end_datetime.isoweekday() % 7) + 1) + (end_datetime, (end_datetime.isoweekday() % 7) + 1), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( DTModel.objects.annotate( - extracted=Extract('start_datetime', 'iso_week_day'), - ).order_by('start_datetime'), + extracted=Extract("start_datetime", "iso_week_day"), + ).order_by("start_datetime"), [ (start_datetime, start_datetime.isoweekday()), (end_datetime, end_datetime.isoweekday()), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'hour')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=Extract("start_datetime", "hour") + ).order_by("start_datetime"), [(start_datetime, start_datetime.hour), (end_datetime, end_datetime.hour)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'minute')).order_by('start_datetime'), - [(start_datetime, start_datetime.minute), (end_datetime, end_datetime.minute)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate( + extracted=Extract("start_datetime", "minute") + ).order_by("start_datetime"), + [ + (start_datetime, start_datetime.minute), + (end_datetime, end_datetime.minute), + ], + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('start_datetime', 'second')).order_by('start_datetime'), - [(start_datetime, start_datetime.second), (end_datetime, end_datetime.second)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate( + extracted=Extract("start_datetime", "second") + ).order_by("start_datetime"), + [ + (start_datetime, start_datetime.second), + (end_datetime, end_datetime.second), + ], + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__year=Extract("start_datetime", "year") + ).count(), + 2, + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__hour=Extract("start_datetime", "hour") + ).count(), + 2, + ) + self.assertEqual( + DTModel.objects.filter( + start_date__month=Extract("start_date", "month") + ).count(), + 2, + ) + self.assertEqual( + DTModel.objects.filter( + start_time__hour=Extract("start_time", "hour") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__year=Extract('start_datetime', 'year')).count(), 2) - self.assertEqual(DTModel.objects.filter(start_datetime__hour=Extract('start_datetime', 'hour')).count(), 2) - self.assertEqual(DTModel.objects.filter(start_date__month=Extract('start_date', 'month')).count(), 2) - self.assertEqual(DTModel.objects.filter(start_time__hour=Extract('start_time', 'hour')).count(), 2) def test_extract_none(self): self.create_model(None, None) - for t in (Extract('start_datetime', 'year'), Extract('start_date', 'year'), Extract('start_time', 'hour')): + for t in ( + Extract("start_datetime", "year"), + Extract("start_date", "year"), + Extract("start_time", "hour"), + ): with self.subTest(t): - self.assertIsNone(DTModel.objects.annotate(extracted=t).first().extracted) + self.assertIsNone( + DTModel.objects.annotate(extracted=t).first().extracted + ) def test_extract_outerref_validation(self): - inner_qs = DTModel.objects.filter(name=ExtractMonth(OuterRef('name'))) + inner_qs = DTModel.objects.filter(name=ExtractMonth(OuterRef("name"))) msg = ( - 'Extract input expression must be DateField, DateTimeField, ' - 'TimeField, or DurationField.' + "Extract input expression must be DateField, DateTimeField, " + "TimeField, or DurationField." ) with self.assertRaisesMessage(ValueError, msg): - DTModel.objects.annotate(related_name=Subquery(inner_qs.values('name')[:1])) + DTModel.objects.annotate(related_name=Subquery(inner_qs.values("name")[:1])) - @skipUnlessDBFeature('has_native_duration_field') + @skipUnlessDBFeature("has_native_duration_field") def test_extract_duration(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123) @@ -295,35 +398,44 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=Extract('duration', 'second')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=Extract("duration", "second")).order_by( + "start_datetime" + ), [ (start_datetime, (end_datetime - start_datetime).seconds % 60), - (end_datetime, (start_datetime - end_datetime).seconds % 60) + (end_datetime, (start_datetime - end_datetime).seconds % 60), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertEqual( DTModel.objects.annotate( - duration_days=Extract('duration', 'day'), - ).filter(duration_days__gt=200).count(), - 1 + duration_days=Extract("duration", "day"), + ) + .filter(duration_days__gt=200) + .count(), + 1, ) - @skipIfDBFeature('has_native_duration_field') + @skipIfDBFeature("has_native_duration_field") def test_extract_duration_without_native_duration_field(self): - msg = 'Extract requires native DurationField database support.' + msg = "Extract requires native DurationField database support." with self.assertRaisesMessage(ValueError, msg): - list(DTModel.objects.annotate(extracted=Extract('duration', 'second'))) + list(DTModel.objects.annotate(extracted=Extract("duration", "second"))) def test_extract_duration_unsupported_lookups(self): msg = "Cannot extract component '%s' from DurationField 'duration'." for lookup in ( - 'year', 'iso_year', 'month', 'week', 'week_day', 'iso_week_day', - 'quarter', + "year", + "iso_year", + "month", + "week", + "week_day", + "iso_week_day", + "quarter", ): with self.subTest(lookup): with self.assertRaisesMessage(ValueError, msg % lookup): - DTModel.objects.annotate(extracted=Extract('duration', lookup)) + DTModel.objects.annotate(extracted=Extract("duration", lookup)) def test_extract_year_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -334,16 +446,25 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractYear('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractYear("start_datetime")).order_by( + "start_datetime" + ), [(start_datetime, start_datetime.year), (end_datetime, end_datetime.year)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractYear('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractYear("start_date")).order_by( + "start_datetime" + ), [(start_datetime, start_datetime.year), (end_datetime, end_datetime.year)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__year=ExtractYear("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__year=ExtractYear('start_datetime')).count(), 2) def test_extract_iso_year_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -354,17 +475,26 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractIsoYear('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=ExtractIsoYear("start_datetime") + ).order_by("start_datetime"), [(start_datetime, start_datetime.year), (end_datetime, end_datetime.year)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractIsoYear('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractIsoYear("start_date")).order_by( + "start_datetime" + ), [(start_datetime, start_datetime.year), (end_datetime, end_datetime.year)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) # Both dates are from the same week year. - self.assertEqual(DTModel.objects.filter(start_datetime__iso_year=ExtractIsoYear('start_datetime')).count(), 2) + self.assertEqual( + DTModel.objects.filter( + start_datetime__iso_year=ExtractIsoYear("start_datetime") + ).count(), + 2, + ) def test_extract_iso_year_func_boundaries(self): end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123) @@ -381,26 +511,34 @@ class DateFunctionTests(TestCase): obj_1_iso_2014 = self.create_model(week_52_day_2014, end_datetime) obj_1_iso_2015 = self.create_model(week_1_day_2014_2015, end_datetime) obj_2_iso_2015 = self.create_model(week_53_day_2015, end_datetime) - qs = DTModel.objects.filter(start_datetime__in=days).annotate( - extracted=ExtractIsoYear('start_datetime'), - ).order_by('start_datetime') - self.assertQuerysetEqual(qs, [ - (week_52_day_2014, 2014), - (week_1_day_2014_2015, 2015), - (week_53_day_2015, 2015), - ], lambda m: (m.start_datetime, m.extracted)) + qs = ( + DTModel.objects.filter(start_datetime__in=days) + .annotate( + extracted=ExtractIsoYear("start_datetime"), + ) + .order_by("start_datetime") + ) + self.assertQuerysetEqual( + qs, + [ + (week_52_day_2014, 2014), + (week_1_day_2014_2015, 2015), + (week_53_day_2015, 2015), + ], + lambda m: (m.start_datetime, m.extracted), + ) qs = DTModel.objects.filter( start_datetime__iso_year=2015, - ).order_by('start_datetime') + ).order_by("start_datetime") self.assertSequenceEqual(qs, [obj_1_iso_2015, obj_2_iso_2015]) qs = DTModel.objects.filter( start_datetime__iso_year__gt=2014, - ).order_by('start_datetime') + ).order_by("start_datetime") self.assertSequenceEqual(qs, [obj_1_iso_2015, obj_2_iso_2015]) qs = DTModel.objects.filter( start_datetime__iso_year__lte=2014, - ).order_by('start_datetime') + ).order_by("start_datetime") self.assertSequenceEqual(qs, [obj_1_iso_2014]) def test_extract_month_func(self): @@ -412,16 +550,31 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractMonth('start_datetime')).order_by('start_datetime'), - [(start_datetime, start_datetime.month), (end_datetime, end_datetime.month)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate(extracted=ExtractMonth("start_datetime")).order_by( + "start_datetime" + ), + [ + (start_datetime, start_datetime.month), + (end_datetime, end_datetime.month), + ], + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractMonth('start_date')).order_by('start_datetime'), - [(start_datetime, start_datetime.month), (end_datetime, end_datetime.month)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate(extracted=ExtractMonth("start_date")).order_by( + "start_datetime" + ), + [ + (start_datetime, start_datetime.month), + (end_datetime, end_datetime.month), + ], + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__month=ExtractMonth("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__month=ExtractMonth('start_datetime')).count(), 2) def test_extract_day_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -432,16 +585,25 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractDay('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractDay("start_datetime")).order_by( + "start_datetime" + ), [(start_datetime, start_datetime.day), (end_datetime, end_datetime.day)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractDay('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractDay("start_date")).order_by( + "start_datetime" + ), [(start_datetime, start_datetime.day), (end_datetime, end_datetime.day)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__day=ExtractDay("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__day=ExtractDay('start_datetime')).count(), 2) def test_extract_week_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -452,17 +614,26 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractWeek('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractWeek("start_datetime")).order_by( + "start_datetime" + ), [(start_datetime, 25), (end_datetime, 24)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractWeek('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractWeek("start_date")).order_by( + "start_datetime" + ), [(start_datetime, 25), (end_datetime, 24)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) # both dates are from the same week. - self.assertEqual(DTModel.objects.filter(start_datetime__week=ExtractWeek('start_datetime')).count(), 2) + self.assertEqual( + DTModel.objects.filter( + start_datetime__week=ExtractWeek("start_datetime") + ).count(), + 2, + ) def test_extract_quarter_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -473,16 +644,25 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractQuarter('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=ExtractQuarter("start_datetime") + ).order_by("start_datetime"), [(start_datetime, 2), (end_datetime, 3)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractQuarter('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractQuarter("start_date")).order_by( + "start_datetime" + ), [(start_datetime, 2), (end_datetime, 3)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__quarter=ExtractQuarter("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__quarter=ExtractQuarter('start_datetime')).count(), 2) def test_extract_quarter_func_boundaries(self): end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123) @@ -497,13 +677,21 @@ class DateFunctionTests(TestCase): dates = [last_quarter_2014, first_quarter_2015] self.create_model(last_quarter_2014, end_datetime) self.create_model(first_quarter_2015, end_datetime) - qs = DTModel.objects.filter(start_datetime__in=dates).annotate( - extracted=ExtractQuarter('start_datetime'), - ).order_by('start_datetime') - self.assertQuerysetEqual(qs, [ - (last_quarter_2014, 4), - (first_quarter_2015, 1), - ], lambda m: (m.start_datetime, m.extracted)) + qs = ( + DTModel.objects.filter(start_datetime__in=dates) + .annotate( + extracted=ExtractQuarter("start_datetime"), + ) + .order_by("start_datetime") + ) + self.assertQuerysetEqual( + qs, + [ + (last_quarter_2014, 4), + (first_quarter_2015, 1), + ], + lambda m: (m.start_datetime, m.extracted), + ) def test_extract_week_func_boundaries(self): end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123) @@ -522,14 +710,22 @@ class DateFunctionTests(TestCase): self.create_model(week_53_day_2015, end_datetime) self.create_model(week_52_day_2014, end_datetime) self.create_model(week_1_day_2014_2015, end_datetime) - qs = DTModel.objects.filter(start_datetime__in=days).annotate( - extracted=ExtractWeek('start_datetime'), - ).order_by('start_datetime') - self.assertQuerysetEqual(qs, [ - (week_52_day_2014, 52), - (week_1_day_2014_2015, 1), - (week_53_day_2015, 53), - ], lambda m: (m.start_datetime, m.extracted)) + qs = ( + DTModel.objects.filter(start_datetime__in=days) + .annotate( + extracted=ExtractWeek("start_datetime"), + ) + .order_by("start_datetime") + ) + self.assertQuerysetEqual( + qs, + [ + (week_52_day_2014, 52), + (week_1_day_2014_2015, 1), + (week_53_day_2015, 53), + ], + lambda m: (m.start_datetime, m.extracted), + ) def test_extract_weekday_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -540,22 +736,31 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractWeekDay('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate( + extracted=ExtractWeekDay("start_datetime") + ).order_by("start_datetime"), [ (start_datetime, (start_datetime.isoweekday() % 7) + 1), (end_datetime, (end_datetime.isoweekday() % 7) + 1), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractWeekDay('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractWeekDay("start_date")).order_by( + "start_datetime" + ), [ (start_datetime, (start_datetime.isoweekday() % 7) + 1), (end_datetime, (end_datetime.isoweekday() % 7) + 1), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__week_day=ExtractWeekDay("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__week_day=ExtractWeekDay('start_datetime')).count(), 2) def test_extract_iso_weekday_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -567,27 +772,27 @@ class DateFunctionTests(TestCase): self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( DTModel.objects.annotate( - extracted=ExtractIsoWeekDay('start_datetime'), - ).order_by('start_datetime'), + extracted=ExtractIsoWeekDay("start_datetime"), + ).order_by("start_datetime"), [ (start_datetime, start_datetime.isoweekday()), (end_datetime, end_datetime.isoweekday()), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( DTModel.objects.annotate( - extracted=ExtractIsoWeekDay('start_date'), - ).order_by('start_datetime'), + extracted=ExtractIsoWeekDay("start_date"), + ).order_by("start_datetime"), [ (start_datetime, start_datetime.isoweekday()), (end_datetime, end_datetime.isoweekday()), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertEqual( DTModel.objects.filter( - start_datetime__week_day=ExtractWeekDay('start_datetime'), + start_datetime__week_day=ExtractWeekDay("start_datetime"), ).count(), 2, ) @@ -601,16 +806,25 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractHour('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractHour("start_datetime")).order_by( + "start_datetime" + ), [(start_datetime, start_datetime.hour), (end_datetime, end_datetime.hour)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractHour('start_time')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=ExtractHour("start_time")).order_by( + "start_datetime" + ), [(start_datetime, start_datetime.hour), (end_datetime, end_datetime.hour)], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__hour=ExtractHour("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__hour=ExtractHour('start_datetime')).count(), 2) def test_extract_minute_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -621,16 +835,31 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractMinute('start_datetime')).order_by('start_datetime'), - [(start_datetime, start_datetime.minute), (end_datetime, end_datetime.minute)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate( + extracted=ExtractMinute("start_datetime") + ).order_by("start_datetime"), + [ + (start_datetime, start_datetime.minute), + (end_datetime, end_datetime.minute), + ], + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractMinute('start_time')).order_by('start_datetime'), - [(start_datetime, start_datetime.minute), (end_datetime, end_datetime.minute)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate(extracted=ExtractMinute("start_time")).order_by( + "start_datetime" + ), + [ + (start_datetime, start_datetime.minute), + (end_datetime, end_datetime.minute), + ], + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__minute=ExtractMinute("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__minute=ExtractMinute('start_datetime')).count(), 2) def test_extract_second_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -641,16 +870,31 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractSecond('start_datetime')).order_by('start_datetime'), - [(start_datetime, start_datetime.second), (end_datetime, end_datetime.second)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate( + extracted=ExtractSecond("start_datetime") + ).order_by("start_datetime"), + [ + (start_datetime, start_datetime.second), + (end_datetime, end_datetime.second), + ], + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=ExtractSecond('start_time')).order_by('start_datetime'), - [(start_datetime, start_datetime.second), (end_datetime, end_datetime.second)], - lambda m: (m.start_datetime, m.extracted) + DTModel.objects.annotate(extracted=ExtractSecond("start_time")).order_by( + "start_datetime" + ), + [ + (start_datetime, start_datetime.second), + (end_datetime, end_datetime.second), + ], + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__second=ExtractSecond("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__second=ExtractSecond('start_datetime')).count(), 2) def test_trunc_func(self): start_datetime = datetime(999, 6, 15, 14, 30, 50, 321) @@ -664,44 +908,46 @@ class DateFunctionTests(TestCase): def test_datetime_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( - truncated=Trunc('start_datetime', kind, output_field=DateTimeField()) - ).order_by('start_datetime'), + truncated=Trunc( + "start_datetime", kind, output_field=DateTimeField() + ) + ).order_by("start_datetime"), [ (start_datetime, truncate_to(start_datetime, kind)), - (end_datetime, truncate_to(end_datetime, kind)) + (end_datetime, truncate_to(end_datetime, kind)), ], - lambda m: (m.start_datetime, m.truncated) + lambda m: (m.start_datetime, m.truncated), ) def test_date_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( - truncated=Trunc('start_date', kind, output_field=DateField()) - ).order_by('start_datetime'), + truncated=Trunc("start_date", kind, output_field=DateField()) + ).order_by("start_datetime"), [ (start_datetime, truncate_to(start_datetime.date(), kind)), - (end_datetime, truncate_to(end_datetime.date(), kind)) + (end_datetime, truncate_to(end_datetime.date(), kind)), ], - lambda m: (m.start_datetime, m.truncated) + lambda m: (m.start_datetime, m.truncated), ) def test_time_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( - truncated=Trunc('start_time', kind, output_field=TimeField()) - ).order_by('start_datetime'), + truncated=Trunc("start_time", kind, output_field=TimeField()) + ).order_by("start_datetime"), [ (start_datetime, truncate_to(start_datetime.time(), kind)), - (end_datetime, truncate_to(end_datetime.time(), kind)) + (end_datetime, truncate_to(end_datetime.time(), kind)), ], - lambda m: (m.start_datetime, m.truncated) + lambda m: (m.start_datetime, m.truncated), ) def test_datetime_to_time_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( - truncated=Trunc('start_datetime', kind, output_field=TimeField()), - ).order_by('start_datetime'), + truncated=Trunc("start_datetime", kind, output_field=TimeField()), + ).order_by("start_datetime"), [ (start_datetime, truncate_to(start_datetime.time(), kind)), (end_datetime, truncate_to(end_datetime.time(), kind)), @@ -709,25 +955,29 @@ class DateFunctionTests(TestCase): lambda m: (m.start_datetime, m.truncated), ) - test_date_kind('year') - test_date_kind('quarter') - test_date_kind('month') - test_date_kind('day') - test_time_kind('hour') - test_time_kind('minute') - test_time_kind('second') - test_datetime_kind('year') - test_datetime_kind('quarter') - test_datetime_kind('month') - test_datetime_kind('day') - test_datetime_kind('hour') - test_datetime_kind('minute') - test_datetime_kind('second') - test_datetime_to_time_kind('hour') - test_datetime_to_time_kind('minute') - test_datetime_to_time_kind('second') - - qs = DTModel.objects.filter(start_datetime__date=Trunc('start_datetime', 'day', output_field=DateField())) + test_date_kind("year") + test_date_kind("quarter") + test_date_kind("month") + test_date_kind("day") + test_time_kind("hour") + test_time_kind("minute") + test_time_kind("second") + test_datetime_kind("year") + test_datetime_kind("quarter") + test_datetime_kind("month") + test_datetime_kind("day") + test_datetime_kind("hour") + test_datetime_kind("minute") + test_datetime_kind("second") + test_datetime_to_time_kind("hour") + test_datetime_to_time_kind("minute") + test_datetime_to_time_kind("second") + + qs = DTModel.objects.filter( + start_datetime__date=Trunc( + "start_datetime", "day", output_field=DateField() + ) + ) self.assertEqual(qs.count(), 2) def _test_trunc_week(self, start_datetime, end_datetime): @@ -739,21 +989,21 @@ class DateFunctionTests(TestCase): self.assertQuerysetEqual( DTModel.objects.annotate( - truncated=Trunc('start_datetime', 'week', output_field=DateTimeField()) - ).order_by('start_datetime'), + truncated=Trunc("start_datetime", "week", output_field=DateTimeField()) + ).order_by("start_datetime"), [ - (start_datetime, truncate_to(start_datetime, 'week')), - (end_datetime, truncate_to(end_datetime, 'week')), + (start_datetime, truncate_to(start_datetime, "week")), + (end_datetime, truncate_to(end_datetime, "week")), ], lambda m: (m.start_datetime, m.truncated), ) self.assertQuerysetEqual( DTModel.objects.annotate( - truncated=Trunc('start_date', 'week', output_field=DateField()) - ).order_by('start_datetime'), + truncated=Trunc("start_date", "week", output_field=DateField()) + ).order_by("start_datetime"), [ - (start_datetime, truncate_to(start_datetime.date(), 'week')), - (end_datetime, truncate_to(end_datetime.date(), 'week')), + (start_datetime, truncate_to(start_datetime.date(), "week")), + (end_datetime, truncate_to(end_datetime.date(), "week")), ], lambda m: (m.start_datetime, m.truncated), ) @@ -771,74 +1021,113 @@ class DateFunctionTests(TestCase): ) def test_trunc_invalid_arguments(self): - msg = 'output_field must be either DateField, TimeField, or DateTimeField' + msg = "output_field must be either DateField, TimeField, or DateTimeField" with self.assertRaisesMessage(ValueError, msg): - list(DTModel.objects.annotate( - truncated=Trunc('start_datetime', 'year', output_field=IntegerField()), - )) + list( + DTModel.objects.annotate( + truncated=Trunc( + "start_datetime", "year", output_field=IntegerField() + ), + ) + ) msg = "'name' isn't a DateField, TimeField, or DateTimeField." with self.assertRaisesMessage(TypeError, msg): - list(DTModel.objects.annotate( - truncated=Trunc('name', 'year', output_field=DateTimeField()), - )) + list( + DTModel.objects.annotate( + truncated=Trunc("name", "year", output_field=DateTimeField()), + ) + ) msg = "Cannot truncate DateField 'start_date' to DateTimeField" with self.assertRaisesMessage(ValueError, msg): - list(DTModel.objects.annotate(truncated=Trunc('start_date', 'second'))) + list(DTModel.objects.annotate(truncated=Trunc("start_date", "second"))) with self.assertRaisesMessage(ValueError, msg): - list(DTModel.objects.annotate( - truncated=Trunc('start_date', 'month', output_field=DateTimeField()), - )) + list( + DTModel.objects.annotate( + truncated=Trunc( + "start_date", "month", output_field=DateTimeField() + ), + ) + ) msg = "Cannot truncate TimeField 'start_time' to DateTimeField" with self.assertRaisesMessage(ValueError, msg): - list(DTModel.objects.annotate(truncated=Trunc('start_time', 'month'))) + list(DTModel.objects.annotate(truncated=Trunc("start_time", "month"))) with self.assertRaisesMessage(ValueError, msg): - list(DTModel.objects.annotate( - truncated=Trunc('start_time', 'second', output_field=DateTimeField()), - )) + list( + DTModel.objects.annotate( + truncated=Trunc( + "start_time", "second", output_field=DateTimeField() + ), + ) + ) def test_trunc_none(self): self.create_model(None, None) - for t in (Trunc('start_datetime', 'year'), Trunc('start_date', 'year'), Trunc('start_time', 'hour')): + for t in ( + Trunc("start_datetime", "year"), + Trunc("start_date", "year"), + Trunc("start_time", "hour"), + ): with self.subTest(t): - self.assertIsNone(DTModel.objects.annotate(truncated=t).first().truncated) + self.assertIsNone( + DTModel.objects.annotate(truncated=t).first().truncated + ) def test_trunc_year_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'year') + end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), "year") if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncYear('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncYear("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'year')), - (end_datetime, truncate_to(end_datetime, 'year')), + (start_datetime, truncate_to(start_datetime, "year")), + (end_datetime, truncate_to(end_datetime, "year")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncYear('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncYear("start_date")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime.date(), 'year')), - (end_datetime, truncate_to(end_datetime.date(), 'year')), + (start_datetime, truncate_to(start_datetime.date(), "year")), + (end_datetime, truncate_to(end_datetime.date(), "year")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter(start_datetime=TruncYear("start_datetime")).count(), + 1, ) - self.assertEqual(DTModel.objects.filter(start_datetime=TruncYear('start_datetime')).count(), 1) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncYear('start_time'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncYear("start_time"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncYear('start_time', output_field=TimeField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncYear("start_time", output_field=TimeField()) + ) + ) def test_trunc_quarter_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 10, 15, 14, 10, 50, 123), 'quarter') - last_quarter_2015 = truncate_to(datetime(2015, 12, 31, 14, 10, 50, 123), 'quarter') - first_quarter_2016 = truncate_to(datetime(2016, 1, 1, 14, 10, 50, 123), 'quarter') + end_datetime = truncate_to(datetime(2016, 10, 15, 14, 10, 50, 123), "quarter") + last_quarter_2015 = truncate_to( + datetime(2015, 12, 31, 14, 10, 50, 123), "quarter" + ) + first_quarter_2016 = truncate_to( + datetime(2016, 1, 1, 14, 10, 50, 123), "quarter" + ) if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) @@ -849,87 +1138,127 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime=last_quarter_2015, end_datetime=end_datetime) self.create_model(start_datetime=first_quarter_2016, end_datetime=end_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncQuarter('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncQuarter("start_date")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime.date(), 'quarter')), - (last_quarter_2015, truncate_to(last_quarter_2015.date(), 'quarter')), - (first_quarter_2016, truncate_to(first_quarter_2016.date(), 'quarter')), - (end_datetime, truncate_to(end_datetime.date(), 'quarter')), + (start_datetime, truncate_to(start_datetime.date(), "quarter")), + (last_quarter_2015, truncate_to(last_quarter_2015.date(), "quarter")), + (first_quarter_2016, truncate_to(first_quarter_2016.date(), "quarter")), + (end_datetime, truncate_to(end_datetime.date(), "quarter")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncQuarter('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncQuarter("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'quarter')), - (last_quarter_2015, truncate_to(last_quarter_2015, 'quarter')), - (first_quarter_2016, truncate_to(first_quarter_2016, 'quarter')), - (end_datetime, truncate_to(end_datetime, 'quarter')), + (start_datetime, truncate_to(start_datetime, "quarter")), + (last_quarter_2015, truncate_to(last_quarter_2015, "quarter")), + (first_quarter_2016, truncate_to(first_quarter_2016, "quarter")), + (end_datetime, truncate_to(end_datetime, "quarter")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncQuarter('start_time'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncQuarter("start_time"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncQuarter('start_time', output_field=TimeField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncQuarter("start_time", output_field=TimeField()) + ) + ) def test_trunc_month_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'month') + end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), "month") if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncMonth('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncMonth("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'month')), - (end_datetime, truncate_to(end_datetime, 'month')), + (start_datetime, truncate_to(start_datetime, "month")), + (end_datetime, truncate_to(end_datetime, "month")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncMonth('start_date')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncMonth("start_date")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime.date(), 'month')), - (end_datetime, truncate_to(end_datetime.date(), 'month')), + (start_datetime, truncate_to(start_datetime.date(), "month")), + (end_datetime, truncate_to(end_datetime.date(), "month")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter(start_datetime=TruncMonth("start_datetime")).count(), + 1, ) - self.assertEqual(DTModel.objects.filter(start_datetime=TruncMonth('start_datetime')).count(), 1) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncMonth('start_time'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncMonth("start_time"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncMonth('start_time', output_field=TimeField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncMonth("start_time", output_field=TimeField()) + ) + ) def test_trunc_week_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'week') + end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), "week") if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncWeek('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncWeek("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'week')), - (end_datetime, truncate_to(end_datetime, 'week')), + (start_datetime, truncate_to(start_datetime, "week")), + (end_datetime, truncate_to(end_datetime, "week")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter(start_datetime=TruncWeek("start_datetime")).count(), + 1, ) - self.assertEqual(DTModel.objects.filter(start_datetime=TruncWeek('start_datetime')).count(), 1) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncWeek('start_time'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncWeek("start_time"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncWeek('start_time', output_field=TimeField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncWeek("start_time", output_field=TimeField()) + ) + ) def test_trunc_date_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -940,24 +1269,43 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncDate('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncDate("start_datetime")).order_by( + "start_datetime" + ), [ (start_datetime, start_datetime.date()), (end_datetime, end_datetime.date()), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__date=TruncDate("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__date=TruncDate('start_datetime')).count(), 2) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateField"): - list(DTModel.objects.annotate(truncated=TruncDate('start_time'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateField" + ): + list(DTModel.objects.annotate(truncated=TruncDate("start_time"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateField"): - list(DTModel.objects.annotate(truncated=TruncDate('start_time', output_field=TimeField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateField" + ): + list( + DTModel.objects.annotate( + truncated=TruncDate("start_time", output_field=TimeField()) + ) + ) def test_trunc_date_none(self): self.create_model(None, None) - self.assertIsNone(DTModel.objects.annotate(truncated=TruncDate('start_datetime')).first().truncated) + self.assertIsNone( + DTModel.objects.annotate(truncated=TruncDate("start_datetime")) + .first() + .truncated + ) def test_trunc_time_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) @@ -968,24 +1316,43 @@ class DateFunctionTests(TestCase): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncTime('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncTime("start_datetime")).order_by( + "start_datetime" + ), [ (start_datetime, start_datetime.time()), (end_datetime, end_datetime.time()), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime__time=TruncTime("start_datetime") + ).count(), + 2, ) - self.assertEqual(DTModel.objects.filter(start_datetime__time=TruncTime('start_datetime')).count(), 2) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to TimeField"): - list(DTModel.objects.annotate(truncated=TruncTime('start_date'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to TimeField" + ): + list(DTModel.objects.annotate(truncated=TruncTime("start_date"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to TimeField"): - list(DTModel.objects.annotate(truncated=TruncTime('start_date', output_field=DateField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to TimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncTime("start_date", output_field=DateField()) + ) + ) def test_trunc_time_none(self): self.create_model(None, None) - self.assertIsNone(DTModel.objects.annotate(truncated=TruncTime('start_datetime')).first().truncated) + self.assertIsNone( + DTModel.objects.annotate(truncated=TruncTime("start_datetime")) + .first() + .truncated + ) def test_trunc_time_comparison(self): start_datetime = datetime(2015, 6, 15, 14, 30, 26) # 0 microseconds. @@ -1003,138 +1370,201 @@ class DateFunctionTests(TestCase): ) self.assertIs( DTModel.objects.annotate( - extracted_start=TruncTime('start_datetime'), - extracted_end=TruncTime('end_datetime'), - ).filter( + extracted_start=TruncTime("start_datetime"), + extracted_end=TruncTime("end_datetime"), + ) + .filter( extracted_start=start_datetime.time(), extracted_end=end_datetime.time(), - ).exists(), + ) + .exists(), True, ) def test_trunc_day_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'day') + end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), "day") if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncDay('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncDay("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'day')), - (end_datetime, truncate_to(end_datetime, 'day')), + (start_datetime, truncate_to(start_datetime, "day")), + (end_datetime, truncate_to(end_datetime, "day")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter(start_datetime=TruncDay("start_datetime")).count(), 1 ) - self.assertEqual(DTModel.objects.filter(start_datetime=TruncDay('start_datetime')).count(), 1) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncDay('start_time'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncDay("start_time"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncDay('start_time', output_field=TimeField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncDay("start_time", output_field=TimeField()) + ) + ) def test_trunc_hour_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'hour') + end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), "hour") if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncHour('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncHour("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'hour')), - (end_datetime, truncate_to(end_datetime, 'hour')), + (start_datetime, truncate_to(start_datetime, "hour")), + (end_datetime, truncate_to(end_datetime, "hour")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncHour('start_time')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncHour("start_time")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime.time(), 'hour')), - (end_datetime, truncate_to(end_datetime.time(), 'hour')), + (start_datetime, truncate_to(start_datetime.time(), "hour")), + (end_datetime, truncate_to(end_datetime.time(), "hour")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter(start_datetime=TruncHour("start_datetime")).count(), + 1, ) - self.assertEqual(DTModel.objects.filter(start_datetime=TruncHour('start_datetime')).count(), 1) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncHour('start_date'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncHour("start_date"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncHour('start_date', output_field=DateField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncHour("start_date", output_field=DateField()) + ) + ) def test_trunc_minute_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'minute') + end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), "minute") if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncMinute('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncMinute("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'minute')), - (end_datetime, truncate_to(end_datetime, 'minute')), + (start_datetime, truncate_to(start_datetime, "minute")), + (end_datetime, truncate_to(end_datetime, "minute")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncMinute('start_time')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncMinute("start_time")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime.time(), 'minute')), - (end_datetime, truncate_to(end_datetime.time(), 'minute')), + (start_datetime, truncate_to(start_datetime.time(), "minute")), + (end_datetime, truncate_to(end_datetime.time(), "minute")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime=TruncMinute("start_datetime") + ).count(), + 1, ) - self.assertEqual(DTModel.objects.filter(start_datetime=TruncMinute('start_datetime')).count(), 1) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncMinute('start_date'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncMinute("start_date"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncMinute('start_date', output_field=DateField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncMinute("start_date", output_field=DateField()) + ) + ) def test_trunc_second_func(self): start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321) - end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'second') + end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), "second") if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncSecond('start_datetime')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncSecond("start_datetime")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime, 'second')), - (end_datetime, truncate_to(end_datetime, 'second')) + (start_datetime, truncate_to(start_datetime, "second")), + (end_datetime, truncate_to(end_datetime, "second")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), ) self.assertQuerysetEqual( - DTModel.objects.annotate(extracted=TruncSecond('start_time')).order_by('start_datetime'), + DTModel.objects.annotate(extracted=TruncSecond("start_time")).order_by( + "start_datetime" + ), [ - (start_datetime, truncate_to(start_datetime.time(), 'second')), - (end_datetime, truncate_to(end_datetime.time(), 'second')) + (start_datetime, truncate_to(start_datetime.time(), "second")), + (end_datetime, truncate_to(end_datetime.time(), "second")), ], - lambda m: (m.start_datetime, m.extracted) + lambda m: (m.start_datetime, m.extracted), + ) + self.assertEqual( + DTModel.objects.filter( + start_datetime=TruncSecond("start_datetime") + ).count(), + 1, ) - self.assertEqual(DTModel.objects.filter(start_datetime=TruncSecond('start_datetime')).count(), 1) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncSecond('start_date'))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to DateTimeField" + ): + list(DTModel.objects.annotate(truncated=TruncSecond("start_date"))) - with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): - list(DTModel.objects.annotate(truncated=TruncSecond('start_date', output_field=DateField()))) + with self.assertRaisesMessage( + ValueError, "Cannot truncate DateField 'start_date' to DateTimeField" + ): + list( + DTModel.objects.annotate( + truncated=TruncSecond("start_date", output_field=DateField()) + ) + ) def test_trunc_subquery_with_parameters(self): - author_1 = Author.objects.create(name='J. R. R. Tolkien') - author_2 = Author.objects.create(name='G. R. R. Martin') + author_1 = Author.objects.create(name="J. R. R. Tolkien") + author_2 = Author.objects.create(name="G. R. R. Martin") fan_since_1 = datetime(2016, 2, 3, 15, 0, 0) fan_since_2 = datetime(2015, 2, 3, 15, 0, 0) fan_since_3 = datetime(2017, 2, 3, 15, 0, 0) @@ -1142,24 +1572,34 @@ class DateFunctionTests(TestCase): fan_since_1 = timezone.make_aware(fan_since_1) fan_since_2 = timezone.make_aware(fan_since_2) fan_since_3 = timezone.make_aware(fan_since_3) - Fan.objects.create(author=author_1, name='Tom', fan_since=fan_since_1) - Fan.objects.create(author=author_1, name='Emma', fan_since=fan_since_2) - Fan.objects.create(author=author_2, name='Isabella', fan_since=fan_since_3) - - inner = Fan.objects.filter( - author=OuterRef('pk'), - name__in=('Emma', 'Isabella', 'Tom') - ).values('author').annotate(newest_fan=Max('fan_since')).values('newest_fan') + Fan.objects.create(author=author_1, name="Tom", fan_since=fan_since_1) + Fan.objects.create(author=author_1, name="Emma", fan_since=fan_since_2) + Fan.objects.create(author=author_2, name="Isabella", fan_since=fan_since_3) + + inner = ( + Fan.objects.filter( + author=OuterRef("pk"), name__in=("Emma", "Isabella", "Tom") + ) + .values("author") + .annotate(newest_fan=Max("fan_since")) + .values("newest_fan") + ) outer = Author.objects.annotate( newest_fan_year=TruncYear(Subquery(inner, output_field=DateTimeField())) ) tz = timezone.utc if settings.USE_TZ else None self.assertSequenceEqual( - outer.order_by('name').values('name', 'newest_fan_year'), + outer.order_by("name").values("name", "newest_fan_year"), [ - {'name': 'G. R. R. Martin', 'newest_fan_year': datetime(2017, 1, 1, 0, 0, tzinfo=tz)}, - {'name': 'J. R. R. Tolkien', 'newest_fan_year': datetime(2016, 1, 1, 0, 0, tzinfo=tz)}, - ] + { + "name": "G. R. R. Martin", + "newest_fan_year": datetime(2017, 1, 1, 0, 0, tzinfo=tz), + }, + { + "name": "J. R. R. Tolkien", + "newest_fan_year": datetime(2016, 1, 1, 0, 0, tzinfo=tz), + }, + ], ) def test_extract_outerref(self): @@ -1176,21 +1616,23 @@ class DateFunctionTests(TestCase): inner_qs = DTModel.objects.filter( start_datetime__year=2000, - start_datetime__month=ExtractMonth(OuterRef('end_datetime')), + start_datetime__month=ExtractMonth(OuterRef("end_datetime")), ) qs = DTModel.objects.annotate( - related_pk=Subquery(inner_qs.values('pk')[:1]), + related_pk=Subquery(inner_qs.values("pk")[:1]), + ) + self.assertSequenceEqual( + qs.order_by("name").values("pk", "related_pk"), + [ + {"pk": obj_1.pk, "related_pk": obj_1.pk}, + {"pk": obj_2.pk, "related_pk": obj_1.pk}, + {"pk": obj_3.pk, "related_pk": None}, + ], ) - self.assertSequenceEqual(qs.order_by('name').values('pk', 'related_pk'), [ - {'pk': obj_1.pk, 'related_pk': obj_1.pk}, - {'pk': obj_2.pk, 'related_pk': obj_1.pk}, - {'pk': obj_3.pk, 'related_pk': None}, - ]) -@override_settings(USE_TZ=True, TIME_ZONE='UTC') +@override_settings(USE_TZ=True, TIME_ZONE="UTC") class DateFunctionWithTimeZoneTests(DateFunctionTests): - def get_timezones(self, key): for constructor in ZONE_CONSTRUCTORS: yield constructor(key) @@ -1204,24 +1646,30 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): delta_tzinfo_pos = datetime_timezone(timedelta(hours=5)) delta_tzinfo_neg = datetime_timezone(timedelta(hours=-5, minutes=17)) - for melb in self.get_timezones('Australia/Melbourne'): + for melb in self.get_timezones("Australia/Melbourne"): with self.subTest(repr(melb)): qs = DTModel.objects.annotate( - day=Extract('start_datetime', 'day'), - day_melb=Extract('start_datetime', 'day', tzinfo=melb), - week=Extract('start_datetime', 'week', tzinfo=melb), - isoyear=ExtractIsoYear('start_datetime', tzinfo=melb), - weekday=ExtractWeekDay('start_datetime'), - weekday_melb=ExtractWeekDay('start_datetime', tzinfo=melb), - isoweekday=ExtractIsoWeekDay('start_datetime'), - isoweekday_melb=ExtractIsoWeekDay('start_datetime', tzinfo=melb), - quarter=ExtractQuarter('start_datetime', tzinfo=melb), - hour=ExtractHour('start_datetime'), - hour_melb=ExtractHour('start_datetime', tzinfo=melb), - hour_with_delta_pos=ExtractHour('start_datetime', tzinfo=delta_tzinfo_pos), - hour_with_delta_neg=ExtractHour('start_datetime', tzinfo=delta_tzinfo_neg), - minute_with_delta_neg=ExtractMinute('start_datetime', tzinfo=delta_tzinfo_neg), - ).order_by('start_datetime') + day=Extract("start_datetime", "day"), + day_melb=Extract("start_datetime", "day", tzinfo=melb), + week=Extract("start_datetime", "week", tzinfo=melb), + isoyear=ExtractIsoYear("start_datetime", tzinfo=melb), + weekday=ExtractWeekDay("start_datetime"), + weekday_melb=ExtractWeekDay("start_datetime", tzinfo=melb), + isoweekday=ExtractIsoWeekDay("start_datetime"), + isoweekday_melb=ExtractIsoWeekDay("start_datetime", tzinfo=melb), + quarter=ExtractQuarter("start_datetime", tzinfo=melb), + hour=ExtractHour("start_datetime"), + hour_melb=ExtractHour("start_datetime", tzinfo=melb), + hour_with_delta_pos=ExtractHour( + "start_datetime", tzinfo=delta_tzinfo_pos + ), + hour_with_delta_neg=ExtractHour( + "start_datetime", tzinfo=delta_tzinfo_neg + ), + minute_with_delta_neg=ExtractMinute( + "start_datetime", tzinfo=delta_tzinfo_neg + ), + ).order_by("start_datetime") utc_model = qs.get() self.assertEqual(utc_model.day, 15) @@ -1260,12 +1708,12 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): start_datetime = timezone.make_aware(start_datetime) end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) - for ust_nera in self.get_timezones('Asia/Ust-Nera'): + for ust_nera in self.get_timezones("Asia/Ust-Nera"): with self.subTest(repr(ust_nera)): qs = DTModel.objects.annotate( - hour=ExtractHour('start_datetime'), - hour_tz=ExtractHour('start_datetime', tzinfo=ust_nera), - ).order_by('start_datetime') + hour=ExtractHour("start_datetime"), + hour_tz=ExtractHour("start_datetime", tzinfo=ust_nera), + ).order_by("start_datetime") utc_model = qs.get() self.assertEqual(utc_model.hour, 23) @@ -1284,27 +1732,33 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): end_datetime = timezone.make_aware(end_datetime) self.create_model(start_datetime, end_datetime) - for melb in self.get_timezones('Australia/Melbourne'): + for melb in self.get_timezones("Australia/Melbourne"): with self.subTest(repr(melb)): with timezone.override(melb): - model = DTModel.objects.annotate( - day_melb=Extract('start_datetime', 'day'), - day_utc=Extract('start_datetime', 'day', tzinfo=timezone.utc), - ).order_by('start_datetime').get() + model = ( + DTModel.objects.annotate( + day_melb=Extract("start_datetime", "day"), + day_utc=Extract( + "start_datetime", "day", tzinfo=timezone.utc + ), + ) + .order_by("start_datetime") + .get() + ) self.assertEqual(model.day_melb, 16) self.assertEqual(model.day_utc, 15) def test_extract_invalid_field_with_timezone(self): - for melb in self.get_timezones('Australia/Melbourne'): + for melb in self.get_timezones("Australia/Melbourne"): with self.subTest(repr(melb)): - msg = 'tzinfo can only be used with DateTimeField.' + msg = "tzinfo can only be used with DateTimeField." with self.assertRaisesMessage(ValueError, msg): DTModel.objects.annotate( - day_melb=Extract('start_date', 'day', tzinfo=melb), + day_melb=Extract("start_date", "day", tzinfo=melb), ).get() with self.assertRaisesMessage(ValueError, msg): DTModel.objects.annotate( - hour_melb=Extract('start_time', 'hour', tzinfo=melb), + hour_melb=Extract("start_time", "hour", tzinfo=melb), ).get() def test_trunc_timezone_applied_before_truncation(self): @@ -1315,23 +1769,32 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): self.create_model(start_datetime, end_datetime) for melb, pacific in zip( - self.get_timezones('Australia/Melbourne'), self.get_timezones('America/Los_Angeles') + self.get_timezones("Australia/Melbourne"), + self.get_timezones("America/Los_Angeles"), ): with self.subTest((repr(melb), repr(pacific))): - model = DTModel.objects.annotate( - melb_year=TruncYear('start_datetime', tzinfo=melb), - pacific_year=TruncYear('start_datetime', tzinfo=pacific), - melb_date=TruncDate('start_datetime', tzinfo=melb), - pacific_date=TruncDate('start_datetime', tzinfo=pacific), - melb_time=TruncTime('start_datetime', tzinfo=melb), - pacific_time=TruncTime('start_datetime', tzinfo=pacific), - ).order_by('start_datetime').get() + model = ( + DTModel.objects.annotate( + melb_year=TruncYear("start_datetime", tzinfo=melb), + pacific_year=TruncYear("start_datetime", tzinfo=pacific), + melb_date=TruncDate("start_datetime", tzinfo=melb), + pacific_date=TruncDate("start_datetime", tzinfo=pacific), + melb_time=TruncTime("start_datetime", tzinfo=melb), + pacific_time=TruncTime("start_datetime", tzinfo=pacific), + ) + .order_by("start_datetime") + .get() + ) melb_start_datetime = start_datetime.astimezone(melb) pacific_start_datetime = start_datetime.astimezone(pacific) self.assertEqual(model.start_datetime, start_datetime) - self.assertEqual(model.melb_year, truncate_to(start_datetime, 'year', melb)) - self.assertEqual(model.pacific_year, truncate_to(start_datetime, 'year', pacific)) + self.assertEqual( + model.melb_year, truncate_to(start_datetime, "year", melb) + ) + self.assertEqual( + model.pacific_year, truncate_to(start_datetime, "year", pacific) + ) self.assertEqual(model.start_datetime.year, 2016) self.assertEqual(model.melb_year.year, 2016) self.assertEqual(model.pacific_year.year, 2015) @@ -1343,25 +1806,33 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): @needs_pytz @ignore_warnings(category=RemovedInDjango50Warning) def test_trunc_ambiguous_and_invalid_times(self): - sao = pytz.timezone('America/Sao_Paulo') + sao = pytz.timezone("America/Sao_Paulo") utc = timezone.utc start_datetime = datetime(2016, 10, 16, 13, tzinfo=utc) end_datetime = datetime(2016, 2, 21, 1, tzinfo=utc) self.create_model(start_datetime, end_datetime) with timezone.override(sao): - with self.assertRaisesMessage(pytz.NonExistentTimeError, '2016-10-16 00:00:00'): - model = DTModel.objects.annotate(truncated_start=TruncDay('start_datetime')).get() - with self.assertRaisesMessage(pytz.AmbiguousTimeError, '2016-02-20 23:00:00'): - model = DTModel.objects.annotate(truncated_end=TruncHour('end_datetime')).get() + with self.assertRaisesMessage( + pytz.NonExistentTimeError, "2016-10-16 00:00:00" + ): + model = DTModel.objects.annotate( + truncated_start=TruncDay("start_datetime") + ).get() + with self.assertRaisesMessage( + pytz.AmbiguousTimeError, "2016-02-20 23:00:00" + ): + model = DTModel.objects.annotate( + truncated_end=TruncHour("end_datetime") + ).get() model = DTModel.objects.annotate( - truncated_start=TruncDay('start_datetime', is_dst=False), - truncated_end=TruncHour('end_datetime', is_dst=False), + truncated_start=TruncDay("start_datetime", is_dst=False), + truncated_end=TruncHour("end_datetime", is_dst=False), ).get() self.assertEqual(model.truncated_start.dst(), timedelta(0)) self.assertEqual(model.truncated_end.dst(), timedelta(0)) model = DTModel.objects.annotate( - truncated_start=TruncDay('start_datetime', is_dst=True), - truncated_end=TruncHour('end_datetime', is_dst=True), + truncated_start=TruncDay("start_datetime", is_dst=True), + truncated_end=TruncHour("end_datetime", is_dst=True), ).get() self.assertEqual(model.truncated_start.dst(), timedelta(0, 3600)) self.assertEqual(model.truncated_end.dst(), timedelta(0, 3600)) @@ -1378,36 +1849,50 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) - for melb in self.get_timezones('Australia/Melbourne'): + for melb in self.get_timezones("Australia/Melbourne"): with self.subTest(repr(melb)): + def test_datetime_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( truncated=Trunc( - 'start_datetime', kind, output_field=DateTimeField(), tzinfo=melb + "start_datetime", + kind, + output_field=DateTimeField(), + tzinfo=melb, ) - ).order_by('start_datetime'), + ).order_by("start_datetime"), [ - (start_datetime, truncate_to(start_datetime.astimezone(melb), kind, melb)), - (end_datetime, truncate_to(end_datetime.astimezone(melb), kind, melb)) + ( + start_datetime, + truncate_to( + start_datetime.astimezone(melb), kind, melb + ), + ), + ( + end_datetime, + truncate_to(end_datetime.astimezone(melb), kind, melb), + ), ], - lambda m: (m.start_datetime, m.truncated) + lambda m: (m.start_datetime, m.truncated), ) def test_datetime_to_date_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( truncated=Trunc( - 'start_datetime', + "start_datetime", kind, output_field=DateField(), tzinfo=melb, ), - ).order_by('start_datetime'), + ).order_by("start_datetime"), [ ( start_datetime, - truncate_to(start_datetime.astimezone(melb).date(), kind), + truncate_to( + start_datetime.astimezone(melb).date(), kind + ), ), ( end_datetime, @@ -1421,16 +1906,18 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): self.assertQuerysetEqual( DTModel.objects.annotate( truncated=Trunc( - 'start_datetime', + "start_datetime", kind, output_field=TimeField(), tzinfo=melb, ) - ).order_by('start_datetime'), + ).order_by("start_datetime"), [ ( start_datetime, - truncate_to(start_datetime.astimezone(melb).time(), kind), + truncate_to( + start_datetime.astimezone(melb).time(), kind + ), ), ( end_datetime, @@ -1440,37 +1927,39 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests): lambda m: (m.start_datetime, m.truncated), ) - test_datetime_to_date_kind('year') - test_datetime_to_date_kind('quarter') - test_datetime_to_date_kind('month') - test_datetime_to_date_kind('week') - test_datetime_to_date_kind('day') - test_datetime_to_time_kind('hour') - test_datetime_to_time_kind('minute') - test_datetime_to_time_kind('second') - test_datetime_kind('year') - test_datetime_kind('quarter') - test_datetime_kind('month') - test_datetime_kind('week') - test_datetime_kind('day') - test_datetime_kind('hour') - test_datetime_kind('minute') - test_datetime_kind('second') + test_datetime_to_date_kind("year") + test_datetime_to_date_kind("quarter") + test_datetime_to_date_kind("month") + test_datetime_to_date_kind("week") + test_datetime_to_date_kind("day") + test_datetime_to_time_kind("hour") + test_datetime_to_time_kind("minute") + test_datetime_to_time_kind("second") + test_datetime_kind("year") + test_datetime_kind("quarter") + test_datetime_kind("month") + test_datetime_kind("week") + test_datetime_kind("day") + test_datetime_kind("hour") + test_datetime_kind("minute") + test_datetime_kind("second") qs = DTModel.objects.filter( - start_datetime__date=Trunc('start_datetime', 'day', output_field=DateField()) + start_datetime__date=Trunc( + "start_datetime", "day", output_field=DateField() + ) ) self.assertEqual(qs.count(), 2) def test_trunc_invalid_field_with_timezone(self): - for melb in self.get_timezones('Australia/Melbourne'): + for melb in self.get_timezones("Australia/Melbourne"): with self.subTest(repr(melb)): - msg = 'tzinfo can only be used with DateTimeField.' + msg = "tzinfo can only be used with DateTimeField." with self.assertRaisesMessage(ValueError, msg): DTModel.objects.annotate( - day_melb=Trunc('start_date', 'day', tzinfo=melb), + day_melb=Trunc("start_date", "day", tzinfo=melb), ).get() with self.assertRaisesMessage(ValueError, msg): DTModel.objects.annotate( - hour_melb=Trunc('start_time', 'hour', tzinfo=melb), + hour_melb=Trunc("start_time", "hour", tzinfo=melb), ).get() diff --git a/tests/db_functions/datetime/test_now.py b/tests/db_functions/datetime/test_now.py index d7b43609b2..669a973be0 100644 --- a/tests/db_functions/datetime/test_now.py +++ b/tests/db_functions/datetime/test_now.py @@ -12,21 +12,24 @@ lorem_ipsum = """ class NowTests(TestCase): - def test_basic(self): a1 = Article.objects.create( - title='How to Django', + title="How to Django", text=lorem_ipsum, written=timezone.now(), ) a2 = Article.objects.create( - title='How to Time Travel', + title="How to Time Travel", text=lorem_ipsum, written=timezone.now(), ) - num_updated = Article.objects.filter(id=a1.id, published=None).update(published=Now()) + num_updated = Article.objects.filter(id=a1.id, published=None).update( + published=Now() + ) self.assertEqual(num_updated, 1) - num_updated = Article.objects.filter(id=a1.id, published=None).update(published=Now()) + num_updated = Article.objects.filter(id=a1.id, published=None).update( + published=Now() + ) self.assertEqual(num_updated, 0) a1.refresh_from_db() self.assertIsInstance(a1.published, datetime) @@ -36,11 +39,11 @@ class NowTests(TestCase): self.assertIsInstance(a2.published, datetime) self.assertQuerysetEqual( Article.objects.filter(published__lte=Now()), - ['How to Django'], - lambda a: a.title + ["How to Django"], + lambda a: a.title, ) self.assertQuerysetEqual( Article.objects.filter(published__gt=Now()), - ['How to Time Travel'], - lambda a: a.title + ["How to Time Travel"], + lambda a: a.title, ) diff --git a/tests/db_functions/math/test_abs.py b/tests/db_functions/math/test_abs.py index a9e0175e84..e56b13f2a2 100644 --- a/tests/db_functions/math/test_abs.py +++ b/tests/db_functions/math/test_abs.py @@ -9,15 +9,14 @@ from ..models import DecimalModel, FloatModel, IntegerModel class AbsTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_abs=Abs('normal')).first() + obj = IntegerModel.objects.annotate(null_abs=Abs("normal")).first() self.assertIsNone(obj.null_abs) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-0.8'), n2=Decimal('1.2')) - obj = DecimalModel.objects.annotate(n1_abs=Abs('n1'), n2_abs=Abs('n2')).first() + DecimalModel.objects.create(n1=Decimal("-0.8"), n2=Decimal("1.2")) + obj = DecimalModel.objects.annotate(n1_abs=Abs("n1"), n2_abs=Abs("n2")).first() self.assertIsInstance(obj.n1_abs, Decimal) self.assertIsInstance(obj.n2_abs, Decimal) self.assertEqual(obj.n1, -obj.n1_abs) @@ -25,7 +24,7 @@ class AbsTests(TestCase): def test_float(self): obj = FloatModel.objects.create(f1=-0.5, f2=12) - obj = FloatModel.objects.annotate(f1_abs=Abs('f1'), f2_abs=Abs('f2')).first() + obj = FloatModel.objects.annotate(f1_abs=Abs("f1"), f2_abs=Abs("f2")).first() self.assertIsInstance(obj.f1_abs, float) self.assertIsInstance(obj.f2_abs, float) self.assertEqual(obj.f1, -obj.f1_abs) @@ -34,9 +33,9 @@ class AbsTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=12, normal=0, big=-45) obj = IntegerModel.objects.annotate( - small_abs=Abs('small'), - normal_abs=Abs('normal'), - big_abs=Abs('big'), + small_abs=Abs("small"), + normal_abs=Abs("normal"), + big_abs=Abs("big"), ).first() self.assertIsInstance(obj.small_abs, int) self.assertIsInstance(obj.normal_abs, int) @@ -47,7 +46,7 @@ class AbsTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Abs): - DecimalModel.objects.create(n1=Decimal('-1.5'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-0.5'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("-1.5"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-0.5"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__abs__gt=1).get() - self.assertEqual(obj.n1, Decimal('-1.5')) + self.assertEqual(obj.n1, Decimal("-1.5")) diff --git a/tests/db_functions/math/test_acos.py b/tests/db_functions/math/test_acos.py index b5cac88eea..fe77866320 100644 --- a/tests/db_functions/math/test_acos.py +++ b/tests/db_functions/math/test_acos.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class ACosTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_acos=ACos('normal')).first() + obj = IntegerModel.objects.annotate(null_acos=ACos("normal")).first() self.assertIsNone(obj.null_acos) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-0.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_acos=ACos('n1'), n2_acos=ACos('n2')).first() + DecimalModel.objects.create(n1=Decimal("-0.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_acos=ACos("n1"), n2_acos=ACos("n2") + ).first() self.assertIsInstance(obj.n1_acos, Decimal) self.assertIsInstance(obj.n2_acos, Decimal) self.assertAlmostEqual(obj.n1_acos, Decimal(math.acos(obj.n1))) @@ -26,7 +27,9 @@ class ACosTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-0.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_acos=ACos('f1'), f2_acos=ACos('f2')).first() + obj = FloatModel.objects.annotate( + f1_acos=ACos("f1"), f2_acos=ACos("f2") + ).first() self.assertIsInstance(obj.f1_acos, float) self.assertIsInstance(obj.f2_acos, float) self.assertAlmostEqual(obj.f1_acos, math.acos(obj.f1)) @@ -35,9 +38,9 @@ class ACosTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=0, normal=1, big=-1) obj = IntegerModel.objects.annotate( - small_acos=ACos('small'), - normal_acos=ACos('normal'), - big_acos=ACos('big'), + small_acos=ACos("small"), + normal_acos=ACos("normal"), + big_acos=ACos("big"), ).first() self.assertIsInstance(obj.small_acos, float) self.assertIsInstance(obj.normal_acos, float) @@ -48,7 +51,7 @@ class ACosTests(TestCase): def test_transform(self): with register_lookup(DecimalField, ACos): - DecimalModel.objects.create(n1=Decimal('0.5'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-0.9'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("0.5"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-0.9"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__acos__lt=2).get() - self.assertEqual(obj.n1, Decimal('0.5')) + self.assertEqual(obj.n1, Decimal("0.5")) diff --git a/tests/db_functions/math/test_asin.py b/tests/db_functions/math/test_asin.py index ddbadb12a6..8a2e78ed43 100644 --- a/tests/db_functions/math/test_asin.py +++ b/tests/db_functions/math/test_asin.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class ASinTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_asin=ASin('normal')).first() + obj = IntegerModel.objects.annotate(null_asin=ASin("normal")).first() self.assertIsNone(obj.null_asin) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('0.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_asin=ASin('n1'), n2_asin=ASin('n2')).first() + DecimalModel.objects.create(n1=Decimal("0.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_asin=ASin("n1"), n2_asin=ASin("n2") + ).first() self.assertIsInstance(obj.n1_asin, Decimal) self.assertIsInstance(obj.n2_asin, Decimal) self.assertAlmostEqual(obj.n1_asin, Decimal(math.asin(obj.n1))) @@ -26,7 +27,9 @@ class ASinTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-0.5, f2=0.87) - obj = FloatModel.objects.annotate(f1_asin=ASin('f1'), f2_asin=ASin('f2')).first() + obj = FloatModel.objects.annotate( + f1_asin=ASin("f1"), f2_asin=ASin("f2") + ).first() self.assertIsInstance(obj.f1_asin, float) self.assertIsInstance(obj.f2_asin, float) self.assertAlmostEqual(obj.f1_asin, math.asin(obj.f1)) @@ -35,9 +38,9 @@ class ASinTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=0, normal=1, big=-1) obj = IntegerModel.objects.annotate( - small_asin=ASin('small'), - normal_asin=ASin('normal'), - big_asin=ASin('big'), + small_asin=ASin("small"), + normal_asin=ASin("normal"), + big_asin=ASin("big"), ).first() self.assertIsInstance(obj.small_asin, float) self.assertIsInstance(obj.normal_asin, float) @@ -48,7 +51,7 @@ class ASinTests(TestCase): def test_transform(self): with register_lookup(DecimalField, ASin): - DecimalModel.objects.create(n1=Decimal('0.1'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('1.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("0.1"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("1.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__asin__gt=1).get() - self.assertEqual(obj.n1, Decimal('1.0')) + self.assertEqual(obj.n1, Decimal("1.0")) diff --git a/tests/db_functions/math/test_atan.py b/tests/db_functions/math/test_atan.py index a14e7de581..32e73e235a 100644 --- a/tests/db_functions/math/test_atan.py +++ b/tests/db_functions/math/test_atan.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class ATanTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_atan=ATan('normal')).first() + obj = IntegerModel.objects.annotate(null_atan=ATan("normal")).first() self.assertIsNone(obj.null_atan) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_atan=ATan('n1'), n2_atan=ATan('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_atan=ATan("n1"), n2_atan=ATan("n2") + ).first() self.assertIsInstance(obj.n1_atan, Decimal) self.assertIsInstance(obj.n2_atan, Decimal) self.assertAlmostEqual(obj.n1_atan, Decimal(math.atan(obj.n1))) @@ -26,7 +27,9 @@ class ATanTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_atan=ATan('f1'), f2_atan=ATan('f2')).first() + obj = FloatModel.objects.annotate( + f1_atan=ATan("f1"), f2_atan=ATan("f2") + ).first() self.assertIsInstance(obj.f1_atan, float) self.assertIsInstance(obj.f2_atan, float) self.assertAlmostEqual(obj.f1_atan, math.atan(obj.f1)) @@ -35,9 +38,9 @@ class ATanTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_atan=ATan('small'), - normal_atan=ATan('normal'), - big_atan=ATan('big'), + small_atan=ATan("small"), + normal_atan=ATan("normal"), + big_atan=ATan("big"), ).first() self.assertIsInstance(obj.small_atan, float) self.assertIsInstance(obj.normal_atan, float) @@ -48,7 +51,7 @@ class ATanTests(TestCase): def test_transform(self): with register_lookup(DecimalField, ATan): - DecimalModel.objects.create(n1=Decimal('3.12'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-5'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("3.12"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-5"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__atan__gt=0).get() - self.assertEqual(obj.n1, Decimal('3.12')) + self.assertEqual(obj.n1, Decimal("3.12")) diff --git a/tests/db_functions/math/test_atan2.py b/tests/db_functions/math/test_atan2.py index ce9dd53187..59779e52b7 100644 --- a/tests/db_functions/math/test_atan2.py +++ b/tests/db_functions/math/test_atan2.py @@ -8,35 +8,34 @@ from ..models import DecimalModel, FloatModel, IntegerModel class ATan2Tests(TestCase): - def test_null(self): IntegerModel.objects.create(big=100) obj = IntegerModel.objects.annotate( - null_atan2_sn=ATan2('small', 'normal'), - null_atan2_nb=ATan2('normal', 'big'), - null_atan2_bn=ATan2('big', 'normal'), + null_atan2_sn=ATan2("small", "normal"), + null_atan2_nb=ATan2("normal", "big"), + null_atan2_bn=ATan2("big", "normal"), ).first() self.assertIsNone(obj.null_atan2_sn) self.assertIsNone(obj.null_atan2_nb) self.assertIsNone(obj.null_atan2_bn) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-9.9'), n2=Decimal('4.6')) - obj = DecimalModel.objects.annotate(n_atan2=ATan2('n1', 'n2')).first() + DecimalModel.objects.create(n1=Decimal("-9.9"), n2=Decimal("4.6")) + obj = DecimalModel.objects.annotate(n_atan2=ATan2("n1", "n2")).first() self.assertIsInstance(obj.n_atan2, Decimal) self.assertAlmostEqual(obj.n_atan2, Decimal(math.atan2(obj.n1, obj.n2))) def test_float(self): FloatModel.objects.create(f1=-25, f2=0.33) - obj = FloatModel.objects.annotate(f_atan2=ATan2('f1', 'f2')).first() + obj = FloatModel.objects.annotate(f_atan2=ATan2("f1", "f2")).first() self.assertIsInstance(obj.f_atan2, float) self.assertAlmostEqual(obj.f_atan2, math.atan2(obj.f1, obj.f2)) def test_integer(self): IntegerModel.objects.create(small=0, normal=1, big=10) obj = IntegerModel.objects.annotate( - atan2_sn=ATan2('small', 'normal'), - atan2_nb=ATan2('normal', 'big'), + atan2_sn=ATan2("small", "normal"), + atan2_nb=ATan2("normal", "big"), ).first() self.assertIsInstance(obj.atan2_sn, float) self.assertIsInstance(obj.atan2_nb, float) diff --git a/tests/db_functions/math/test_ceil.py b/tests/db_functions/math/test_ceil.py index 86fe084185..23c3bcd84a 100644 --- a/tests/db_functions/math/test_ceil.py +++ b/tests/db_functions/math/test_ceil.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class CeilTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_ceil=Ceil('normal')).first() + obj = IntegerModel.objects.annotate(null_ceil=Ceil("normal")).first() self.assertIsNone(obj.null_ceil) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_ceil=Ceil('n1'), n2_ceil=Ceil('n2')).first() + DecimalModel.objects.create(n1=Decimal("12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_ceil=Ceil("n1"), n2_ceil=Ceil("n2") + ).first() self.assertIsInstance(obj.n1_ceil, Decimal) self.assertIsInstance(obj.n2_ceil, Decimal) self.assertEqual(obj.n1_ceil, Decimal(math.ceil(obj.n1))) @@ -26,7 +27,9 @@ class CeilTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-12.5, f2=21.33) - obj = FloatModel.objects.annotate(f1_ceil=Ceil('f1'), f2_ceil=Ceil('f2')).first() + obj = FloatModel.objects.annotate( + f1_ceil=Ceil("f1"), f2_ceil=Ceil("f2") + ).first() self.assertIsInstance(obj.f1_ceil, float) self.assertIsInstance(obj.f2_ceil, float) self.assertEqual(obj.f1_ceil, math.ceil(obj.f1)) @@ -35,9 +38,9 @@ class CeilTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-11, normal=0, big=-100) obj = IntegerModel.objects.annotate( - small_ceil=Ceil('small'), - normal_ceil=Ceil('normal'), - big_ceil=Ceil('big'), + small_ceil=Ceil("small"), + normal_ceil=Ceil("normal"), + big_ceil=Ceil("big"), ).first() self.assertIsInstance(obj.small_ceil, int) self.assertIsInstance(obj.normal_ceil, int) @@ -48,7 +51,7 @@ class CeilTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Ceil): - DecimalModel.objects.create(n1=Decimal('3.12'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('1.25'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("3.12"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("1.25"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__ceil__gt=3).get() - self.assertEqual(obj.n1, Decimal('3.12')) + self.assertEqual(obj.n1, Decimal("3.12")) diff --git a/tests/db_functions/math/test_cos.py b/tests/db_functions/math/test_cos.py index 73e59f0463..9e96589bac 100644 --- a/tests/db_functions/math/test_cos.py +++ b/tests/db_functions/math/test_cos.py @@ -10,15 +10,14 @@ from ..models import DecimalModel, FloatModel, IntegerModel class CosTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_cos=Cos('normal')).first() + obj = IntegerModel.objects.annotate(null_cos=Cos("normal")).first() self.assertIsNone(obj.null_cos) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_cos=Cos('n1'), n2_cos=Cos('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate(n1_cos=Cos("n1"), n2_cos=Cos("n2")).first() self.assertIsInstance(obj.n1_cos, Decimal) self.assertIsInstance(obj.n2_cos, Decimal) self.assertAlmostEqual(obj.n1_cos, Decimal(math.cos(obj.n1))) @@ -26,7 +25,7 @@ class CosTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_cos=Cos('f1'), f2_cos=Cos('f2')).first() + obj = FloatModel.objects.annotate(f1_cos=Cos("f1"), f2_cos=Cos("f2")).first() self.assertIsInstance(obj.f1_cos, float) self.assertIsInstance(obj.f2_cos, float) self.assertAlmostEqual(obj.f1_cos, math.cos(obj.f1)) @@ -35,9 +34,9 @@ class CosTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_cos=Cos('small'), - normal_cos=Cos('normal'), - big_cos=Cos('big'), + small_cos=Cos("small"), + normal_cos=Cos("normal"), + big_cos=Cos("big"), ).first() self.assertIsInstance(obj.small_cos, float) self.assertIsInstance(obj.normal_cos, float) @@ -48,7 +47,7 @@ class CosTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Cos): - DecimalModel.objects.create(n1=Decimal('-8.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('3.14'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("-8.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("3.14"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__cos__gt=-0.2).get() - self.assertEqual(obj.n1, Decimal('-8.0')) + self.assertEqual(obj.n1, Decimal("-8.0")) diff --git a/tests/db_functions/math/test_cot.py b/tests/db_functions/math/test_cot.py index d876648598..04fdcb475c 100644 --- a/tests/db_functions/math/test_cot.py +++ b/tests/db_functions/math/test_cot.py @@ -10,15 +10,14 @@ from ..models import DecimalModel, FloatModel, IntegerModel class CotTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_cot=Cot('normal')).first() + obj = IntegerModel.objects.annotate(null_cot=Cot("normal")).first() self.assertIsNone(obj.null_cot) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_cot=Cot('n1'), n2_cot=Cot('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate(n1_cot=Cot("n1"), n2_cot=Cot("n2")).first() self.assertIsInstance(obj.n1_cot, Decimal) self.assertIsInstance(obj.n2_cot, Decimal) self.assertAlmostEqual(obj.n1_cot, Decimal(1 / math.tan(obj.n1))) @@ -26,7 +25,7 @@ class CotTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_cot=Cot('f1'), f2_cot=Cot('f2')).first() + obj = FloatModel.objects.annotate(f1_cot=Cot("f1"), f2_cot=Cot("f2")).first() self.assertIsInstance(obj.f1_cot, float) self.assertIsInstance(obj.f2_cot, float) self.assertAlmostEqual(obj.f1_cot, 1 / math.tan(obj.f1)) @@ -35,9 +34,9 @@ class CotTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-5, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_cot=Cot('small'), - normal_cot=Cot('normal'), - big_cot=Cot('big'), + small_cot=Cot("small"), + normal_cot=Cot("normal"), + big_cot=Cot("big"), ).first() self.assertIsInstance(obj.small_cot, float) self.assertIsInstance(obj.normal_cot, float) @@ -48,7 +47,7 @@ class CotTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Cot): - DecimalModel.objects.create(n1=Decimal('12.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('1.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("12.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("1.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__cot__gt=0).get() - self.assertEqual(obj.n1, Decimal('1.0')) + self.assertEqual(obj.n1, Decimal("1.0")) diff --git a/tests/db_functions/math/test_degrees.py b/tests/db_functions/math/test_degrees.py index ab687b8da2..06a5ac7d88 100644 --- a/tests/db_functions/math/test_degrees.py +++ b/tests/db_functions/math/test_degrees.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class DegreesTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_degrees=Degrees('normal')).first() + obj = IntegerModel.objects.annotate(null_degrees=Degrees("normal")).first() self.assertIsNone(obj.null_degrees) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_degrees=Degrees('n1'), n2_degrees=Degrees('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_degrees=Degrees("n1"), n2_degrees=Degrees("n2") + ).first() self.assertIsInstance(obj.n1_degrees, Decimal) self.assertIsInstance(obj.n2_degrees, Decimal) self.assertAlmostEqual(obj.n1_degrees, Decimal(math.degrees(obj.n1))) @@ -26,7 +27,9 @@ class DegreesTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_degrees=Degrees('f1'), f2_degrees=Degrees('f2')).first() + obj = FloatModel.objects.annotate( + f1_degrees=Degrees("f1"), f2_degrees=Degrees("f2") + ).first() self.assertIsInstance(obj.f1_degrees, float) self.assertIsInstance(obj.f2_degrees, float) self.assertAlmostEqual(obj.f1_degrees, math.degrees(obj.f1)) @@ -35,9 +38,9 @@ class DegreesTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_degrees=Degrees('small'), - normal_degrees=Degrees('normal'), - big_degrees=Degrees('big'), + small_degrees=Degrees("small"), + normal_degrees=Degrees("normal"), + big_degrees=Degrees("big"), ).first() self.assertIsInstance(obj.small_degrees, float) self.assertIsInstance(obj.normal_degrees, float) @@ -48,7 +51,7 @@ class DegreesTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Degrees): - DecimalModel.objects.create(n1=Decimal('5.4'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-30'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("5.4"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-30"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__degrees__gt=0).get() - self.assertEqual(obj.n1, Decimal('5.4')) + self.assertEqual(obj.n1, Decimal("5.4")) diff --git a/tests/db_functions/math/test_exp.py b/tests/db_functions/math/test_exp.py index a1e806ae45..885549b8cd 100644 --- a/tests/db_functions/math/test_exp.py +++ b/tests/db_functions/math/test_exp.py @@ -10,15 +10,14 @@ from ..models import DecimalModel, FloatModel, IntegerModel class ExpTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_exp=Exp('normal')).first() + obj = IntegerModel.objects.annotate(null_exp=Exp("normal")).first() self.assertIsNone(obj.null_exp) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_exp=Exp('n1'), n2_exp=Exp('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate(n1_exp=Exp("n1"), n2_exp=Exp("n2")).first() self.assertIsInstance(obj.n1_exp, Decimal) self.assertIsInstance(obj.n2_exp, Decimal) self.assertAlmostEqual(obj.n1_exp, Decimal(math.exp(obj.n1))) @@ -26,7 +25,7 @@ class ExpTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_exp=Exp('f1'), f2_exp=Exp('f2')).first() + obj = FloatModel.objects.annotate(f1_exp=Exp("f1"), f2_exp=Exp("f2")).first() self.assertIsInstance(obj.f1_exp, float) self.assertIsInstance(obj.f2_exp, float) self.assertAlmostEqual(obj.f1_exp, math.exp(obj.f1)) @@ -35,9 +34,9 @@ class ExpTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_exp=Exp('small'), - normal_exp=Exp('normal'), - big_exp=Exp('big'), + small_exp=Exp("small"), + normal_exp=Exp("normal"), + big_exp=Exp("big"), ).first() self.assertIsInstance(obj.small_exp, float) self.assertIsInstance(obj.normal_exp, float) @@ -48,7 +47,7 @@ class ExpTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Exp): - DecimalModel.objects.create(n1=Decimal('12.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-1.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("12.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-1.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__exp__gt=10).get() - self.assertEqual(obj.n1, Decimal('12.0')) + self.assertEqual(obj.n1, Decimal("12.0")) diff --git a/tests/db_functions/math/test_floor.py b/tests/db_functions/math/test_floor.py index 1068e55476..b660c1c48e 100644 --- a/tests/db_functions/math/test_floor.py +++ b/tests/db_functions/math/test_floor.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class FloorTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_floor=Floor('normal')).first() + obj = IntegerModel.objects.annotate(null_floor=Floor("normal")).first() self.assertIsNone(obj.null_floor) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_floor=Floor('n1'), n2_floor=Floor('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_floor=Floor("n1"), n2_floor=Floor("n2") + ).first() self.assertIsInstance(obj.n1_floor, Decimal) self.assertIsInstance(obj.n2_floor, Decimal) self.assertEqual(obj.n1_floor, Decimal(math.floor(obj.n1))) @@ -26,7 +27,9 @@ class FloorTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_floor=Floor('f1'), f2_floor=Floor('f2')).first() + obj = FloatModel.objects.annotate( + f1_floor=Floor("f1"), f2_floor=Floor("f2") + ).first() self.assertIsInstance(obj.f1_floor, float) self.assertIsInstance(obj.f2_floor, float) self.assertEqual(obj.f1_floor, math.floor(obj.f1)) @@ -35,9 +38,9 @@ class FloorTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_floor=Floor('small'), - normal_floor=Floor('normal'), - big_floor=Floor('big'), + small_floor=Floor("small"), + normal_floor=Floor("normal"), + big_floor=Floor("big"), ).first() self.assertIsInstance(obj.small_floor, int) self.assertIsInstance(obj.normal_floor, int) @@ -48,7 +51,7 @@ class FloorTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Floor): - DecimalModel.objects.create(n1=Decimal('5.4'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('3.4'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("5.4"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("3.4"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__floor__gt=4).get() - self.assertEqual(obj.n1, Decimal('5.4')) + self.assertEqual(obj.n1, Decimal("5.4")) diff --git a/tests/db_functions/math/test_ln.py b/tests/db_functions/math/test_ln.py index fd2ac87c06..d8a87a348a 100644 --- a/tests/db_functions/math/test_ln.py +++ b/tests/db_functions/math/test_ln.py @@ -10,15 +10,14 @@ from ..models import DecimalModel, FloatModel, IntegerModel class LnTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_ln=Ln('normal')).first() + obj = IntegerModel.objects.annotate(null_ln=Ln("normal")).first() self.assertIsNone(obj.null_ln) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_ln=Ln('n1'), n2_ln=Ln('n2')).first() + DecimalModel.objects.create(n1=Decimal("12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate(n1_ln=Ln("n1"), n2_ln=Ln("n2")).first() self.assertIsInstance(obj.n1_ln, Decimal) self.assertIsInstance(obj.n2_ln, Decimal) self.assertAlmostEqual(obj.n1_ln, Decimal(math.log(obj.n1))) @@ -26,7 +25,7 @@ class LnTests(TestCase): def test_float(self): FloatModel.objects.create(f1=27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_ln=Ln('f1'), f2_ln=Ln('f2')).first() + obj = FloatModel.objects.annotate(f1_ln=Ln("f1"), f2_ln=Ln("f2")).first() self.assertIsInstance(obj.f1_ln, float) self.assertIsInstance(obj.f2_ln, float) self.assertAlmostEqual(obj.f1_ln, math.log(obj.f1)) @@ -35,9 +34,9 @@ class LnTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=20, normal=15, big=1) obj = IntegerModel.objects.annotate( - small_ln=Ln('small'), - normal_ln=Ln('normal'), - big_ln=Ln('big'), + small_ln=Ln("small"), + normal_ln=Ln("normal"), + big_ln=Ln("big"), ).first() self.assertIsInstance(obj.small_ln, float) self.assertIsInstance(obj.normal_ln, float) @@ -48,7 +47,7 @@ class LnTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Ln): - DecimalModel.objects.create(n1=Decimal('12.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('1.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("12.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("1.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__ln__gt=0).get() - self.assertEqual(obj.n1, Decimal('12.0')) + self.assertEqual(obj.n1, Decimal("12.0")) diff --git a/tests/db_functions/math/test_log.py b/tests/db_functions/math/test_log.py index 293993800a..655dcbbcfe 100644 --- a/tests/db_functions/math/test_log.py +++ b/tests/db_functions/math/test_log.py @@ -8,36 +8,35 @@ from ..models import DecimalModel, FloatModel, IntegerModel class LogTests(TestCase): - def test_null(self): IntegerModel.objects.create(big=100) obj = IntegerModel.objects.annotate( - null_log_small=Log('small', 'normal'), - null_log_normal=Log('normal', 'big'), - null_log_big=Log('big', 'normal'), + null_log_small=Log("small", "normal"), + null_log_normal=Log("normal", "big"), + null_log_big=Log("big", "normal"), ).first() self.assertIsNone(obj.null_log_small) self.assertIsNone(obj.null_log_normal) self.assertIsNone(obj.null_log_big) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('12.9'), n2=Decimal('3.6')) - obj = DecimalModel.objects.annotate(n_log=Log('n1', 'n2')).first() + DecimalModel.objects.create(n1=Decimal("12.9"), n2=Decimal("3.6")) + obj = DecimalModel.objects.annotate(n_log=Log("n1", "n2")).first() self.assertIsInstance(obj.n_log, Decimal) self.assertAlmostEqual(obj.n_log, Decimal(math.log(obj.n2, obj.n1))) def test_float(self): FloatModel.objects.create(f1=2.0, f2=4.0) - obj = FloatModel.objects.annotate(f_log=Log('f1', 'f2')).first() + obj = FloatModel.objects.annotate(f_log=Log("f1", "f2")).first() self.assertIsInstance(obj.f_log, float) self.assertAlmostEqual(obj.f_log, math.log(obj.f2, obj.f1)) def test_integer(self): IntegerModel.objects.create(small=4, normal=8, big=2) obj = IntegerModel.objects.annotate( - small_log=Log('small', 'big'), - normal_log=Log('normal', 'big'), - big_log=Log('big', 'big'), + small_log=Log("small", "big"), + normal_log=Log("normal", "big"), + big_log=Log("big", "big"), ).first() self.assertIsInstance(obj.small_log, float) self.assertIsInstance(obj.normal_log, float) diff --git a/tests/db_functions/math/test_mod.py b/tests/db_functions/math/test_mod.py index dc363432b7..919b9419d2 100644 --- a/tests/db_functions/math/test_mod.py +++ b/tests/db_functions/math/test_mod.py @@ -8,34 +8,33 @@ from ..models import DecimalModel, FloatModel, IntegerModel class ModTests(TestCase): - def test_null(self): IntegerModel.objects.create(big=100) obj = IntegerModel.objects.annotate( - null_mod_small=Mod('small', 'normal'), - null_mod_normal=Mod('normal', 'big'), + null_mod_small=Mod("small", "normal"), + null_mod_normal=Mod("normal", "big"), ).first() self.assertIsNone(obj.null_mod_small) self.assertIsNone(obj.null_mod_normal) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-9.9'), n2=Decimal('4.6')) - obj = DecimalModel.objects.annotate(n_mod=Mod('n1', 'n2')).first() + DecimalModel.objects.create(n1=Decimal("-9.9"), n2=Decimal("4.6")) + obj = DecimalModel.objects.annotate(n_mod=Mod("n1", "n2")).first() self.assertIsInstance(obj.n_mod, Decimal) self.assertAlmostEqual(obj.n_mod, Decimal(math.fmod(obj.n1, obj.n2))) def test_float(self): FloatModel.objects.create(f1=-25, f2=0.33) - obj = FloatModel.objects.annotate(f_mod=Mod('f1', 'f2')).first() + obj = FloatModel.objects.annotate(f_mod=Mod("f1", "f2")).first() self.assertIsInstance(obj.f_mod, float) self.assertAlmostEqual(obj.f_mod, math.fmod(obj.f1, obj.f2)) def test_integer(self): IntegerModel.objects.create(small=20, normal=15, big=1) obj = IntegerModel.objects.annotate( - small_mod=Mod('small', 'normal'), - normal_mod=Mod('normal', 'big'), - big_mod=Mod('big', 'small'), + small_mod=Mod("small", "normal"), + normal_mod=Mod("normal", "big"), + big_mod=Mod("big", "small"), ).first() self.assertIsInstance(obj.small_mod, float) self.assertIsInstance(obj.normal_mod, float) diff --git a/tests/db_functions/math/test_pi.py b/tests/db_functions/math/test_pi.py index 2446420fd3..11e4638168 100644 --- a/tests/db_functions/math/test_pi.py +++ b/tests/db_functions/math/test_pi.py @@ -7,7 +7,6 @@ from ..models import FloatModel class PiTests(TestCase): - def test(self): FloatModel.objects.create(f1=2.5, f2=15.9) obj = FloatModel.objects.annotate(pi=Pi()).first() diff --git a/tests/db_functions/math/test_power.py b/tests/db_functions/math/test_power.py index 94929d38b7..44a90f7571 100644 --- a/tests/db_functions/math/test_power.py +++ b/tests/db_functions/math/test_power.py @@ -7,40 +7,39 @@ from ..models import DecimalModel, FloatModel, IntegerModel class PowerTests(TestCase): - def test_null(self): IntegerModel.objects.create(big=100) obj = IntegerModel.objects.annotate( - null_power_small=Power('small', 'normal'), - null_power_normal=Power('normal', 'big'), - null_power_big=Power('big', 'normal'), + null_power_small=Power("small", "normal"), + null_power_normal=Power("normal", "big"), + null_power_big=Power("big", "normal"), ).first() self.assertIsNone(obj.null_power_small) self.assertIsNone(obj.null_power_normal) self.assertIsNone(obj.null_power_big) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('1.0'), n2=Decimal('-0.6')) - obj = DecimalModel.objects.annotate(n_power=Power('n1', 'n2')).first() + DecimalModel.objects.create(n1=Decimal("1.0"), n2=Decimal("-0.6")) + obj = DecimalModel.objects.annotate(n_power=Power("n1", "n2")).first() self.assertIsInstance(obj.n_power, Decimal) - self.assertAlmostEqual(obj.n_power, Decimal(obj.n1 ** obj.n2)) + self.assertAlmostEqual(obj.n_power, Decimal(obj.n1**obj.n2)) def test_float(self): FloatModel.objects.create(f1=2.3, f2=1.1) - obj = FloatModel.objects.annotate(f_power=Power('f1', 'f2')).first() + obj = FloatModel.objects.annotate(f_power=Power("f1", "f2")).first() self.assertIsInstance(obj.f_power, float) - self.assertAlmostEqual(obj.f_power, obj.f1 ** obj.f2) + self.assertAlmostEqual(obj.f_power, obj.f1**obj.f2) def test_integer(self): IntegerModel.objects.create(small=-1, normal=20, big=3) obj = IntegerModel.objects.annotate( - small_power=Power('small', 'normal'), - normal_power=Power('normal', 'big'), - big_power=Power('big', 'small'), + small_power=Power("small", "normal"), + normal_power=Power("normal", "big"), + big_power=Power("big", "small"), ).first() self.assertIsInstance(obj.small_power, float) self.assertIsInstance(obj.normal_power, float) self.assertIsInstance(obj.big_power, float) - self.assertAlmostEqual(obj.small_power, obj.small ** obj.normal) - self.assertAlmostEqual(obj.normal_power, obj.normal ** obj.big) - self.assertAlmostEqual(obj.big_power, obj.big ** obj.small) + self.assertAlmostEqual(obj.small_power, obj.small**obj.normal) + self.assertAlmostEqual(obj.normal_power, obj.normal**obj.big) + self.assertAlmostEqual(obj.big_power, obj.big**obj.small) diff --git a/tests/db_functions/math/test_radians.py b/tests/db_functions/math/test_radians.py index ac51155641..cd94a016e4 100644 --- a/tests/db_functions/math/test_radians.py +++ b/tests/db_functions/math/test_radians.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class RadiansTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_radians=Radians('normal')).first() + obj = IntegerModel.objects.annotate(null_radians=Radians("normal")).first() self.assertIsNone(obj.null_radians) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_radians=Radians('n1'), n2_radians=Radians('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_radians=Radians("n1"), n2_radians=Radians("n2") + ).first() self.assertIsInstance(obj.n1_radians, Decimal) self.assertIsInstance(obj.n2_radians, Decimal) self.assertAlmostEqual(obj.n1_radians, Decimal(math.radians(obj.n1))) @@ -26,7 +27,9 @@ class RadiansTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_radians=Radians('f1'), f2_radians=Radians('f2')).first() + obj = FloatModel.objects.annotate( + f1_radians=Radians("f1"), f2_radians=Radians("f2") + ).first() self.assertIsInstance(obj.f1_radians, float) self.assertIsInstance(obj.f2_radians, float) self.assertAlmostEqual(obj.f1_radians, math.radians(obj.f1)) @@ -35,9 +38,9 @@ class RadiansTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_radians=Radians('small'), - normal_radians=Radians('normal'), - big_radians=Radians('big'), + small_radians=Radians("small"), + normal_radians=Radians("normal"), + big_radians=Radians("big"), ).first() self.assertIsInstance(obj.small_radians, float) self.assertIsInstance(obj.normal_radians, float) @@ -48,7 +51,7 @@ class RadiansTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Radians): - DecimalModel.objects.create(n1=Decimal('2.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-1.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("2.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-1.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__radians__gt=0).get() - self.assertEqual(obj.n1, Decimal('2.0')) + self.assertEqual(obj.n1, Decimal("2.0")) diff --git a/tests/db_functions/math/test_round.py b/tests/db_functions/math/test_round.py index 320d37fe4e..04ece4246d 100644 --- a/tests/db_functions/math/test_round.py +++ b/tests/db_functions/math/test_round.py @@ -11,35 +11,36 @@ from ..models import DecimalModel, FloatModel, IntegerModel class RoundTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_round=Round('normal')).first() + obj = IntegerModel.objects.annotate(null_round=Round("normal")).first() self.assertIsNone(obj.null_round) def test_null_with_precision(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_round=Round('normal', 5)).first() + obj = IntegerModel.objects.annotate(null_round=Round("normal", 5)).first() self.assertIsNone(obj.null_round) def test_null_with_negative_precision(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_round=Round('normal', -1)).first() + obj = IntegerModel.objects.annotate(null_round=Round("normal", -1)).first() self.assertIsNone(obj.null_round) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_round=Round('n1'), n2_round=Round('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_round=Round("n1"), n2_round=Round("n2") + ).first() self.assertIsInstance(obj.n1_round, Decimal) self.assertIsInstance(obj.n2_round, Decimal) self.assertAlmostEqual(obj.n1_round, obj.n1, places=0) self.assertAlmostEqual(obj.n2_round, obj.n2, places=0) def test_decimal_with_precision(self): - DecimalModel.objects.create(n1=Decimal('-5.75'), n2=Pi()) + DecimalModel.objects.create(n1=Decimal("-5.75"), n2=Pi()) obj = DecimalModel.objects.annotate( - n1_round=Round('n1', 1), - n2_round=Round('n2', 5), + n1_round=Round("n1", 1), + n2_round=Round("n2", 5), ).first() self.assertIsInstance(obj.n1_round, Decimal) self.assertIsInstance(obj.n2_round, Decimal) @@ -47,14 +48,16 @@ class RoundTests(TestCase): self.assertAlmostEqual(obj.n2_round, obj.n2, places=5) def test_decimal_with_negative_precision(self): - DecimalModel.objects.create(n1=Decimal('365.25')) - obj = DecimalModel.objects.annotate(n1_round=Round('n1', -1)).first() + DecimalModel.objects.create(n1=Decimal("365.25")) + obj = DecimalModel.objects.annotate(n1_round=Round("n1", -1)).first() self.assertIsInstance(obj.n1_round, Decimal) self.assertEqual(obj.n1_round, 370) def test_float(self): FloatModel.objects.create(f1=-27.55, f2=0.55) - obj = FloatModel.objects.annotate(f1_round=Round('f1'), f2_round=Round('f2')).first() + obj = FloatModel.objects.annotate( + f1_round=Round("f1"), f2_round=Round("f2") + ).first() self.assertIsInstance(obj.f1_round, float) self.assertIsInstance(obj.f2_round, float) self.assertAlmostEqual(obj.f1_round, obj.f1, places=0) @@ -63,8 +66,8 @@ class RoundTests(TestCase): def test_float_with_precision(self): FloatModel.objects.create(f1=-5.75, f2=Pi()) obj = FloatModel.objects.annotate( - f1_round=Round('f1', 1), - f2_round=Round('f2', 5), + f1_round=Round("f1", 1), + f2_round=Round("f2", 5), ).first() self.assertIsInstance(obj.f1_round, float) self.assertIsInstance(obj.f2_round, float) @@ -73,16 +76,16 @@ class RoundTests(TestCase): def test_float_with_negative_precision(self): FloatModel.objects.create(f1=365.25) - obj = FloatModel.objects.annotate(f1_round=Round('f1', -1)).first() + obj = FloatModel.objects.annotate(f1_round=Round("f1", -1)).first() self.assertIsInstance(obj.f1_round, float) self.assertEqual(obj.f1_round, 370) def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_round=Round('small'), - normal_round=Round('normal'), - big_round=Round('big'), + small_round=Round("small"), + normal_round=Round("normal"), + big_round=Round("big"), ).first() self.assertIsInstance(obj.small_round, int) self.assertIsInstance(obj.normal_round, int) @@ -94,9 +97,9 @@ class RoundTests(TestCase): def test_integer_with_precision(self): IntegerModel.objects.create(small=-5, normal=3, big=-100) obj = IntegerModel.objects.annotate( - small_round=Round('small', 1), - normal_round=Round('normal', 5), - big_round=Round('big', 2), + small_round=Round("small", 1), + normal_round=Round("normal", 5), + big_round=Round("big", 2), ).first() self.assertIsInstance(obj.small_round, int) self.assertIsInstance(obj.normal_round, int) @@ -107,23 +110,23 @@ class RoundTests(TestCase): def test_integer_with_negative_precision(self): IntegerModel.objects.create(normal=365) - obj = IntegerModel.objects.annotate(normal_round=Round('normal', -1)).first() + obj = IntegerModel.objects.annotate(normal_round=Round("normal", -1)).first() self.assertIsInstance(obj.normal_round, int) self.assertEqual(obj.normal_round, 370) def test_transform(self): with register_lookup(DecimalField, Round): - DecimalModel.objects.create(n1=Decimal('2.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-1.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("2.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-1.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__round__gt=0).get() - self.assertEqual(obj.n1, Decimal('2.0')) + self.assertEqual(obj.n1, Decimal("2.0")) @unittest.skipUnless( - connection.vendor == 'sqlite', + connection.vendor == "sqlite", "SQLite doesn't support negative precision.", ) def test_unsupported_negative_precision(self): FloatModel.objects.create(f1=123.45) - msg = 'SQLite does not support negative precision.' + msg = "SQLite does not support negative precision." with self.assertRaisesMessage(ValueError, msg): - FloatModel.objects.annotate(value=Round('f1', -1)).first() + FloatModel.objects.annotate(value=Round("f1", -1)).first() diff --git a/tests/db_functions/math/test_sign.py b/tests/db_functions/math/test_sign.py index 0458932cee..c099441a19 100644 --- a/tests/db_functions/math/test_sign.py +++ b/tests/db_functions/math/test_sign.py @@ -9,23 +9,26 @@ from ..models import DecimalModel, FloatModel, IntegerModel class SignTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_sign=Sign('normal')).first() + obj = IntegerModel.objects.annotate(null_sign=Sign("normal")).first() self.assertIsNone(obj.null_sign) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_sign=Sign('n1'), n2_sign=Sign('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_sign=Sign("n1"), n2_sign=Sign("n2") + ).first() self.assertIsInstance(obj.n1_sign, Decimal) self.assertIsInstance(obj.n2_sign, Decimal) - self.assertEqual(obj.n1_sign, Decimal('-1')) - self.assertEqual(obj.n2_sign, Decimal('1')) + self.assertEqual(obj.n1_sign, Decimal("-1")) + self.assertEqual(obj.n2_sign, Decimal("1")) def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_sign=Sign('f1'), f2_sign=Sign('f2')).first() + obj = FloatModel.objects.annotate( + f1_sign=Sign("f1"), f2_sign=Sign("f2") + ).first() self.assertIsInstance(obj.f1_sign, float) self.assertIsInstance(obj.f2_sign, float) self.assertEqual(obj.f1_sign, -1.0) @@ -34,9 +37,9 @@ class SignTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=0, big=20) obj = IntegerModel.objects.annotate( - small_sign=Sign('small'), - normal_sign=Sign('normal'), - big_sign=Sign('big'), + small_sign=Sign("small"), + normal_sign=Sign("normal"), + big_sign=Sign("big"), ).first() self.assertIsInstance(obj.small_sign, int) self.assertIsInstance(obj.normal_sign, int) @@ -47,7 +50,7 @@ class SignTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Sign): - DecimalModel.objects.create(n1=Decimal('5.4'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('-0.1'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("5.4"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("-0.1"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__sign__lt=0, n2__sign=0).get() - self.assertEqual(obj.n1, Decimal('-0.1')) + self.assertEqual(obj.n1, Decimal("-0.1")) diff --git a/tests/db_functions/math/test_sin.py b/tests/db_functions/math/test_sin.py index be7d1515bd..e6c93d75da 100644 --- a/tests/db_functions/math/test_sin.py +++ b/tests/db_functions/math/test_sin.py @@ -10,15 +10,14 @@ from ..models import DecimalModel, FloatModel, IntegerModel class SinTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_sin=Sin('normal')).first() + obj = IntegerModel.objects.annotate(null_sin=Sin("normal")).first() self.assertIsNone(obj.null_sin) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_sin=Sin('n1'), n2_sin=Sin('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate(n1_sin=Sin("n1"), n2_sin=Sin("n2")).first() self.assertIsInstance(obj.n1_sin, Decimal) self.assertIsInstance(obj.n2_sin, Decimal) self.assertAlmostEqual(obj.n1_sin, Decimal(math.sin(obj.n1))) @@ -26,7 +25,7 @@ class SinTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_sin=Sin('f1'), f2_sin=Sin('f2')).first() + obj = FloatModel.objects.annotate(f1_sin=Sin("f1"), f2_sin=Sin("f2")).first() self.assertIsInstance(obj.f1_sin, float) self.assertIsInstance(obj.f2_sin, float) self.assertAlmostEqual(obj.f1_sin, math.sin(obj.f1)) @@ -35,9 +34,9 @@ class SinTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_sin=Sin('small'), - normal_sin=Sin('normal'), - big_sin=Sin('big'), + small_sin=Sin("small"), + normal_sin=Sin("normal"), + big_sin=Sin("big"), ).first() self.assertIsInstance(obj.small_sin, float) self.assertIsInstance(obj.normal_sin, float) @@ -48,7 +47,7 @@ class SinTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Sin): - DecimalModel.objects.create(n1=Decimal('5.4'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('0.1'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("5.4"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("0.1"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__sin__lt=0).get() - self.assertEqual(obj.n1, Decimal('5.4')) + self.assertEqual(obj.n1, Decimal("5.4")) diff --git a/tests/db_functions/math/test_sqrt.py b/tests/db_functions/math/test_sqrt.py index baafaea723..b7751d929e 100644 --- a/tests/db_functions/math/test_sqrt.py +++ b/tests/db_functions/math/test_sqrt.py @@ -10,15 +10,16 @@ from ..models import DecimalModel, FloatModel, IntegerModel class SqrtTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_sqrt=Sqrt('normal')).first() + obj = IntegerModel.objects.annotate(null_sqrt=Sqrt("normal")).first() self.assertIsNone(obj.null_sqrt) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_sqrt=Sqrt('n1'), n2_sqrt=Sqrt('n2')).first() + DecimalModel.objects.create(n1=Decimal("12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate( + n1_sqrt=Sqrt("n1"), n2_sqrt=Sqrt("n2") + ).first() self.assertIsInstance(obj.n1_sqrt, Decimal) self.assertIsInstance(obj.n2_sqrt, Decimal) self.assertAlmostEqual(obj.n1_sqrt, Decimal(math.sqrt(obj.n1))) @@ -26,7 +27,9 @@ class SqrtTests(TestCase): def test_float(self): FloatModel.objects.create(f1=27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_sqrt=Sqrt('f1'), f2_sqrt=Sqrt('f2')).first() + obj = FloatModel.objects.annotate( + f1_sqrt=Sqrt("f1"), f2_sqrt=Sqrt("f2") + ).first() self.assertIsInstance(obj.f1_sqrt, float) self.assertIsInstance(obj.f2_sqrt, float) self.assertAlmostEqual(obj.f1_sqrt, math.sqrt(obj.f1)) @@ -35,9 +38,9 @@ class SqrtTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=20, normal=15, big=1) obj = IntegerModel.objects.annotate( - small_sqrt=Sqrt('small'), - normal_sqrt=Sqrt('normal'), - big_sqrt=Sqrt('big'), + small_sqrt=Sqrt("small"), + normal_sqrt=Sqrt("normal"), + big_sqrt=Sqrt("big"), ).first() self.assertIsInstance(obj.small_sqrt, float) self.assertIsInstance(obj.normal_sqrt, float) @@ -48,7 +51,7 @@ class SqrtTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Sqrt): - DecimalModel.objects.create(n1=Decimal('6.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('1.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("6.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("1.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__sqrt__gt=2).get() - self.assertEqual(obj.n1, Decimal('6.0')) + self.assertEqual(obj.n1, Decimal("6.0")) diff --git a/tests/db_functions/math/test_tan.py b/tests/db_functions/math/test_tan.py index 51f7ad994c..db9c0ee4b3 100644 --- a/tests/db_functions/math/test_tan.py +++ b/tests/db_functions/math/test_tan.py @@ -10,15 +10,14 @@ from ..models import DecimalModel, FloatModel, IntegerModel class TanTests(TestCase): - def test_null(self): IntegerModel.objects.create() - obj = IntegerModel.objects.annotate(null_tan=Tan('normal')).first() + obj = IntegerModel.objects.annotate(null_tan=Tan("normal")).first() self.assertIsNone(obj.null_tan) def test_decimal(self): - DecimalModel.objects.create(n1=Decimal('-12.9'), n2=Decimal('0.6')) - obj = DecimalModel.objects.annotate(n1_tan=Tan('n1'), n2_tan=Tan('n2')).first() + DecimalModel.objects.create(n1=Decimal("-12.9"), n2=Decimal("0.6")) + obj = DecimalModel.objects.annotate(n1_tan=Tan("n1"), n2_tan=Tan("n2")).first() self.assertIsInstance(obj.n1_tan, Decimal) self.assertIsInstance(obj.n2_tan, Decimal) self.assertAlmostEqual(obj.n1_tan, Decimal(math.tan(obj.n1))) @@ -26,7 +25,7 @@ class TanTests(TestCase): def test_float(self): FloatModel.objects.create(f1=-27.5, f2=0.33) - obj = FloatModel.objects.annotate(f1_tan=Tan('f1'), f2_tan=Tan('f2')).first() + obj = FloatModel.objects.annotate(f1_tan=Tan("f1"), f2_tan=Tan("f2")).first() self.assertIsInstance(obj.f1_tan, float) self.assertIsInstance(obj.f2_tan, float) self.assertAlmostEqual(obj.f1_tan, math.tan(obj.f1)) @@ -35,9 +34,9 @@ class TanTests(TestCase): def test_integer(self): IntegerModel.objects.create(small=-20, normal=15, big=-1) obj = IntegerModel.objects.annotate( - small_tan=Tan('small'), - normal_tan=Tan('normal'), - big_tan=Tan('big'), + small_tan=Tan("small"), + normal_tan=Tan("normal"), + big_tan=Tan("big"), ).first() self.assertIsInstance(obj.small_tan, float) self.assertIsInstance(obj.normal_tan, float) @@ -48,7 +47,7 @@ class TanTests(TestCase): def test_transform(self): with register_lookup(DecimalField, Tan): - DecimalModel.objects.create(n1=Decimal('0.0'), n2=Decimal('0')) - DecimalModel.objects.create(n1=Decimal('12.0'), n2=Decimal('0')) + DecimalModel.objects.create(n1=Decimal("0.0"), n2=Decimal("0")) + DecimalModel.objects.create(n1=Decimal("12.0"), n2=Decimal("0")) obj = DecimalModel.objects.filter(n1__tan__lt=0).get() - self.assertEqual(obj.n1, Decimal('12.0')) + self.assertEqual(obj.n1, Decimal("12.0")) diff --git a/tests/db_functions/migrations/0002_create_test_models.py b/tests/db_functions/migrations/0002_create_test_models.py index 3699d67a6f..4f72f4e854 100644 --- a/tests/db_functions/migrations/0002_create_test_models.py +++ b/tests/db_functions/migrations/0002_create_test_models.py @@ -4,74 +4,89 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('db_functions', '0001_setup_extensions'), + ("db_functions", "0001_setup_extensions"), ] operations = [ migrations.CreateModel( - name='Author', + name="Author", fields=[ - ('name', models.CharField(max_length=50)), - ('alias', models.CharField(max_length=50, null=True, blank=True)), - ('goes_by', models.CharField(max_length=50, null=True, blank=True)), - ('age', models.PositiveSmallIntegerField(default=30)), + ("name", models.CharField(max_length=50)), + ("alias", models.CharField(max_length=50, null=True, blank=True)), + ("goes_by", models.CharField(max_length=50, null=True, blank=True)), + ("age", models.PositiveSmallIntegerField(default=30)), ], ), migrations.CreateModel( - name='Article', + name="Article", fields=[ - ('authors', models.ManyToManyField('db_functions.Author', related_name='articles')), - ('title', models.CharField(max_length=50)), - ('summary', models.CharField(max_length=200, null=True, blank=True)), - ('text', models.TextField()), - ('written', models.DateTimeField()), - ('published', models.DateTimeField(null=True, blank=True)), - ('updated', models.DateTimeField(null=True, blank=True)), - ('views', models.PositiveIntegerField(default=0)), + ( + "authors", + models.ManyToManyField( + "db_functions.Author", related_name="articles" + ), + ), + ("title", models.CharField(max_length=50)), + ("summary", models.CharField(max_length=200, null=True, blank=True)), + ("text", models.TextField()), + ("written", models.DateTimeField()), + ("published", models.DateTimeField(null=True, blank=True)), + ("updated", models.DateTimeField(null=True, blank=True)), + ("views", models.PositiveIntegerField(default=0)), ], ), migrations.CreateModel( - name='Fan', + name="Fan", fields=[ - ('name', models.CharField(max_length=50)), - ('age', models.PositiveSmallIntegerField(default=30)), - ('author', models.ForeignKey('db_functions.Author', models.CASCADE, related_name='fans')), - ('fan_since', models.DateTimeField(null=True, blank=True)), + ("name", models.CharField(max_length=50)), + ("age", models.PositiveSmallIntegerField(default=30)), + ( + "author", + models.ForeignKey( + "db_functions.Author", models.CASCADE, related_name="fans" + ), + ), + ("fan_since", models.DateTimeField(null=True, blank=True)), ], ), migrations.CreateModel( - name='DTModel', + name="DTModel", fields=[ - ('name', models.CharField(max_length=32)), - ('start_datetime', models.DateTimeField(null=True, blank=True)), - ('end_datetime', models.DateTimeField(null=True, blank=True)), - ('start_date', models.DateField(null=True, blank=True)), - ('end_date', models.DateField(null=True, blank=True)), - ('start_time', models.TimeField(null=True, blank=True)), - ('end_time', models.TimeField(null=True, blank=True)), - ('duration', models.DurationField(null=True, blank=True)), + ("name", models.CharField(max_length=32)), + ("start_datetime", models.DateTimeField(null=True, blank=True)), + ("end_datetime", models.DateTimeField(null=True, blank=True)), + ("start_date", models.DateField(null=True, blank=True)), + ("end_date", models.DateField(null=True, blank=True)), + ("start_time", models.TimeField(null=True, blank=True)), + ("end_time", models.TimeField(null=True, blank=True)), + ("duration", models.DurationField(null=True, blank=True)), ], ), migrations.CreateModel( - name='DecimalModel', + name="DecimalModel", fields=[ - ('n1', models.DecimalField(decimal_places=2, max_digits=6)), - ('n2', models.DecimalField(decimal_places=7, max_digits=9, null=True, blank=True)), + ("n1", models.DecimalField(decimal_places=2, max_digits=6)), + ( + "n2", + models.DecimalField( + decimal_places=7, max_digits=9, null=True, blank=True + ), + ), ], ), migrations.CreateModel( - name='IntegerModel', + name="IntegerModel", fields=[ - ('big', models.BigIntegerField(null=True, blank=True)), - ('normal', models.IntegerField(null=True, blank=True)), - ('small', models.SmallIntegerField(null=True, blank=True)), + ("big", models.BigIntegerField(null=True, blank=True)), + ("normal", models.IntegerField(null=True, blank=True)), + ("small", models.SmallIntegerField(null=True, blank=True)), ], ), migrations.CreateModel( - name='FloatModel', + name="FloatModel", fields=[ - ('f1', models.FloatField(null=True, blank=True)), - ('f2', models.FloatField(null=True, blank=True)), + ("f1", models.FloatField(null=True, blank=True)), + ("f2", models.FloatField(null=True, blank=True)), ], ), ] diff --git a/tests/db_functions/models.py b/tests/db_functions/models.py index 5c3379b44a..d6a06511bc 100644 --- a/tests/db_functions/models.py +++ b/tests/db_functions/models.py @@ -12,7 +12,7 @@ class Author(models.Model): class Article(models.Model): - authors = models.ManyToManyField(Author, related_name='articles') + authors = models.ManyToManyField(Author, related_name="articles") title = models.CharField(max_length=50) summary = models.CharField(max_length=200, null=True, blank=True) text = models.TextField() @@ -25,7 +25,7 @@ class Article(models.Model): class Fan(models.Model): name = models.CharField(max_length=50) age = models.PositiveSmallIntegerField(default=30) - author = models.ForeignKey(Author, models.CASCADE, related_name='fans') + author = models.ForeignKey(Author, models.CASCADE, related_name="fans") fan_since = models.DateTimeField(null=True, blank=True) diff --git a/tests/db_functions/tests.py b/tests/db_functions/tests.py index e6d8a4fa0a..e5b73cdaac 100644 --- a/tests/db_functions/tests.py +++ b/tests/db_functions/tests.py @@ -1,4 +1,5 @@ -from django.db.models import CharField, Value as V +from django.db.models import CharField +from django.db.models import Value as V from django.db.models.functions import Coalesce, Length, Upper from django.test import TestCase from django.test.utils import register_lookup @@ -11,62 +12,67 @@ class UpperBilateral(Upper): class FunctionTests(TestCase): - def test_nested_function_ordering(self): - Author.objects.create(name='John Smith') - Author.objects.create(name='Rhonda Simpson', alias='ronny') + Author.objects.create(name="John Smith") + Author.objects.create(name="Rhonda Simpson", alias="ronny") - authors = Author.objects.order_by(Length(Coalesce('alias', 'name'))) + authors = Author.objects.order_by(Length(Coalesce("alias", "name"))) self.assertQuerysetEqual( - authors, [ - 'Rhonda Simpson', - 'John Smith', + authors, + [ + "Rhonda Simpson", + "John Smith", ], - lambda a: a.name + lambda a: a.name, ) - authors = Author.objects.order_by(Length(Coalesce('alias', 'name')).desc()) + authors = Author.objects.order_by(Length(Coalesce("alias", "name")).desc()) self.assertQuerysetEqual( - authors, [ - 'John Smith', - 'Rhonda Simpson', + authors, + [ + "John Smith", + "Rhonda Simpson", ], - lambda a: a.name + lambda a: a.name, ) def test_func_transform_bilateral(self): with register_lookup(CharField, UpperBilateral): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') - authors = Author.objects.filter(name__upper__exact='john smith') + 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', + authors.order_by("name"), + [ + "John Smith", ], - lambda a: a.name + lambda a: a.name, ) def test_func_transform_bilateral_multivalue(self): with register_lookup(CharField, UpperBilateral): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') - authors = Author.objects.filter(name__upper__in=['john smith', 'rhonda']) + Author.objects.create(name="John Smith", alias="smithj") + Author.objects.create(name="Rhonda") + authors = Author.objects.filter(name__upper__in=["john smith", "rhonda"]) self.assertQuerysetEqual( - authors.order_by('name'), [ - 'John Smith', - 'Rhonda', + authors.order_by("name"), + [ + "John Smith", + "Rhonda", ], - lambda a: a.name + lambda a: a.name, ) def test_function_as_filter(self): - Author.objects.create(name='John Smith', alias='SMITHJ') - Author.objects.create(name='Rhonda') + Author.objects.create(name="John Smith", alias="SMITHJ") + Author.objects.create(name="Rhonda") self.assertQuerysetEqual( - Author.objects.filter(alias=Upper(V('smithj'))), - ['John Smith'], lambda x: x.name + Author.objects.filter(alias=Upper(V("smithj"))), + ["John Smith"], + lambda x: x.name, ) self.assertQuerysetEqual( - Author.objects.exclude(alias=Upper(V('smithj'))), - ['Rhonda'], lambda x: x.name + Author.objects.exclude(alias=Upper(V("smithj"))), + ["Rhonda"], + lambda x: x.name, ) diff --git a/tests/db_functions/text/test_chr.py b/tests/db_functions/text/test_chr.py index 67a2a6a98d..7a55994096 100644 --- a/tests/db_functions/text/test_chr.py +++ b/tests/db_functions/text/test_chr.py @@ -9,22 +9,31 @@ from ..models import Author class ChrTests(TestCase): @classmethod def setUpTestData(cls): - cls.john = Author.objects.create(name='John Smith', alias='smithj') - cls.elena = Author.objects.create(name='Élena Jordan', alias='elena') - cls.rhonda = Author.objects.create(name='Rhonda') + cls.john = Author.objects.create(name="John Smith", alias="smithj") + cls.elena = Author.objects.create(name="Élena Jordan", alias="elena") + cls.rhonda = Author.objects.create(name="Rhonda") def test_basic(self): - authors = Author.objects.annotate(first_initial=Left('name', 1)) - self.assertCountEqual(authors.filter(first_initial=Chr(ord('J'))), [self.john]) - self.assertCountEqual(authors.exclude(first_initial=Chr(ord('J'))), [self.elena, self.rhonda]) + authors = Author.objects.annotate(first_initial=Left("name", 1)) + self.assertCountEqual(authors.filter(first_initial=Chr(ord("J"))), [self.john]) + self.assertCountEqual( + authors.exclude(first_initial=Chr(ord("J"))), [self.elena, self.rhonda] + ) def test_non_ascii(self): - authors = Author.objects.annotate(first_initial=Left('name', 1)) - self.assertCountEqual(authors.filter(first_initial=Chr(ord('É'))), [self.elena]) - self.assertCountEqual(authors.exclude(first_initial=Chr(ord('É'))), [self.john, self.rhonda]) + authors = Author.objects.annotate(first_initial=Left("name", 1)) + self.assertCountEqual(authors.filter(first_initial=Chr(ord("É"))), [self.elena]) + self.assertCountEqual( + authors.exclude(first_initial=Chr(ord("É"))), [self.john, self.rhonda] + ) def test_transform(self): with register_lookup(IntegerField, Chr): - authors = Author.objects.annotate(name_code_point=Ord('name')) - self.assertCountEqual(authors.filter(name_code_point__chr=Chr(ord('J'))), [self.john]) - self.assertCountEqual(authors.exclude(name_code_point__chr=Chr(ord('J'))), [self.elena, self.rhonda]) + authors = Author.objects.annotate(name_code_point=Ord("name")) + self.assertCountEqual( + authors.filter(name_code_point__chr=Chr(ord("J"))), [self.john] + ) + self.assertCountEqual( + authors.exclude(name_code_point__chr=Chr(ord("J"))), + [self.elena, self.rhonda], + ) diff --git a/tests/db_functions/text/test_concat.py b/tests/db_functions/text/test_concat.py index 9850b2fd0d..5932a9bed0 100644 --- a/tests/db_functions/text/test_concat.py +++ b/tests/db_functions/text/test_concat.py @@ -1,7 +1,8 @@ from unittest import skipUnless from django.db import connection -from django.db.models import CharField, TextField, Value as V +from django.db.models import CharField, TextField +from django.db.models import Value as V from django.db.models.functions import Concat, ConcatPair, Upper from django.test import TestCase from django.utils import timezone @@ -14,68 +15,77 @@ lorem_ipsum = """ 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')) + 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', + authors.order_by("name"), + [ + "", + "smithjJohn", + "Maggie", + "adnohR", ], - lambda a: a.joined + 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')) + 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') + 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()), + joined=Concat("name", V(" ("), "goes_by", V(")"), output_field=CharField()), ) self.assertQuerysetEqual( - authors.order_by('name'), [ - 'Jayden ()', - 'John Smith (John)', - 'Margaret (Maggie)', - 'Rhonda ()', + authors.order_by("name"), + [ + "Jayden ()", + "John Smith (John)", + "Margaret (Maggie)", + "Rhonda ()", ], - lambda a: a.joined + lambda a: a.joined, ) def test_mixed_char_text(self): - Article.objects.create(title='The Title', text=lorem_ipsum, written=timezone.now()) + 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) + 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 + 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.") + @skipUnless(connection.vendor == "sqlite", "sqlite specific implementation detail.") def test_coalesce_idempotent(self): - pair = ConcatPair(V('a'), V('b')) + 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.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')) + 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)) diff --git a/tests/db_functions/text/test_left.py b/tests/db_functions/text/test_left.py index 873bbf859b..8871f9ac79 100644 --- a/tests/db_functions/text/test_left.py +++ b/tests/db_functions/text/test_left.py @@ -8,20 +8,28 @@ from ..models import Author class LeftTests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') + Author.objects.create(name="John Smith", alias="smithj") + Author.objects.create(name="Rhonda") def test_basic(self): - authors = Author.objects.annotate(name_part=Left('name', 5)) - self.assertQuerysetEqual(authors.order_by('name'), ['John ', 'Rhond'], lambda a: a.name_part) + authors = Author.objects.annotate(name_part=Left("name", 5)) + self.assertQuerysetEqual( + authors.order_by("name"), ["John ", "Rhond"], lambda a: a.name_part + ) # If alias is null, set it to the first 2 lower characters of the name. - Author.objects.filter(alias__isnull=True).update(alias=Lower(Left('name', 2))) - self.assertQuerysetEqual(authors.order_by('name'), ['smithj', 'rh'], lambda a: a.alias) + Author.objects.filter(alias__isnull=True).update(alias=Lower(Left("name", 2))) + self.assertQuerysetEqual( + authors.order_by("name"), ["smithj", "rh"], lambda a: a.alias + ) def test_invalid_length(self): with self.assertRaisesMessage(ValueError, "'length' must be greater than 0"): - Author.objects.annotate(raises=Left('name', 0)) + Author.objects.annotate(raises=Left("name", 0)) def test_expressions(self): - authors = Author.objects.annotate(name_part=Left('name', Value(3, output_field=IntegerField()))) - self.assertQuerysetEqual(authors.order_by('name'), ['Joh', 'Rho'], lambda a: a.name_part) + authors = Author.objects.annotate( + name_part=Left("name", Value(3, output_field=IntegerField())) + ) + self.assertQuerysetEqual( + authors.order_by("name"), ["Joh", "Rho"], lambda a: a.name_part + ) diff --git a/tests/db_functions/text/test_length.py b/tests/db_functions/text/test_length.py index 62d1d1c775..c6afead6aa 100644 --- a/tests/db_functions/text/test_length.py +++ b/tests/db_functions/text/test_length.py @@ -7,40 +7,40 @@ from ..models import Author class LengthTests(TestCase): - def test_basic(self): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') + 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'), + 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) + 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) + 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')) + 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'), + authors, + [ + ("Rhonda", "ronny"), + ("John Smith", "smithj"), + ("John Smith", "smithj1"), ], - lambda a: (a.name, a.alias) + lambda a: (a.name, a.alias), ) def test_transform(self): with register_lookup(CharField, Length): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') + 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 + authors.order_by("name"), ["John Smith"], lambda a: a.name ) diff --git a/tests/db_functions/text/test_lower.py b/tests/db_functions/text/test_lower.py index 2f8dd6257d..f4bdc04573 100644 --- a/tests/db_functions/text/test_lower.py +++ b/tests/db_functions/text/test_lower.py @@ -7,34 +7,34 @@ 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')) + 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 + authors.order_by("name"), ["john smith", "rhonda"], lambda a: a.lower_name ) - Author.objects.update(name=Lower('name')) + Author.objects.update(name=Lower("name")) self.assertQuerysetEqual( - authors.order_by('name'), [ - ('john smith', 'john smith'), - ('rhonda', 'rhonda'), + authors.order_by("name"), + [ + ("john smith", "john smith"), + ("rhonda", "rhonda"), ], - lambda a: (a.lower_name, a.name) + 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')) + with self.assertRaisesMessage( + TypeError, "'Lower' takes exactly 1 argument (2 given)" + ): + Author.objects.update(name=Lower("name", "name")) def test_transform(self): with register_lookup(CharField, Lower): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') - authors = Author.objects.filter(name__lower__exact='john smith') + 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 + authors.order_by("name"), ["John Smith"], lambda a: a.name ) diff --git a/tests/db_functions/text/test_md5.py b/tests/db_functions/text/test_md5.py index 931f80ba2c..fd0aec58f2 100644 --- a/tests/db_functions/text/test_md5.py +++ b/tests/db_functions/text/test_md5.py @@ -10,32 +10,40 @@ from ..models import Author class MD5Tests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.bulk_create([ - Author(alias='John Smith'), - Author(alias='Jordan Élena'), - Author(alias='皇帝'), - Author(alias=''), - Author(alias=None), - ]) + Author.objects.bulk_create( + [ + Author(alias="John Smith"), + Author(alias="Jordan Élena"), + Author(alias="皇帝"), + Author(alias=""), + Author(alias=None), + ] + ) def test_basic(self): - authors = Author.objects.annotate( - md5_alias=MD5('alias'), - ).values_list('md5_alias', flat=True).order_by('pk') + authors = ( + Author.objects.annotate( + md5_alias=MD5("alias"), + ) + .values_list("md5_alias", flat=True) + .order_by("pk") + ) self.assertSequenceEqual( authors, [ - '6117323d2cabbc17d44c2b44587f682c', - 'ca6d48f6772000141e66591aee49d56c', - 'bf2c13bc1154e3d2e7df848cbc8be73d', - 'd41d8cd98f00b204e9800998ecf8427e', - 'd41d8cd98f00b204e9800998ecf8427e' if connection.features.interprets_empty_strings_as_nulls else None, + "6117323d2cabbc17d44c2b44587f682c", + "ca6d48f6772000141e66591aee49d56c", + "bf2c13bc1154e3d2e7df848cbc8be73d", + "d41d8cd98f00b204e9800998ecf8427e", + "d41d8cd98f00b204e9800998ecf8427e" + if connection.features.interprets_empty_strings_as_nulls + else None, ], ) def test_transform(self): with register_lookup(CharField, MD5): authors = Author.objects.filter( - alias__md5='6117323d2cabbc17d44c2b44587f682c', - ).values_list('alias', flat=True) - self.assertSequenceEqual(authors, ['John Smith']) + alias__md5="6117323d2cabbc17d44c2b44587f682c", + ).values_list("alias", flat=True) + self.assertSequenceEqual(authors, ["John Smith"]) diff --git a/tests/db_functions/text/test_ord.py b/tests/db_functions/text/test_ord.py index dd704d3c9a..15ad4173f7 100644 --- a/tests/db_functions/text/test_ord.py +++ b/tests/db_functions/text/test_ord.py @@ -9,17 +9,25 @@ from ..models import Author class OrdTests(TestCase): @classmethod def setUpTestData(cls): - cls.john = Author.objects.create(name='John Smith', alias='smithj') - cls.elena = Author.objects.create(name='Élena Jordan', alias='elena') - cls.rhonda = Author.objects.create(name='Rhonda') + cls.john = Author.objects.create(name="John Smith", alias="smithj") + cls.elena = Author.objects.create(name="Élena Jordan", alias="elena") + cls.rhonda = Author.objects.create(name="Rhonda") def test_basic(self): - authors = Author.objects.annotate(name_part=Ord('name')) - self.assertCountEqual(authors.filter(name_part__gt=Ord(Value('John'))), [self.elena, self.rhonda]) - self.assertCountEqual(authors.exclude(name_part__gt=Ord(Value('John'))), [self.john]) + authors = Author.objects.annotate(name_part=Ord("name")) + self.assertCountEqual( + authors.filter(name_part__gt=Ord(Value("John"))), [self.elena, self.rhonda] + ) + self.assertCountEqual( + authors.exclude(name_part__gt=Ord(Value("John"))), [self.john] + ) def test_transform(self): with register_lookup(CharField, Ord): - authors = Author.objects.annotate(first_initial=Left('name', 1)) - self.assertCountEqual(authors.filter(first_initial__ord=ord('J')), [self.john]) - self.assertCountEqual(authors.exclude(first_initial__ord=ord('J')), [self.elena, self.rhonda]) + authors = Author.objects.annotate(first_initial=Left("name", 1)) + self.assertCountEqual( + authors.filter(first_initial__ord=ord("J")), [self.john] + ) + self.assertCountEqual( + authors.exclude(first_initial__ord=ord("J")), [self.elena, self.rhonda] + ) diff --git a/tests/db_functions/text/test_pad.py b/tests/db_functions/text/test_pad.py index fbe82c166e..006a27c0e8 100644 --- a/tests/db_functions/text/test_pad.py +++ b/tests/db_functions/text/test_pad.py @@ -8,45 +8,51 @@ from ..models import Author class PadTests(TestCase): def test_pad(self): - Author.objects.create(name='John', alias='j') - none_value = '' if connection.features.interprets_empty_strings_as_nulls else None + Author.objects.create(name="John", alias="j") + none_value = ( + "" if connection.features.interprets_empty_strings_as_nulls else None + ) tests = ( - (LPad('name', 7, Value('xy')), 'xyxJohn'), - (RPad('name', 7, Value('xy')), 'Johnxyx'), - (LPad('name', 6, Value('x')), 'xxJohn'), - (RPad('name', 6, Value('x')), 'Johnxx'), + (LPad("name", 7, Value("xy")), "xyxJohn"), + (RPad("name", 7, Value("xy")), "Johnxyx"), + (LPad("name", 6, Value("x")), "xxJohn"), + (RPad("name", 6, Value("x")), "Johnxx"), # The default pad string is a space. - (LPad('name', 6), ' John'), - (RPad('name', 6), 'John '), + (LPad("name", 6), " John"), + (RPad("name", 6), "John "), # If string is longer than length it is truncated. - (LPad('name', 2), 'Jo'), - (RPad('name', 2), 'Jo'), - (LPad('name', 0), ''), - (RPad('name', 0), ''), - (LPad('name', None), none_value), - (RPad('name', None), none_value), + (LPad("name", 2), "Jo"), + (RPad("name", 2), "Jo"), + (LPad("name", 0), ""), + (RPad("name", 0), ""), + (LPad("name", None), none_value), + (RPad("name", None), none_value), (LPad(Value(None), 1), none_value), (RPad(Value(None), 1), none_value), - (LPad('goes_by', 1), none_value), - (RPad('goes_by', 1), none_value), + (LPad("goes_by", 1), none_value), + (RPad("goes_by", 1), none_value), ) for function, padded_name in tests: with self.subTest(function=function): authors = Author.objects.annotate(padded_name=function) - self.assertQuerysetEqual(authors, [padded_name], lambda a: a.padded_name, ordered=False) + self.assertQuerysetEqual( + authors, [padded_name], lambda a: a.padded_name, ordered=False + ) def test_pad_negative_length(self): for function in (LPad, RPad): with self.subTest(function=function): - with self.assertRaisesMessage(ValueError, "'length' must be greater or equal to 0."): - function('name', -1) + with self.assertRaisesMessage( + ValueError, "'length' must be greater or equal to 0." + ): + function("name", -1) def test_combined_with_length(self): - Author.objects.create(name='Rhonda', alias='john_smith') - Author.objects.create(name='♥♣♠', alias='bytes') - authors = Author.objects.annotate(filled=LPad('name', Length('alias'))) + Author.objects.create(name="Rhonda", alias="john_smith") + Author.objects.create(name="♥♣♠", alias="bytes") + authors = Author.objects.annotate(filled=LPad("name", Length("alias"))) self.assertQuerysetEqual( - authors.order_by('alias'), - [' ♥♣♠', ' Rhonda'], + authors.order_by("alias"), + [" ♥♣♠", " Rhonda"], lambda a: a.filled, ) diff --git a/tests/db_functions/text/test_repeat.py b/tests/db_functions/text/test_repeat.py index 2234c2e2da..c2d21eae50 100644 --- a/tests/db_functions/text/test_repeat.py +++ b/tests/db_functions/text/test_repeat.py @@ -8,22 +8,28 @@ from ..models import Author class RepeatTests(TestCase): def test_basic(self): - Author.objects.create(name='John', alias='xyz') - none_value = '' if connection.features.interprets_empty_strings_as_nulls else None + Author.objects.create(name="John", alias="xyz") + none_value = ( + "" if connection.features.interprets_empty_strings_as_nulls else None + ) tests = ( - (Repeat('name', 0), ''), - (Repeat('name', 2), 'JohnJohn'), - (Repeat('name', Length('alias')), 'JohnJohnJohn'), - (Repeat(Value('x'), 3), 'xxx'), - (Repeat('name', None), none_value), + (Repeat("name", 0), ""), + (Repeat("name", 2), "JohnJohn"), + (Repeat("name", Length("alias")), "JohnJohnJohn"), + (Repeat(Value("x"), 3), "xxx"), + (Repeat("name", None), none_value), (Repeat(Value(None), 4), none_value), - (Repeat('goes_by', 1), none_value), + (Repeat("goes_by", 1), none_value), ) for function, repeated_text in tests: with self.subTest(function=function): authors = Author.objects.annotate(repeated_text=function) - self.assertQuerysetEqual(authors, [repeated_text], lambda a: a.repeated_text, ordered=False) + self.assertQuerysetEqual( + authors, [repeated_text], lambda a: a.repeated_text, ordered=False + ) def test_negative_number(self): - with self.assertRaisesMessage(ValueError, "'number' must be greater or equal to 0."): - Repeat('name', -1) + with self.assertRaisesMessage( + ValueError, "'number' must be greater or equal to 0." + ): + Repeat("name", -1) diff --git a/tests/db_functions/text/test_replace.py b/tests/db_functions/text/test_replace.py index ae87781b8c..28e39faf09 100644 --- a/tests/db_functions/text/test_replace.py +++ b/tests/db_functions/text/test_replace.py @@ -6,50 +6,78 @@ from ..models import Author class ReplaceTests(TestCase): - @classmethod def setUpTestData(cls): - Author.objects.create(name='George R. R. Martin') - Author.objects.create(name='J. R. R. Tolkien') + Author.objects.create(name="George R. R. Martin") + Author.objects.create(name="J. R. R. Tolkien") def test_replace_with_empty_string(self): qs = Author.objects.annotate( - without_middlename=Replace(F('name'), Value('R. R. '), Value('')), + without_middlename=Replace(F("name"), Value("R. R. "), Value("")), + ) + self.assertQuerysetEqual( + qs, + [ + ("George R. R. Martin", "George Martin"), + ("J. R. R. Tolkien", "J. Tolkien"), + ], + transform=lambda x: (x.name, x.without_middlename), + ordered=False, ) - self.assertQuerysetEqual(qs, [ - ('George R. R. Martin', 'George Martin'), - ('J. R. R. Tolkien', 'J. Tolkien'), - ], transform=lambda x: (x.name, x.without_middlename), ordered=False) def test_case_sensitive(self): - qs = Author.objects.annotate(same_name=Replace(F('name'), Value('r. r.'), Value(''))) - self.assertQuerysetEqual(qs, [ - ('George R. R. Martin', 'George R. R. Martin'), - ('J. R. R. Tolkien', 'J. R. R. Tolkien'), - ], transform=lambda x: (x.name, x.same_name), ordered=False) + qs = Author.objects.annotate( + same_name=Replace(F("name"), Value("r. r."), Value("")) + ) + self.assertQuerysetEqual( + qs, + [ + ("George R. R. Martin", "George R. R. Martin"), + ("J. R. R. Tolkien", "J. R. R. Tolkien"), + ], + transform=lambda x: (x.name, x.same_name), + ordered=False, + ) def test_replace_expression(self): - qs = Author.objects.annotate(same_name=Replace( - Concat(Value('Author: '), F('name')), Value('Author: '), Value('')), + qs = Author.objects.annotate( + same_name=Replace( + Concat(Value("Author: "), F("name")), Value("Author: "), Value("") + ), + ) + self.assertQuerysetEqual( + qs, + [ + ("George R. R. Martin", "George R. R. Martin"), + ("J. R. R. Tolkien", "J. R. R. Tolkien"), + ], + transform=lambda x: (x.name, x.same_name), + ordered=False, ) - self.assertQuerysetEqual(qs, [ - ('George R. R. Martin', 'George R. R. Martin'), - ('J. R. R. Tolkien', 'J. R. R. Tolkien'), - ], transform=lambda x: (x.name, x.same_name), ordered=False) def test_update(self): Author.objects.update( - name=Replace(F('name'), Value('R. R. '), Value('')), + name=Replace(F("name"), Value("R. R. "), Value("")), + ) + self.assertQuerysetEqual( + Author.objects.all(), + [ + ("George Martin"), + ("J. Tolkien"), + ], + transform=lambda x: x.name, + ordered=False, ) - self.assertQuerysetEqual(Author.objects.all(), [ - ('George Martin'), - ('J. Tolkien'), - ], transform=lambda x: x.name, ordered=False) def test_replace_with_default_arg(self): # The default replacement is an empty string. - qs = Author.objects.annotate(same_name=Replace(F('name'), Value('R. R. '))) - self.assertQuerysetEqual(qs, [ - ('George R. R. Martin', 'George Martin'), - ('J. R. R. Tolkien', 'J. Tolkien'), - ], transform=lambda x: (x.name, x.same_name), ordered=False) + qs = Author.objects.annotate(same_name=Replace(F("name"), Value("R. R. "))) + self.assertQuerysetEqual( + qs, + [ + ("George R. R. Martin", "George Martin"), + ("J. R. R. Tolkien", "J. Tolkien"), + ], + transform=lambda x: (x.name, x.same_name), + ordered=False, + ) diff --git a/tests/db_functions/text/test_reverse.py b/tests/db_functions/text/test_reverse.py index 1cc1045b04..4d1a81ccf2 100644 --- a/tests/db_functions/text/test_reverse.py +++ b/tests/db_functions/text/test_reverse.py @@ -10,22 +10,27 @@ from ..models import Author class ReverseTests(TestCase): @classmethod def setUpTestData(cls): - cls.john = Author.objects.create(name='John Smith', alias='smithj') - cls.elena = Author.objects.create(name='Élena Jordan', alias='elena') - cls.python = Author.objects.create(name='パイソン') + cls.john = Author.objects.create(name="John Smith", alias="smithj") + cls.elena = Author.objects.create(name="Élena Jordan", alias="elena") + cls.python = Author.objects.create(name="パイソン") def test_null(self): - author = Author.objects.annotate(backward=Reverse('alias')).get(pk=self.python.pk) - self.assertEqual(author.backward, '' if connection.features.interprets_empty_strings_as_nulls else None) + author = Author.objects.annotate(backward=Reverse("alias")).get( + pk=self.python.pk + ) + self.assertEqual( + author.backward, + "" if connection.features.interprets_empty_strings_as_nulls else None, + ) def test_basic(self): - authors = Author.objects.annotate(backward=Reverse('name')) + authors = Author.objects.annotate(backward=Reverse("name")) self.assertQuerysetEqual( authors, [ - ('John Smith', 'htimS nhoJ'), - ('Élena Jordan', 'nadroJ anelÉ'), - ('パイソン', 'ンソイパ'), + ("John Smith", "htimS nhoJ"), + ("Élena Jordan", "nadroJ anelÉ"), + ("パイソン", "ンソイパ"), ], lambda a: (a.name, a.backward), ordered=False, @@ -34,13 +39,24 @@ class ReverseTests(TestCase): def test_transform(self): with register_lookup(CharField, Reverse): authors = Author.objects.all() - self.assertCountEqual(authors.filter(name__reverse=self.john.name[::-1]), [self.john]) - self.assertCountEqual(authors.exclude(name__reverse=self.john.name[::-1]), [self.elena, self.python]) + self.assertCountEqual( + authors.filter(name__reverse=self.john.name[::-1]), [self.john] + ) + self.assertCountEqual( + authors.exclude(name__reverse=self.john.name[::-1]), + [self.elena, self.python], + ) def test_expressions(self): - author = Author.objects.annotate(backward=Reverse(Trim('name'))).get(pk=self.john.pk) + author = Author.objects.annotate(backward=Reverse(Trim("name"))).get( + pk=self.john.pk + ) self.assertEqual(author.backward, self.john.name[::-1]) with register_lookup(CharField, Reverse), register_lookup(CharField, Length): authors = Author.objects.all() - self.assertCountEqual(authors.filter(name__reverse__length__gt=7), [self.john, self.elena]) - self.assertCountEqual(authors.exclude(name__reverse__length__gt=7), [self.python]) + self.assertCountEqual( + authors.filter(name__reverse__length__gt=7), [self.john, self.elena] + ) + self.assertCountEqual( + authors.exclude(name__reverse__length__gt=7), [self.python] + ) diff --git a/tests/db_functions/text/test_right.py b/tests/db_functions/text/test_right.py index ab29cb9456..8c271fcf7d 100644 --- a/tests/db_functions/text/test_right.py +++ b/tests/db_functions/text/test_right.py @@ -8,20 +8,28 @@ from ..models import Author class RightTests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') + Author.objects.create(name="John Smith", alias="smithj") + Author.objects.create(name="Rhonda") def test_basic(self): - authors = Author.objects.annotate(name_part=Right('name', 5)) - self.assertQuerysetEqual(authors.order_by('name'), ['Smith', 'honda'], lambda a: a.name_part) + authors = Author.objects.annotate(name_part=Right("name", 5)) + self.assertQuerysetEqual( + authors.order_by("name"), ["Smith", "honda"], lambda a: a.name_part + ) # If alias is null, set it to the first 2 lower characters of the name. - Author.objects.filter(alias__isnull=True).update(alias=Lower(Right('name', 2))) - self.assertQuerysetEqual(authors.order_by('name'), ['smithj', 'da'], lambda a: a.alias) + Author.objects.filter(alias__isnull=True).update(alias=Lower(Right("name", 2))) + self.assertQuerysetEqual( + authors.order_by("name"), ["smithj", "da"], lambda a: a.alias + ) def test_invalid_length(self): with self.assertRaisesMessage(ValueError, "'length' must be greater than 0"): - Author.objects.annotate(raises=Right('name', 0)) + Author.objects.annotate(raises=Right("name", 0)) def test_expressions(self): - authors = Author.objects.annotate(name_part=Right('name', Value(3, output_field=IntegerField()))) - self.assertQuerysetEqual(authors.order_by('name'), ['ith', 'nda'], lambda a: a.name_part) + authors = Author.objects.annotate( + name_part=Right("name", Value(3, output_field=IntegerField())) + ) + self.assertQuerysetEqual( + authors.order_by("name"), ["ith", "nda"], lambda a: a.name_part + ) diff --git a/tests/db_functions/text/test_sha1.py b/tests/db_functions/text/test_sha1.py index e34057bd6c..175c5727ff 100644 --- a/tests/db_functions/text/test_sha1.py +++ b/tests/db_functions/text/test_sha1.py @@ -10,33 +10,40 @@ from ..models import Author class SHA1Tests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.bulk_create([ - Author(alias='John Smith'), - Author(alias='Jordan Élena'), - Author(alias='皇帝'), - Author(alias=''), - Author(alias=None), - ]) + Author.objects.bulk_create( + [ + Author(alias="John Smith"), + Author(alias="Jordan Élena"), + Author(alias="皇帝"), + Author(alias=""), + Author(alias=None), + ] + ) def test_basic(self): - authors = Author.objects.annotate( - sha1_alias=SHA1('alias'), - ).values_list('sha1_alias', flat=True).order_by('pk') + authors = ( + Author.objects.annotate( + sha1_alias=SHA1("alias"), + ) + .values_list("sha1_alias", flat=True) + .order_by("pk") + ) self.assertSequenceEqual( authors, [ - 'e61a3587b3f7a142b8c7b9263c82f8119398ecb7', - '0781e0745a2503e6ded05ed5bc554c421d781b0c', - '198d15ea139de04060caf95bc3e0ec5883cba881', - 'da39a3ee5e6b4b0d3255bfef95601890afd80709', - 'da39a3ee5e6b4b0d3255bfef95601890afd80709' - if connection.features.interprets_empty_strings_as_nulls else None, + "e61a3587b3f7a142b8c7b9263c82f8119398ecb7", + "0781e0745a2503e6ded05ed5bc554c421d781b0c", + "198d15ea139de04060caf95bc3e0ec5883cba881", + "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "da39a3ee5e6b4b0d3255bfef95601890afd80709" + if connection.features.interprets_empty_strings_as_nulls + else None, ], ) def test_transform(self): with register_lookup(CharField, SHA1): authors = Author.objects.filter( - alias__sha1='e61a3587b3f7a142b8c7b9263c82f8119398ecb7', - ).values_list('alias', flat=True) - self.assertSequenceEqual(authors, ['John Smith']) + alias__sha1="e61a3587b3f7a142b8c7b9263c82f8119398ecb7", + ).values_list("alias", flat=True) + self.assertSequenceEqual(authors, ["John Smith"]) diff --git a/tests/db_functions/text/test_sha224.py b/tests/db_functions/text/test_sha224.py index d2f1d538dc..83c30a3091 100644 --- a/tests/db_functions/text/test_sha224.py +++ b/tests/db_functions/text/test_sha224.py @@ -12,39 +12,48 @@ from ..models import Author class SHA224Tests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.bulk_create([ - Author(alias='John Smith'), - Author(alias='Jordan Élena'), - Author(alias='皇帝'), - Author(alias=''), - Author(alias=None), - ]) + Author.objects.bulk_create( + [ + Author(alias="John Smith"), + Author(alias="Jordan Élena"), + Author(alias="皇帝"), + Author(alias=""), + Author(alias=None), + ] + ) def test_basic(self): - authors = Author.objects.annotate( - sha224_alias=SHA224('alias'), - ).values_list('sha224_alias', flat=True).order_by('pk') + authors = ( + Author.objects.annotate( + sha224_alias=SHA224("alias"), + ) + .values_list("sha224_alias", flat=True) + .order_by("pk") + ) self.assertSequenceEqual( authors, [ - 'a61303c220731168452cb6acf3759438b1523e768f464e3704e12f70', - '2297904883e78183cb118fc3dc21a610d60daada7b6ebdbc85139f4d', - 'eba942746e5855121d9d8f79e27dfdebed81adc85b6bf41591203080', - 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f', - 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f' - if connection.features.interprets_empty_strings_as_nulls else None, + "a61303c220731168452cb6acf3759438b1523e768f464e3704e12f70", + "2297904883e78183cb118fc3dc21a610d60daada7b6ebdbc85139f4d", + "eba942746e5855121d9d8f79e27dfdebed81adc85b6bf41591203080", + "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", + "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" + if connection.features.interprets_empty_strings_as_nulls + else None, ], ) def test_transform(self): with register_lookup(CharField, SHA224): authors = Author.objects.filter( - alias__sha224='a61303c220731168452cb6acf3759438b1523e768f464e3704e12f70', - ).values_list('alias', flat=True) - self.assertSequenceEqual(authors, ['John Smith']) + alias__sha224="a61303c220731168452cb6acf3759438b1523e768f464e3704e12f70", + ).values_list("alias", flat=True) + self.assertSequenceEqual(authors, ["John Smith"]) - @unittest.skipUnless(connection.vendor == 'oracle', "Oracle doesn't support SHA224.") + @unittest.skipUnless( + connection.vendor == "oracle", "Oracle doesn't support SHA224." + ) def test_unsupported(self): - msg = 'SHA224 is not supported on Oracle.' + msg = "SHA224 is not supported on Oracle." with self.assertRaisesMessage(NotSupportedError, msg): - Author.objects.annotate(sha224_alias=SHA224('alias')).first() + Author.objects.annotate(sha224_alias=SHA224("alias")).first() diff --git a/tests/db_functions/text/test_sha256.py b/tests/db_functions/text/test_sha256.py index 54ad841422..d6f431fdf6 100644 --- a/tests/db_functions/text/test_sha256.py +++ b/tests/db_functions/text/test_sha256.py @@ -10,33 +10,40 @@ from ..models import Author class SHA256Tests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.bulk_create([ - Author(alias='John Smith'), - Author(alias='Jordan Élena'), - Author(alias='皇帝'), - Author(alias=''), - Author(alias=None), - ]) + Author.objects.bulk_create( + [ + Author(alias="John Smith"), + Author(alias="Jordan Élena"), + Author(alias="皇帝"), + Author(alias=""), + Author(alias=None), + ] + ) def test_basic(self): - authors = Author.objects.annotate( - sha256_alias=SHA256('alias'), - ).values_list('sha256_alias', flat=True).order_by('pk') + authors = ( + Author.objects.annotate( + sha256_alias=SHA256("alias"), + ) + .values_list("sha256_alias", flat=True) + .order_by("pk") + ) self.assertSequenceEqual( authors, [ - 'ef61a579c907bbed674c0dbcbcf7f7af8f851538eef7b8e58c5bee0b8cfdac4a', - '6e4cce20cd83fc7c202f21a8b2452a68509cf24d1c272a045b5e0cfc43f0d94e', - '3ad2039e3ec0c88973ae1c0fce5a3dbafdd5a1627da0a92312c54ebfcf43988e', - 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', - 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' - if connection.features.interprets_empty_strings_as_nulls else None, + "ef61a579c907bbed674c0dbcbcf7f7af8f851538eef7b8e58c5bee0b8cfdac4a", + "6e4cce20cd83fc7c202f21a8b2452a68509cf24d1c272a045b5e0cfc43f0d94e", + "3ad2039e3ec0c88973ae1c0fce5a3dbafdd5a1627da0a92312c54ebfcf43988e", + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + if connection.features.interprets_empty_strings_as_nulls + else None, ], ) def test_transform(self): with register_lookup(CharField, SHA256): authors = Author.objects.filter( - alias__sha256='ef61a579c907bbed674c0dbcbcf7f7af8f851538eef7b8e58c5bee0b8cfdac4a', - ).values_list('alias', flat=True) - self.assertSequenceEqual(authors, ['John Smith']) + alias__sha256="ef61a579c907bbed674c0dbcbcf7f7af8f851538eef7b8e58c5bee0b8cfdac4a", + ).values_list("alias", flat=True) + self.assertSequenceEqual(authors, ["John Smith"]) diff --git a/tests/db_functions/text/test_sha384.py b/tests/db_functions/text/test_sha384.py index 95aa54cdbb..cac72d54ce 100644 --- a/tests/db_functions/text/test_sha384.py +++ b/tests/db_functions/text/test_sha384.py @@ -10,27 +10,34 @@ from ..models import Author class SHA384Tests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.bulk_create([ - Author(alias='John Smith'), - Author(alias='Jordan Élena'), - Author(alias='皇帝'), - Author(alias=''), - Author(alias=None), - ]) + Author.objects.bulk_create( + [ + Author(alias="John Smith"), + Author(alias="Jordan Élena"), + Author(alias="皇帝"), + Author(alias=""), + Author(alias=None), + ] + ) def test_basic(self): - authors = Author.objects.annotate( - sha384_alias=SHA384('alias'), - ).values_list('sha384_alias', flat=True).order_by('pk') + authors = ( + Author.objects.annotate( + sha384_alias=SHA384("alias"), + ) + .values_list("sha384_alias", flat=True) + .order_by("pk") + ) self.assertSequenceEqual( authors, [ - '9df976bfbcf96c66fbe5cba866cd4deaa8248806f15b69c4010a404112906e4ca7b57e53b9967b80d77d4f5c2982cbc8', - '72202c8005492016cc670219cce82d47d6d2d4273464c742ab5811d691b1e82a7489549e3a73ffa119694f90678ba2e3', - 'eda87fae41e59692c36c49e43279c8111a00d79122a282a944e8ba9a403218f049a48326676a43c7ba378621175853b0', - '38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b', - '38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b' - if connection.features.interprets_empty_strings_as_nulls else None, + "9df976bfbcf96c66fbe5cba866cd4deaa8248806f15b69c4010a404112906e4ca7b57e53b9967b80d77d4f5c2982cbc8", + "72202c8005492016cc670219cce82d47d6d2d4273464c742ab5811d691b1e82a7489549e3a73ffa119694f90678ba2e3", + "eda87fae41e59692c36c49e43279c8111a00d79122a282a944e8ba9a403218f049a48326676a43c7ba378621175853b0", + "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", + "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" + if connection.features.interprets_empty_strings_as_nulls + else None, ], ) @@ -38,7 +45,7 @@ class SHA384Tests(TestCase): with register_lookup(CharField, SHA384): authors = Author.objects.filter( alias__sha384=( - '9df976bfbcf96c66fbe5cba866cd4deaa8248806f15b69c4010a404112906e4ca7b57e53b9967b80d77d4f5c2982cbc8' + "9df976bfbcf96c66fbe5cba866cd4deaa8248806f15b69c4010a404112906e4ca7b57e53b9967b80d77d4f5c2982cbc8" ), - ).values_list('alias', flat=True) - self.assertSequenceEqual(authors, ['John Smith']) + ).values_list("alias", flat=True) + self.assertSequenceEqual(authors, ["John Smith"]) diff --git a/tests/db_functions/text/test_sha512.py b/tests/db_functions/text/test_sha512.py index aa0d1e6fdd..f5a7ad4ae5 100644 --- a/tests/db_functions/text/test_sha512.py +++ b/tests/db_functions/text/test_sha512.py @@ -10,32 +10,39 @@ from ..models import Author class SHA512Tests(TestCase): @classmethod def setUpTestData(cls): - Author.objects.bulk_create([ - Author(alias='John Smith'), - Author(alias='Jordan Élena'), - Author(alias='皇帝'), - Author(alias=''), - Author(alias=None), - ]) + Author.objects.bulk_create( + [ + Author(alias="John Smith"), + Author(alias="Jordan Élena"), + Author(alias="皇帝"), + Author(alias=""), + Author(alias=None), + ] + ) def test_basic(self): - authors = Author.objects.annotate( - sha512_alias=SHA512('alias'), - ).values_list('sha512_alias', flat=True).order_by('pk') + authors = ( + Author.objects.annotate( + sha512_alias=SHA512("alias"), + ) + .values_list("sha512_alias", flat=True) + .order_by("pk") + ) self.assertSequenceEqual( authors, [ - 'ed014a19bb67a85f9c8b1d81e04a0e7101725be8627d79d02ca4f3bd803f33cf' - '3b8fed53e80d2a12c0d0e426824d99d110f0919298a5055efff040a3fc091518', - 'b09c449f3ba49a32ab44754982d4749ac938af293e4af2de28858858080a1611' - '2b719514b5e48cb6ce54687e843a4b3e69a04cdb2a9dc99c3b99bdee419fa7d0', - 'b554d182e25fb487a3f2b4285bb8672f98956b5369138e681b467d1f079af116' - '172d88798345a3a7666faf5f35a144c60812d3234dcd35f444624f2faee16857', - 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce' - '47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', - 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce' - '47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e' - if connection.features.interprets_empty_strings_as_nulls else None, + "ed014a19bb67a85f9c8b1d81e04a0e7101725be8627d79d02ca4f3bd803f33cf" + "3b8fed53e80d2a12c0d0e426824d99d110f0919298a5055efff040a3fc091518", + "b09c449f3ba49a32ab44754982d4749ac938af293e4af2de28858858080a1611" + "2b719514b5e48cb6ce54687e843a4b3e69a04cdb2a9dc99c3b99bdee419fa7d0", + "b554d182e25fb487a3f2b4285bb8672f98956b5369138e681b467d1f079af116" + "172d88798345a3a7666faf5f35a144c60812d3234dcd35f444624f2faee16857", + "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" + "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", + "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" + "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + if connection.features.interprets_empty_strings_as_nulls + else None, ], ) @@ -43,9 +50,9 @@ class SHA512Tests(TestCase): with register_lookup(CharField, SHA512): authors = Author.objects.filter( alias__sha512=( - 'ed014a19bb67a85f9c8b1d81e04a0e7101725be8627d79d02ca4f3bd8' - '03f33cf3b8fed53e80d2a12c0d0e426824d99d110f0919298a5055eff' - 'f040a3fc091518' + "ed014a19bb67a85f9c8b1d81e04a0e7101725be8627d79d02ca4f3bd8" + "03f33cf3b8fed53e80d2a12c0d0e426824d99d110f0919298a5055eff" + "f040a3fc091518" ), - ).values_list('alias', flat=True) - self.assertSequenceEqual(authors, ['John Smith']) + ).values_list("alias", flat=True) + self.assertSequenceEqual(authors, ["John Smith"]) diff --git a/tests/db_functions/text/test_strindex.py b/tests/db_functions/text/test_strindex.py index 1670df00fd..84305ea1b7 100644 --- a/tests/db_functions/text/test_strindex.py +++ b/tests/db_functions/text/test_strindex.py @@ -8,59 +8,67 @@ from ..models import Article, Author class StrIndexTests(TestCase): def test_annotate_charfield(self): - Author.objects.create(name='George. R. R. Martin') - Author.objects.create(name='J. R. R. Tolkien') - Author.objects.create(name='Terry Pratchett') - authors = Author.objects.annotate(fullstop=StrIndex('name', Value('R.'))) - self.assertQuerysetEqual(authors.order_by('name'), [9, 4, 0], lambda a: a.fullstop) + Author.objects.create(name="George. R. R. Martin") + Author.objects.create(name="J. R. R. Tolkien") + Author.objects.create(name="Terry Pratchett") + authors = Author.objects.annotate(fullstop=StrIndex("name", Value("R."))) + self.assertQuerysetEqual( + authors.order_by("name"), [9, 4, 0], lambda a: a.fullstop + ) def test_annotate_textfield(self): Article.objects.create( - title='How to Django', - text='This is about How to Django.', + title="How to Django", + text="This is about How to Django.", written=timezone.now(), ) Article.objects.create( - title='How to Tango', + title="How to Tango", text="Won't find anything here.", written=timezone.now(), ) - articles = Article.objects.annotate(title_pos=StrIndex('text', 'title')) - self.assertQuerysetEqual(articles.order_by('title'), [15, 0], lambda a: a.title_pos) + articles = Article.objects.annotate(title_pos=StrIndex("text", "title")) + self.assertQuerysetEqual( + articles.order_by("title"), [15, 0], lambda a: a.title_pos + ) def test_order_by(self): - Author.objects.create(name='Terry Pratchett') - Author.objects.create(name='J. R. R. Tolkien') - Author.objects.create(name='George. R. R. Martin') + Author.objects.create(name="Terry Pratchett") + Author.objects.create(name="J. R. R. Tolkien") + Author.objects.create(name="George. R. R. Martin") self.assertQuerysetEqual( - Author.objects.order_by(StrIndex('name', Value('R.')).asc()), [ - 'Terry Pratchett', - 'J. R. R. Tolkien', - 'George. R. R. Martin', + Author.objects.order_by(StrIndex("name", Value("R.")).asc()), + [ + "Terry Pratchett", + "J. R. R. Tolkien", + "George. R. R. Martin", ], - lambda a: a.name + lambda a: a.name, ) self.assertQuerysetEqual( - Author.objects.order_by(StrIndex('name', Value('R.')).desc()), [ - 'George. R. R. Martin', - 'J. R. R. Tolkien', - 'Terry Pratchett', + Author.objects.order_by(StrIndex("name", Value("R.")).desc()), + [ + "George. R. R. Martin", + "J. R. R. Tolkien", + "Terry Pratchett", ], - lambda a: a.name + lambda a: a.name, ) def test_unicode_values(self): - Author.objects.create(name='ツリー') - Author.objects.create(name='皇帝') - Author.objects.create(name='皇帝 ツリー') - authors = Author.objects.annotate(sb=StrIndex('name', Value('リ'))) - self.assertQuerysetEqual(authors.order_by('name'), [2, 0, 5], lambda a: a.sb) + Author.objects.create(name="ツリー") + Author.objects.create(name="皇帝") + Author.objects.create(name="皇帝 ツリー") + authors = Author.objects.annotate(sb=StrIndex("name", Value("リ"))) + self.assertQuerysetEqual(authors.order_by("name"), [2, 0, 5], lambda a: a.sb) def test_filtering(self): - Author.objects.create(name='George. R. R. Martin') - Author.objects.create(name='Terry Pratchett') + Author.objects.create(name="George. R. R. Martin") + Author.objects.create(name="Terry Pratchett") self.assertQuerysetEqual( - Author.objects.annotate(middle_name=StrIndex('name', Value('R.'))).filter(middle_name__gt=0), - ['George. R. R. Martin'], - lambda a: a.name + Author.objects.annotate(middle_name=StrIndex("name", Value("R."))).filter( + middle_name__gt=0 + ), + ["George. R. R. Martin"], + lambda a: a.name, ) diff --git a/tests/db_functions/text/test_substr.py b/tests/db_functions/text/test_substr.py index 35af5656ef..751995355c 100644 --- a/tests/db_functions/text/test_substr.py +++ b/tests/db_functions/text/test_substr.py @@ -6,48 +6,43 @@ 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)) + 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.order_by("name"), [" Sm", "da"], lambda a: a.name_part ) - authors = Author.objects.annotate(name_part=Substr('name', 2)) + authors = Author.objects.annotate(name_part=Substr("name", 2)) self.assertQuerysetEqual( - authors.order_by('name'), ['ohn Smith', 'honda'], - lambda a: a.name_part + 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)), + alias=Lower(Substr("name", 1, 5)), ) self.assertQuerysetEqual( - authors.order_by('name'), ['smithj', 'rhond'], - lambda a: a.alias + authors.order_by("name"), ["smithj", "rhond"], lambda a: a.alias ) def test_start(self): - Author.objects.create(name='John Smith', alias='smithj') + 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') + 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)) + 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) + Author.objects.create(name="John Smith", alias="smithj") + Author.objects.create(name="Rhonda") + substr = Substr(Upper("name"), StrIndex("name", V("h")), 5) authors = Author.objects.annotate(name_part=substr) self.assertQuerysetEqual( - authors.order_by('name'), ['HN SM', 'HONDA'], - lambda a: a.name_part + authors.order_by("name"), ["HN SM", "HONDA"], lambda a: a.name_part ) diff --git a/tests/db_functions/text/test_trim.py b/tests/db_functions/text/test_trim.py index 9834cef1c6..57a342851e 100644 --- a/tests/db_functions/text/test_trim.py +++ b/tests/db_functions/text/test_trim.py @@ -8,31 +8,34 @@ from ..models import Author class TrimTests(TestCase): def test_trim(self): - Author.objects.create(name=' John ', alias='j') - Author.objects.create(name='Rhonda', alias='r') + Author.objects.create(name=" John ", alias="j") + Author.objects.create(name="Rhonda", alias="r") authors = Author.objects.annotate( - ltrim=LTrim('name'), - rtrim=RTrim('name'), - trim=Trim('name'), + ltrim=LTrim("name"), + rtrim=RTrim("name"), + trim=Trim("name"), ) self.assertQuerysetEqual( - authors.order_by('alias'), [ - ('John ', ' John', 'John'), - ('Rhonda', 'Rhonda', 'Rhonda'), + authors.order_by("alias"), + [ + ("John ", " John", "John"), + ("Rhonda", "Rhonda", "Rhonda"), ], - lambda a: (a.ltrim, a.rtrim, a.trim) + lambda a: (a.ltrim, a.rtrim, a.trim), ) def test_trim_transform(self): - Author.objects.create(name=' John ') - Author.objects.create(name='Rhonda') + Author.objects.create(name=" John ") + Author.objects.create(name="Rhonda") tests = ( - (LTrim, 'John '), - (RTrim, ' John'), - (Trim, 'John'), + (LTrim, "John "), + (RTrim, " John"), + (Trim, "John"), ) for transform, trimmed_name in tests: with self.subTest(transform=transform): with register_lookup(CharField, transform): - authors = Author.objects.filter(**{'name__%s' % transform.lookup_name: trimmed_name}) - self.assertQuerysetEqual(authors, [' John '], lambda a: a.name) + authors = Author.objects.filter( + **{"name__%s" % transform.lookup_name: trimmed_name} + ) + self.assertQuerysetEqual(authors, [" John "], lambda a: a.name) diff --git a/tests/db_functions/text/test_upper.py b/tests/db_functions/text/test_upper.py index 5b5df0af33..728ea82265 100644 --- a/tests/db_functions/text/test_upper.py +++ b/tests/db_functions/text/test_upper.py @@ -7,35 +7,37 @@ 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')) + 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', + authors.order_by("name"), + [ + "JOHN SMITH", + "RHONDA", ], - lambda a: a.upper_name + lambda a: a.upper_name, ) - Author.objects.update(name=Upper('name')) + Author.objects.update(name=Upper("name")) self.assertQuerysetEqual( - authors.order_by('name'), [ - ('JOHN SMITH', 'JOHN SMITH'), - ('RHONDA', 'RHONDA'), + authors.order_by("name"), + [ + ("JOHN SMITH", "JOHN SMITH"), + ("RHONDA", "RHONDA"), ], - lambda a: (a.upper_name, a.name) + lambda a: (a.upper_name, a.name), ) def test_transform(self): with register_lookup(CharField, Upper): - Author.objects.create(name='John Smith', alias='smithj') - Author.objects.create(name='Rhonda') - authors = Author.objects.filter(name__upper__exact='JOHN SMITH') + 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', + authors.order_by("name"), + [ + "John Smith", ], - lambda a: a.name + lambda a: a.name, ) diff --git a/tests/db_functions/window/test_validation.py b/tests/db_functions/window/test_validation.py index 2efc88fdfa..43adde442d 100644 --- a/tests/db_functions/window/test_validation.py +++ b/tests/db_functions/window/test_validation.py @@ -4,36 +4,36 @@ from django.test import SimpleTestCase class ValidationTests(SimpleTestCase): def test_nth_negative_nth_value(self): - msg = 'NthValue requires a positive integer as for nth' + msg = "NthValue requires a positive integer as for nth" with self.assertRaisesMessage(ValueError, msg): - NthValue(expression='salary', nth=-1) + NthValue(expression="salary", nth=-1) def test_nth_null_expression(self): - msg = 'NthValue requires a non-null source expression' + msg = "NthValue requires a non-null source expression" with self.assertRaisesMessage(ValueError, msg): NthValue(expression=None) def test_lag_negative_offset(self): - msg = 'Lag requires a positive integer for the offset' + msg = "Lag requires a positive integer for the offset" with self.assertRaisesMessage(ValueError, msg): - Lag(expression='salary', offset=-1) + Lag(expression="salary", offset=-1) def test_lead_negative_offset(self): - msg = 'Lead requires a positive integer for the offset' + msg = "Lead requires a positive integer for the offset" with self.assertRaisesMessage(ValueError, msg): - Lead(expression='salary', offset=-1) + Lead(expression="salary", offset=-1) def test_null_source_lead(self): - msg = 'Lead requires a non-null source expression' + msg = "Lead requires a non-null source expression" with self.assertRaisesMessage(ValueError, msg): Lead(expression=None) def test_null_source_lag(self): - msg = 'Lag requires a non-null source expression' + msg = "Lag requires a non-null source expression" with self.assertRaisesMessage(ValueError, msg): Lag(expression=None) def test_negative_num_buckets_ntile(self): - msg = 'num_buckets must be greater than 0' + msg = "num_buckets must be greater than 0" with self.assertRaisesMessage(ValueError, msg): Ntile(num_buckets=-1) |