summaryrefslogtreecommitdiff
path: root/tests/backends/sqlite
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2017-02-11 21:37:49 +0100
committerTim Graham <timograham@gmail.com>2017-06-21 12:00:47 -0400
commit8cb1b1fd8e529d1896daeb089ea726109e0ba4f7 (patch)
tree3337abead0afac6a46b0ccfd48bc530aec3717de /tests/backends/sqlite
parent0f91ba1adc037345474749faa64d36a4077b3fb8 (diff)
Reorganized backends tests.
Diffstat (limited to 'tests/backends/sqlite')
-rw-r--r--tests/backends/sqlite/__init__.py0
-rw-r--r--tests/backends/sqlite/tests.py138
2 files changed, 138 insertions, 0 deletions
diff --git a/tests/backends/sqlite/__init__.py b/tests/backends/sqlite/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/backends/sqlite/__init__.py
diff --git a/tests/backends/sqlite/tests.py b/tests/backends/sqlite/tests.py
new file mode 100644
index 0000000000..838835ccdd
--- /dev/null
+++ b/tests/backends/sqlite/tests.py
@@ -0,0 +1,138 @@
+import re
+import threading
+import unittest
+
+from django.core.exceptions import ImproperlyConfigured
+from django.db import connection
+from django.db.models import Avg, StdDev, Sum, Variance
+from django.test import (
+ TestCase, TransactionTestCase, override_settings, skipUnlessDBFeature,
+)
+
+from ..models import Item, Object, Square
+
+
+@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
+class Tests(TestCase):
+ longMessage = True
+
+ def test_autoincrement(self):
+ """
+ auto_increment fields are created with the AUTOINCREMENT keyword
+ in order to be monotonically increasing (#10164).
+ """
+ with connection.schema_editor(collect_sql=True) as editor:
+ editor.create_model(Square)
+ statements = editor.collected_sql
+ match = re.search('"id" ([^,]+),', statements[0])
+ self.assertIsNotNone(match)
+ self.assertEqual(
+ 'integer NOT NULL PRIMARY KEY AUTOINCREMENT',
+ match.group(1),
+ 'Wrong SQL used to create an auto-increment column on SQLite'
+ )
+
+ def test_aggregation(self):
+ """
+ Raise NotImplementedError when aggregating on date/time fields (#19360).
+ """
+ for aggregate in (Sum, Avg, Variance, StdDev):
+ with self.assertRaises(NotImplementedError):
+ Item.objects.all().aggregate(aggregate('time'))
+ with self.assertRaises(NotImplementedError):
+ Item.objects.all().aggregate(aggregate('date'))
+ with self.assertRaises(NotImplementedError):
+ Item.objects.all().aggregate(aggregate('last_modified'))
+ with self.assertRaises(NotImplementedError):
+ Item.objects.all().aggregate(
+ **{'complex': aggregate('last_modified') + aggregate('last_modified')}
+ )
+
+ 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',
+ }
+ }
+ wrapper = DatabaseWrapper(settings_dict)
+ creation = wrapper.creation
+ if creation.connection.features.can_share_in_memory_db:
+ expected = creation.connection.settings_dict['TEST']['NAME']
+ self.assertEqual(creation._get_test_db_name(), expected)
+ else:
+ msg = (
+ "Using a shared memory database with `mode=memory` in the "
+ "database name is not supported in your environment, "
+ "use `:memory:` instead."
+ )
+ with self.assertRaisesMessage(ImproperlyConfigured, msg):
+ creation._get_test_db_name()
+
+
+@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');"
+ connection.cursor().execute(query)
+ self.assertEqual(connection.queries[-1]['sql'], query)
+
+ def test_parameter_quoting(self):
+ # The implementation of last_executed_queries isn't optimal. It's
+ # worth testing that parameters are quoted (#14091).
+ query = "SELECT %s"
+ params = ["\"'\\"]
+ connection.cursor().execute(query, params)
+ # Note that the single quote is repeated
+ substituted = "SELECT '\"''\\'"
+ 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
+ # greater than SQLITE_MAX_COLUMN (default = 2000), last_executed_query
+ # can hit the SQLITE_MAX_COLUMN limit (#26063).
+ cursor = connection.cursor()
+ sql = "SELECT MAX(%s)" % ", ".join(["%s"] * 2001)
+ params = list(range(2001))
+ # This should not raise an exception.
+ cursor.db.ops.last_executed_query(cursor.cursor, sql, params)
+
+
+@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).
+ cursor = connection.cursor()
+ cursor.execute("select strftime('%s', date('now'))")
+ response = cursor.fetchall()[0][0]
+ # response should be an non-zero integer
+ self.assertTrue(int(response))
+
+
+@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
+@override_settings(DEBUG=True)
+class EscapingChecksDebug(EscapingChecks):
+ pass
+
+
+@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
+@skipUnlessDBFeature('can_share_in_memory_db')
+class ThreadSharing(TransactionTestCase):
+ 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()
+ thread.join()
+ self.assertEqual(Object.objects.count(), 2)