Refs #33355 -- Added missing tests for database functions and expression on null values.

This commit is contained in:
Adam Johnson 2021-12-10 09:13:09 +00:00 committed by Mariusz Felisiak
parent 78f062f63e
commit a8fa3e5cd7
7 changed files with 22 additions and 0 deletions

View File

@ -85,6 +85,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"Oracle doesn't support bitwise XOR.": { "Oracle doesn't support bitwise XOR.": {
'expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor', 'expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor',
'expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor_null', 'expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor_null',
'expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor_right_null',
}, },
"Oracle requires ORDER BY in row_number, ANSI:SQL doesn't.": { "Oracle requires ORDER BY in row_number, ANSI:SQL doesn't.": {
'expressions_window.tests.WindowFunctionTests.test_row_number_no_ordering', 'expressions_window.tests.WindowFunctionTests.test_row_number_no_ordering',

View File

@ -14,9 +14,11 @@ class ATan2Tests(TestCase):
obj = IntegerModel.objects.annotate( obj = IntegerModel.objects.annotate(
null_atan2_sn=ATan2('small', 'normal'), null_atan2_sn=ATan2('small', 'normal'),
null_atan2_nb=ATan2('normal', 'big'), null_atan2_nb=ATan2('normal', 'big'),
null_atan2_bn=ATan2('big', 'normal'),
).first() ).first()
self.assertIsNone(obj.null_atan2_sn) self.assertIsNone(obj.null_atan2_sn)
self.assertIsNone(obj.null_atan2_nb) self.assertIsNone(obj.null_atan2_nb)
self.assertIsNone(obj.null_atan2_bn)
def test_decimal(self): def test_decimal(self):
DecimalModel.objects.create(n1=Decimal('-9.9'), n2=Decimal('4.6')) DecimalModel.objects.create(n1=Decimal('-9.9'), n2=Decimal('4.6'))

View File

@ -14,9 +14,11 @@ class LogTests(TestCase):
obj = IntegerModel.objects.annotate( obj = IntegerModel.objects.annotate(
null_log_small=Log('small', 'normal'), null_log_small=Log('small', 'normal'),
null_log_normal=Log('normal', 'big'), null_log_normal=Log('normal', 'big'),
null_log_big=Log('big', 'normal'),
).first() ).first()
self.assertIsNone(obj.null_log_small) self.assertIsNone(obj.null_log_small)
self.assertIsNone(obj.null_log_normal) self.assertIsNone(obj.null_log_normal)
self.assertIsNone(obj.null_log_big)
def test_decimal(self): def test_decimal(self):
DecimalModel.objects.create(n1=Decimal('12.9'), n2=Decimal('3.6')) DecimalModel.objects.create(n1=Decimal('12.9'), n2=Decimal('3.6'))

View File

@ -13,9 +13,11 @@ class PowerTests(TestCase):
obj = IntegerModel.objects.annotate( obj = IntegerModel.objects.annotate(
null_power_small=Power('small', 'normal'), null_power_small=Power('small', 'normal'),
null_power_normal=Power('normal', 'big'), null_power_normal=Power('normal', 'big'),
null_power_big=Power('big', 'normal'),
).first() ).first()
self.assertIsNone(obj.null_power_small) self.assertIsNone(obj.null_power_small)
self.assertIsNone(obj.null_power_normal) self.assertIsNone(obj.null_power_normal)
self.assertIsNone(obj.null_power_big)
def test_decimal(self): def test_decimal(self):
DecimalModel.objects.create(n1=Decimal('1.0'), n2=Decimal('-0.6')) DecimalModel.objects.create(n1=Decimal('1.0'), n2=Decimal('-0.6'))

View File

@ -25,6 +25,8 @@ class PadTests(TestCase):
(RPad('name', 0), ''), (RPad('name', 0), ''),
(LPad('name', None), none_value), (LPad('name', None), none_value),
(RPad('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), (LPad('goes_by', 1), none_value),
(RPad('goes_by', 1), none_value), (RPad('goes_by', 1), none_value),
) )

View File

@ -16,6 +16,7 @@ class RepeatTests(TestCase):
(Repeat('name', Length('alias')), 'JohnJohnJohn'), (Repeat('name', Length('alias')), 'JohnJohnJohn'),
(Repeat(Value('x'), 3), 'xxx'), (Repeat(Value('x'), 3), 'xxx'),
(Repeat('name', None), none_value), (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: for function, repeated_text in tests:

View File

@ -1246,6 +1246,12 @@ class ExpressionOperatorTests(TestCase):
Number.objects.filter(pk=self.n.pk).update(integer=F('integer') % 20) Number.objects.filter(pk=self.n.pk).update(integer=F('integer') % 20)
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 2) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 2)
def test_lefthand_modulo_null(self):
# LH Modulo arithmetic on integers.
Employee.objects.create(firstname='John', lastname='Doe', salary=None)
qs = Employee.objects.annotate(modsalary=F('salary') % 20)
self.assertIsNone(qs.get().salary)
def test_lefthand_bitwise_and(self): def test_lefthand_bitwise_and(self):
# LH Bitwise ands on integers # LH Bitwise ands on integers
Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitand(56)) Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitand(56))
@ -1294,6 +1300,12 @@ class ExpressionOperatorTests(TestCase):
employee.refresh_from_db() employee.refresh_from_db()
self.assertIsNone(employee.salary) self.assertIsNone(employee.salary)
def test_lefthand_bitwise_xor_right_null(self):
employee = Employee.objects.create(firstname='John', lastname='Doe', salary=48)
Employee.objects.update(salary=F('salary').bitxor(None))
employee.refresh_from_db()
self.assertIsNone(employee.salary)
@unittest.skipUnless(connection.vendor == 'oracle', "Oracle doesn't support bitwise XOR.") @unittest.skipUnless(connection.vendor == 'oracle', "Oracle doesn't support bitwise XOR.")
def test_lefthand_bitwise_xor_not_supported(self): def test_lefthand_bitwise_xor_not_supported(self):
msg = 'Bitwise XOR is not supported in Oracle.' msg = 'Bitwise XOR is not supported in Oracle.'