test_operations.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import decimal
  2. from django.db import NotSupportedError, connection
  3. from django.db.backends.base.operations import BaseDatabaseOperations
  4. from django.db.models import DurationField
  5. from django.test import (
  6. SimpleTestCase, TestCase, override_settings, skipIfDBFeature,
  7. )
  8. from django.utils import timezone
  9. class SimpleDatabaseOperationTests(SimpleTestCase):
  10. may_requre_msg = 'subclasses of BaseDatabaseOperations may require a %s() method'
  11. def setUp(self):
  12. self.ops = BaseDatabaseOperations(connection=connection)
  13. def test_deferrable_sql(self):
  14. self.assertEqual(self.ops.deferrable_sql(), '')
  15. def test_end_transaction_rollback(self):
  16. self.assertEqual(self.ops.end_transaction_sql(success=False), 'ROLLBACK;')
  17. def test_no_limit_value(self):
  18. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'no_limit_value'):
  19. self.ops.no_limit_value()
  20. def test_quote_name(self):
  21. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'quote_name'):
  22. self.ops.quote_name('a')
  23. def test_regex_lookup(self):
  24. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'regex_lookup'):
  25. self.ops.regex_lookup(lookup_type='regex')
  26. def test_set_time_zone_sql(self):
  27. self.assertEqual(self.ops.set_time_zone_sql(), '')
  28. def test_sql_flush(self):
  29. msg = 'subclasses of BaseDatabaseOperations must provide a sql_flush() method'
  30. with self.assertRaisesMessage(NotImplementedError, msg):
  31. self.ops.sql_flush(None, None, None)
  32. def test_pk_default_value(self):
  33. self.assertEqual(self.ops.pk_default_value(), 'DEFAULT')
  34. def test_tablespace_sql(self):
  35. self.assertEqual(self.ops.tablespace_sql(None), '')
  36. def test_sequence_reset_by_name_sql(self):
  37. self.assertEqual(self.ops.sequence_reset_by_name_sql(None, []), [])
  38. def test_adapt_unknown_value_decimal(self):
  39. value = decimal.Decimal('3.14')
  40. self.assertEqual(
  41. self.ops.adapt_unknown_value(value),
  42. self.ops.adapt_decimalfield_value(value)
  43. )
  44. def test_adapt_unknown_value_date(self):
  45. value = timezone.now().date()
  46. self.assertEqual(self.ops.adapt_unknown_value(value), self.ops.adapt_datefield_value(value))
  47. def test_adapt_unknown_value_time(self):
  48. value = timezone.now().time()
  49. self.assertEqual(self.ops.adapt_unknown_value(value), self.ops.adapt_timefield_value(value))
  50. def test_adapt_timefield_value_none(self):
  51. self.assertIsNone(self.ops.adapt_timefield_value(None))
  52. def test_adapt_datetimefield_value(self):
  53. self.assertIsNone(self.ops.adapt_datetimefield_value(None))
  54. def test_adapt_timefield_value(self):
  55. msg = 'Django does not support timezone-aware times.'
  56. with self.assertRaisesMessage(ValueError, msg):
  57. self.ops.adapt_timefield_value(timezone.make_aware(timezone.now()))
  58. @override_settings(USE_TZ=False)
  59. def test_adapt_timefield_value_unaware(self):
  60. now = timezone.now()
  61. self.assertEqual(self.ops.adapt_timefield_value(now), str(now))
  62. def test_date_extract_sql(self):
  63. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'date_extract_sql'):
  64. self.ops.date_extract_sql(None, None)
  65. def test_time_extract_sql(self):
  66. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'date_extract_sql'):
  67. self.ops.time_extract_sql(None, None)
  68. def test_date_interval_sql(self):
  69. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'date_interval_sql'):
  70. self.ops.date_interval_sql(None)
  71. def test_date_trunc_sql(self):
  72. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'date_trunc_sql'):
  73. self.ops.date_trunc_sql(None, None)
  74. def test_time_trunc_sql(self):
  75. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'time_trunc_sql'):
  76. self.ops.time_trunc_sql(None, None)
  77. def test_datetime_trunc_sql(self):
  78. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'datetime_trunc_sql'):
  79. self.ops.datetime_trunc_sql(None, None, None)
  80. def test_datetime_cast_date_sql(self):
  81. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'datetime_cast_date_sql'):
  82. self.ops.datetime_cast_date_sql(None, None)
  83. def test_datetime_cast_time_sql(self):
  84. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'datetime_cast_time_sql'):
  85. self.ops.datetime_cast_time_sql(None, None)
  86. def test_datetime_extract_sql(self):
  87. with self.assertRaisesMessage(NotImplementedError, self.may_requre_msg % 'datetime_extract_sql'):
  88. self.ops.datetime_extract_sql(None, None, None)
  89. class DatabaseOperationTests(TestCase):
  90. def setUp(self):
  91. self.ops = BaseDatabaseOperations(connection=connection)
  92. @skipIfDBFeature('supports_over_clause')
  93. def test_window_frame_raise_not_supported_error(self):
  94. msg = 'This backend does not support window expressions.'
  95. with self.assertRaisesMessage(NotSupportedError, msg):
  96. self.ops.window_frame_rows_start_end()
  97. @skipIfDBFeature('can_distinct_on_fields')
  98. def test_distinct_on_fields(self):
  99. msg = 'DISTINCT ON fields is not supported by this database backend'
  100. with self.assertRaisesMessage(NotSupportedError, msg):
  101. self.ops.distinct_sql(['a', 'b'], None)
  102. @skipIfDBFeature('supports_temporal_subtraction')
  103. def test_subtract_temporals(self):
  104. duration_field = DurationField()
  105. duration_field_internal_type = duration_field.get_internal_type()
  106. msg = (
  107. 'This backend does not support %s subtraction.' %
  108. duration_field_internal_type
  109. )
  110. with self.assertRaisesMessage(NotSupportedError, msg):
  111. self.ops.subtract_temporals(duration_field_internal_type, None, None)