summaryrefslogtreecommitdiff
path: root/tests/backends/sqlite/tests.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/backends/sqlite/tests.py')
-rw-r--r--tests/backends/sqlite/tests.py116
1 files changed, 67 insertions, 49 deletions
diff --git a/tests/backends/sqlite/tests.py b/tests/backends/sqlite/tests.py
index 07477a5c71..e167e09dcf 100644
--- a/tests/backends/sqlite/tests.py
+++ b/tests/backends/sqlite/tests.py
@@ -12,7 +12,10 @@ from django.db import NotSupportedError, connection, transaction
from django.db.models import Aggregate, Avg, CharField, StdDev, Sum, Variance
from django.db.utils import ConnectionHandler
from django.test import (
- TestCase, TransactionTestCase, override_settings, skipIfDBFeature,
+ TestCase,
+ TransactionTestCase,
+ override_settings,
+ skipIfDBFeature,
)
from django.test.utils import isolate_apps
@@ -25,35 +28,43 @@ except ImproperlyConfigured:
pass
-@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
+@unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
class Tests(TestCase):
longMessage = True
def test_check_sqlite_version(self):
- msg = 'SQLite 3.9.0 or later is required (found 3.8.11.1).'
- with mock.patch.object(dbapi2, 'sqlite_version_info', (3, 8, 11, 1)), \
- mock.patch.object(dbapi2, 'sqlite_version', '3.8.11.1'), \
- self.assertRaisesMessage(ImproperlyConfigured, msg):
+ msg = "SQLite 3.9.0 or later is required (found 3.8.11.1)."
+ with mock.patch.object(
+ dbapi2, "sqlite_version_info", (3, 8, 11, 1)
+ ), mock.patch.object(
+ dbapi2, "sqlite_version", "3.8.11.1"
+ ), self.assertRaisesMessage(
+ ImproperlyConfigured, msg
+ ):
check_sqlite_version()
def test_aggregation(self):
"""Raise NotSupportedError when aggregating on date/time fields."""
for aggregate in (Sum, Avg, Variance, StdDev):
with self.assertRaises(NotSupportedError):
- Item.objects.all().aggregate(aggregate('time'))
+ Item.objects.all().aggregate(aggregate("time"))
with self.assertRaises(NotSupportedError):
- Item.objects.all().aggregate(aggregate('date'))
+ Item.objects.all().aggregate(aggregate("date"))
with self.assertRaises(NotSupportedError):
- Item.objects.all().aggregate(aggregate('last_modified'))
+ Item.objects.all().aggregate(aggregate("last_modified"))
with self.assertRaises(NotSupportedError):
Item.objects.all().aggregate(
- **{'complex': aggregate('last_modified') + aggregate('last_modified')}
+ **{
+ "complex": aggregate("last_modified")
+ + aggregate("last_modified")
+ }
)
def test_distinct_aggregation(self):
class DistinctAggregate(Aggregate):
allow_distinct = True
- aggregate = DistinctAggregate('first', 'second', distinct=True)
+
+ aggregate = DistinctAggregate("first", "second", distinct=True)
msg = (
"SQLite doesn't support DISTINCT on aggregate functions accepting "
"multiple arguments."
@@ -67,32 +78,36 @@ class Tests(TestCase):
class DistinctAggregate(Aggregate):
allow_distinct = True
- aggregate = DistinctAggregate('first', 'second', distinct=False)
+ aggregate = DistinctAggregate("first", "second", distinct=False)
connection.ops.check_expression_support(aggregate)
def test_memory_db_test_name(self):
"""A named in-memory db should be allowed where supported."""
from django.db.backends.sqlite3.base import DatabaseWrapper
+
settings_dict = {
- 'TEST': {
- 'NAME': 'file:memorydb_test?mode=memory&cache=shared',
+ "TEST": {
+ "NAME": "file:memorydb_test?mode=memory&cache=shared",
}
}
creation = DatabaseWrapper(settings_dict).creation
- self.assertEqual(creation._get_test_db_name(), creation.connection.settings_dict['TEST']['NAME'])
+ self.assertEqual(
+ creation._get_test_db_name(),
+ creation.connection.settings_dict["TEST"]["NAME"],
+ )
def test_regexp_function(self):
tests = (
- ('test', r'[0-9]+', False),
- ('test', r'[a-z]+', True),
- ('test', None, None),
- (None, r'[a-z]+', None),
+ ("test", r"[0-9]+", False),
+ ("test", r"[a-z]+", True),
+ ("test", None, None),
+ (None, r"[a-z]+", None),
(None, None, None),
)
for string, pattern, expected in tests:
with self.subTest((string, pattern)):
with connection.cursor() as cursor:
- cursor.execute('SELECT %s REGEXP %s', [string, pattern])
+ cursor.execute("SELECT %s REGEXP %s", [string, pattern])
value = cursor.fetchone()[0]
value = bool(value) if value in {0, 1} else value
self.assertIs(value, expected)
@@ -100,22 +115,22 @@ class Tests(TestCase):
def test_pathlib_name(self):
with tempfile.TemporaryDirectory() as tmp:
settings_dict = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': Path(tmp) / 'test.db',
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": Path(tmp) / "test.db",
},
}
connections = ConnectionHandler(settings_dict)
- connections['default'].ensure_connection()
- connections['default'].close()
- self.assertTrue(os.path.isfile(os.path.join(tmp, 'test.db')))
+ connections["default"].ensure_connection()
+ connections["default"].close()
+ self.assertTrue(os.path.isfile(os.path.join(tmp, "test.db")))
-@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
-@isolate_apps('backends')
+@unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
+@isolate_apps("backends")
class SchemaTests(TransactionTestCase):
- available_apps = ['backends']
+ available_apps = ["backends"]
def test_autoincrement(self):
"""
@@ -128,9 +143,9 @@ class SchemaTests(TransactionTestCase):
match = re.search('"id" ([^,]+),', statements[0])
self.assertIsNotNone(match)
self.assertEqual(
- 'integer NOT NULL PRIMARY KEY AUTOINCREMENT',
+ "integer NOT NULL PRIMARY KEY AUTOINCREMENT",
match[1],
- 'Wrong SQL used to create an auto-increment column on SQLite'
+ "Wrong SQL used to create an auto-increment column on SQLite",
)
def test_disable_constraint_checking_failure_disallowed(self):
@@ -139,11 +154,11 @@ class SchemaTests(TransactionTestCase):
foreign key constraint checks are not disabled beforehand.
"""
msg = (
- 'SQLite schema editor cannot be used while foreign key '
- 'constraint checks are enabled. Make sure to disable them '
- 'before entering a transaction.atomic() context because '
- 'SQLite does not support disabling them in the middle of '
- 'a multi-statement transaction.'
+ "SQLite schema editor cannot be used while foreign key "
+ "constraint checks are enabled. Make sure to disable them "
+ "before entering a transaction.atomic() context because "
+ "SQLite does not support disabling them in the middle of "
+ "a multi-statement transaction."
)
with self.assertRaisesMessage(NotSupportedError, msg):
with transaction.atomic(), connection.schema_editor(atomic=True):
@@ -154,23 +169,25 @@ class SchemaTests(TransactionTestCase):
SQLite schema editor is usable within an outer transaction as long as
foreign key constraints checks are disabled beforehand.
"""
+
def constraint_checks_enabled():
with connection.cursor() as cursor:
- return bool(cursor.execute('PRAGMA foreign_keys').fetchone()[0])
+ return bool(cursor.execute("PRAGMA foreign_keys").fetchone()[0])
+
with connection.constraint_checks_disabled(), transaction.atomic():
with connection.schema_editor(atomic=True):
self.assertFalse(constraint_checks_enabled())
self.assertFalse(constraint_checks_enabled())
self.assertTrue(constraint_checks_enabled())
- @skipIfDBFeature('supports_atomic_references_rename')
+ @skipIfDBFeature("supports_atomic_references_rename")
def test_field_rename_inside_atomic_block(self):
"""
NotImplementedError is raised when a model field rename is attempted
inside an atomic block.
"""
new_field = CharField(max_length=255, unique=True)
- new_field.set_attributes_from_name('renamed')
+ new_field.set_attributes_from_name("renamed")
msg = (
"Renaming the 'backends_author'.'name' column while in a "
"transaction is not supported on SQLite < 3.26 because it would "
@@ -179,9 +196,9 @@ class SchemaTests(TransactionTestCase):
)
with self.assertRaisesMessage(NotSupportedError, msg):
with connection.schema_editor(atomic=True) as editor:
- editor.alter_field(Author, Author._meta.get_field('name'), new_field)
+ editor.alter_field(Author, Author._meta.get_field("name"), new_field)
- @skipIfDBFeature('supports_atomic_references_rename')
+ @skipIfDBFeature("supports_atomic_references_rename")
def test_table_rename_inside_atomic_block(self):
"""
NotImplementedError is raised when a table rename is attempted inside
@@ -197,16 +214,15 @@ class SchemaTests(TransactionTestCase):
editor.alter_db_table(Author, "backends_author", "renamed_table")
-@unittest.skipUnless(connection.vendor == 'sqlite', 'Test only for SQLite')
+@unittest.skipUnless(connection.vendor == "sqlite", "Test only for SQLite")
@override_settings(DEBUG=True)
class LastExecutedQueryTest(TestCase):
-
def test_no_interpolation(self):
# This shouldn't raise an exception (#17158)
query = "SELECT strftime('%Y', 'now');"
with connection.cursor() as cursor:
cursor.execute(query)
- self.assertEqual(connection.queries[-1]['sql'], query)
+ self.assertEqual(connection.queries[-1]["sql"], query)
def test_parameter_quoting(self):
# The implementation of last_executed_queries isn't optimal. It's
@@ -217,7 +233,7 @@ class LastExecutedQueryTest(TestCase):
cursor.execute(query, params)
# Note that the single quote is repeated
substituted = "SELECT '\"''\\'"
- self.assertEqual(connection.queries[-1]['sql'], substituted)
+ self.assertEqual(connection.queries[-1]["sql"], substituted)
def test_large_number_of_parameters(self):
# If SQLITE_MAX_VARIABLE_NUMBER (default = 999) has been changed to be
@@ -230,12 +246,13 @@ class LastExecutedQueryTest(TestCase):
cursor.db.ops.last_executed_query(cursor.cursor, sql, params)
-@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
+@unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
class EscapingChecks(TestCase):
"""
All tests in this test case are also run with settings.DEBUG=True in
EscapingChecksDebug test case, to also test CursorDebugWrapper.
"""
+
def test_parameter_escaping(self):
# '%s' escaping support for sqlite3 (#13648).
with connection.cursor() as cursor:
@@ -245,19 +262,20 @@ class EscapingChecks(TestCase):
self.assertTrue(int(response))
-@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
+@unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
@override_settings(DEBUG=True)
class EscapingChecksDebug(EscapingChecks):
pass
-@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
+@unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
class ThreadSharing(TransactionTestCase):
- available_apps = ['backends']
+ available_apps = ["backends"]
def test_database_sharing_in_threads(self):
def create_object():
Object.objects.create()
+
create_object()
thread = threading.Thread(target=create_object)
thread.start()