blob: 7867bf361e5ac6f659f7495e49b29ff63f9d7f99 [file] [log] [blame]
Petri Lehtinenf8547992012-02-02 17:17:36 +02001#-*- coding: iso-8859-1 -*-
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002# pysqlite2/test/dbapi.py: tests for DB-API compliance
3#
Gerhard Häringf9cee222010-03-05 15:20:03 +00004# Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005#
6# This file is part of pysqlite.
7#
8# This software is provided 'as-is', without any express or implied
9# warranty. In no event will the authors be held liable for any damages
10# arising from the use of this software.
11#
12# Permission is granted to anyone to use this software for any purpose,
13# including commercial applications, and to alter it and redistribute it
14# freely, subject to the following restrictions:
15#
16# 1. The origin of this software must not be misrepresented; you must not
17# claim that you wrote the original software. If you use this software
18# in a product, an acknowledgment in the product documentation would be
19# appreciated but is not required.
20# 2. Altered source versions must be plainly marked as such, and must not be
21# misrepresented as being the original software.
22# 3. This notice may not be removed or altered from any source distribution.
23
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020024import threading
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000025import unittest
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000026import sqlite3 as sqlite
27
Hai Shifcce8c62020-08-08 05:55:35 +080028from test.support.os_helper import TESTFN, unlink
Antoine Pitrou902fc8b2013-02-10 00:02:44 +010029
30
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000031class ModuleTests(unittest.TestCase):
32 def CheckAPILevel(self):
33 self.assertEqual(sqlite.apilevel, "2.0",
34 "apilevel is %s, should be 2.0" % sqlite.apilevel)
35
36 def CheckThreadSafety(self):
37 self.assertEqual(sqlite.threadsafety, 1,
38 "threadsafety is %d, should be 1" % sqlite.threadsafety)
39
40 def CheckParamStyle(self):
41 self.assertEqual(sqlite.paramstyle, "qmark",
42 "paramstyle is '%s', should be 'qmark'" %
43 sqlite.paramstyle)
44
45 def CheckWarning(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000046 self.assertTrue(issubclass(sqlite.Warning, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000047 "Warning is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000048
49 def CheckError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000050 self.assertTrue(issubclass(sqlite.Error, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000051 "Error is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000052
53 def CheckInterfaceError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000054 self.assertTrue(issubclass(sqlite.InterfaceError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000055 "InterfaceError is not a subclass of Error")
56
57 def CheckDatabaseError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000058 self.assertTrue(issubclass(sqlite.DatabaseError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000059 "DatabaseError is not a subclass of Error")
60
61 def CheckDataError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000062 self.assertTrue(issubclass(sqlite.DataError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000063 "DataError is not a subclass of DatabaseError")
64
65 def CheckOperationalError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000066 self.assertTrue(issubclass(sqlite.OperationalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000067 "OperationalError is not a subclass of DatabaseError")
68
69 def CheckIntegrityError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000070 self.assertTrue(issubclass(sqlite.IntegrityError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000071 "IntegrityError is not a subclass of DatabaseError")
72
73 def CheckInternalError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000074 self.assertTrue(issubclass(sqlite.InternalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000075 "InternalError is not a subclass of DatabaseError")
76
77 def CheckProgrammingError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000078 self.assertTrue(issubclass(sqlite.ProgrammingError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000079 "ProgrammingError is not a subclass of DatabaseError")
80
81 def CheckNotSupportedError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000082 self.assertTrue(issubclass(sqlite.NotSupportedError,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000083 sqlite.DatabaseError),
84 "NotSupportedError is not a subclass of DatabaseError")
85
86class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +000087
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000088 def setUp(self):
89 self.cx = sqlite.connect(":memory:")
90 cu = self.cx.cursor()
91 cu.execute("create table test(id integer primary key, name text)")
92 cu.execute("insert into test(name) values (?)", ("foo",))
93
94 def tearDown(self):
95 self.cx.close()
96
97 def CheckCommit(self):
98 self.cx.commit()
99
100 def CheckCommitAfterNoChanges(self):
101 """
102 A commit should also work when no changes were made to the database.
103 """
104 self.cx.commit()
105 self.cx.commit()
106
107 def CheckRollback(self):
108 self.cx.rollback()
109
110 def CheckRollbackAfterNoChanges(self):
111 """
112 A rollback should also work when no changes were made to the database.
113 """
114 self.cx.rollback()
115 self.cx.rollback()
116
117 def CheckCursor(self):
118 cu = self.cx.cursor()
119
120 def CheckFailedOpen(self):
121 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
Berker Peksag1003b342016-06-12 22:34:49 +0300122 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000123 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000124
125 def CheckClose(self):
126 self.cx.close()
127
128 def CheckExceptions(self):
129 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000130 self.assertEqual(self.cx.Warning, sqlite.Warning)
131 self.assertEqual(self.cx.Error, sqlite.Error)
132 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
133 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
134 self.assertEqual(self.cx.DataError, sqlite.DataError)
135 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
136 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
137 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
138 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
139 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000140
R. David Murrayd35251d2010-06-01 01:32:12 +0000141 def CheckInTransaction(self):
142 # Can't use db from setUp because we want to test initial state.
143 cx = sqlite.connect(":memory:")
144 cu = cx.cursor()
145 self.assertEqual(cx.in_transaction, False)
146 cu.execute("create table transactiontest(id integer primary key, name text)")
147 self.assertEqual(cx.in_transaction, False)
148 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
149 self.assertEqual(cx.in_transaction, True)
150 cu.execute("select name from transactiontest where name=?", ["foo"])
151 row = cu.fetchone()
152 self.assertEqual(cx.in_transaction, True)
153 cx.commit()
154 self.assertEqual(cx.in_transaction, False)
155 cu.execute("select name from transactiontest where name=?", ["foo"])
156 row = cu.fetchone()
157 self.assertEqual(cx.in_transaction, False)
158
159 def CheckInTransactionRO(self):
160 with self.assertRaises(AttributeError):
161 self.cx.in_transaction = True
162
Anders Lorentsena22a1272017-11-07 01:47:43 +0100163 def CheckOpenWithPathLikeObject(self):
Ville Skyttä61f82e02018-04-20 23:08:45 +0300164 """ Checks that we can successfully connect to a database using an object that
Anders Lorentsena22a1272017-11-07 01:47:43 +0100165 is PathLike, i.e. has __fspath__(). """
166 self.addCleanup(unlink, TESTFN)
167 class Path:
168 def __fspath__(self):
169 return TESTFN
170 path = Path()
171 with sqlite.connect(path) as cx:
172 cx.execute('create table test(id integer)')
173
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100174 def CheckOpenUri(self):
175 if sqlite.sqlite_version_info < (3, 7, 7):
176 with self.assertRaises(sqlite.NotSupportedError):
177 sqlite.connect(':memory:', uri=True)
178 return
179 self.addCleanup(unlink, TESTFN)
180 with sqlite.connect(TESTFN) as cx:
181 cx.execute('create table test(id integer)')
182 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
183 cx.execute('insert into test(id) values(0)')
184 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
185 with self.assertRaises(sqlite.OperationalError):
186 cx.execute('insert into test(id) values(1)')
187
188
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000189class CursorTests(unittest.TestCase):
190 def setUp(self):
191 self.cx = sqlite.connect(":memory:")
192 self.cu = self.cx.cursor()
Berker Peksage0b70cd2016-06-14 15:25:36 +0300193 self.cu.execute(
194 "create table test(id integer primary key, name text, "
195 "income number, unique_test text unique)"
196 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000197 self.cu.execute("insert into test(name) values (?)", ("foo",))
198
199 def tearDown(self):
200 self.cu.close()
201 self.cx.close()
202
203 def CheckExecuteNoArgs(self):
204 self.cu.execute("delete from test")
205
206 def CheckExecuteIllegalSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300207 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000208 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000209
210 def CheckExecuteTooMuchSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300211 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000212 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000213
214 def CheckExecuteTooMuchSql2(self):
215 self.cu.execute("select 5+4; -- foo bar")
216
217 def CheckExecuteTooMuchSql3(self):
218 self.cu.execute("""
219 select 5+4;
220
221 /*
222 foo
223 */
224 """)
225
226 def CheckExecuteWrongSqlArg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200227 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000228 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000229
230 def CheckExecuteArgInt(self):
231 self.cu.execute("insert into test(id) values (?)", (42,))
232
233 def CheckExecuteArgFloat(self):
234 self.cu.execute("insert into test(income) values (?)", (2500.32,))
235
236 def CheckExecuteArgString(self):
237 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
238
Petri Lehtinen023fe332012-02-01 22:18:19 +0200239 def CheckExecuteArgStringWithZeroByte(self):
240 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
241
242 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
243 row = self.cu.fetchone()
244 self.assertEqual(row[0], "Hu\x00go")
245
Berker Peksagc4154402016-06-12 13:41:47 +0300246 def CheckExecuteNonIterable(self):
247 with self.assertRaises(ValueError) as cm:
248 self.cu.execute("insert into test(id) values (?)", 42)
249 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
250
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000251 def CheckExecuteWrongNoOfArgs1(self):
252 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300253 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000254 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255
256 def CheckExecuteWrongNoOfArgs2(self):
257 # too little parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300258 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000259 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
261 def CheckExecuteWrongNoOfArgs3(self):
262 # no parameters, parameters are needed
Berker Peksag1003b342016-06-12 22:34:49 +0300263 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000264 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000265
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000266 def CheckExecuteParamList(self):
267 self.cu.execute("insert into test(name) values ('foo')")
268 self.cu.execute("select name from test where name=?", ["foo"])
269 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000270 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000271
272 def CheckExecuteParamSequence(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300273 class L:
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000274 def __len__(self):
275 return 1
276 def __getitem__(self, x):
277 assert x == 0
278 return "foo"
279
280 self.cu.execute("insert into test(name) values ('foo')")
281 self.cu.execute("select name from test where name=?", L())
282 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000283 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000284
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300285 def CheckExecuteParamSequenceBadLen(self):
286 # Issue41662: Error in __len__() was overridden with ProgrammingError.
287 class L:
288 def __len__(self):
289 1/0
290 def __getitem__(slf, x):
291 raise AssertionError
292
293 self.cu.execute("insert into test(name) values ('foo')")
294 with self.assertRaises(ZeroDivisionError):
295 self.cu.execute("select name from test where name=?", L())
296
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000297 def CheckExecuteDictMapping(self):
298 self.cu.execute("insert into test(name) values ('foo')")
299 self.cu.execute("select name from test where name=:name", {"name": "foo"})
300 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000301 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000302
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000303 def CheckExecuteDictMapping_Mapping(self):
304 class D(dict):
305 def __missing__(self, key):
306 return "foo"
307
308 self.cu.execute("insert into test(name) values ('foo')")
309 self.cu.execute("select name from test where name=:name", D())
310 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000311 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000312
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313 def CheckExecuteDictMappingTooLittleArgs(self):
314 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300315 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000316 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000317
318 def CheckExecuteDictMappingNoArgs(self):
319 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300320 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000321 self.cu.execute("select name from test where name=:name")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000322
323 def CheckExecuteDictMappingUnnamed(self):
324 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300325 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000326 self.cu.execute("select name from test where name=?", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000327
328 def CheckClose(self):
329 self.cu.close()
330
331 def CheckRowcountExecute(self):
332 self.cu.execute("delete from test")
333 self.cu.execute("insert into test(name) values ('foo')")
334 self.cu.execute("insert into test(name) values ('foo')")
335 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000336 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000337
Georg Brandlf78e02b2008-06-10 17:40:04 +0000338 def CheckRowcountSelect(self):
339 """
340 pysqlite does not know the rowcount of SELECT statements, because we
341 don't fetch all rows after executing the select statement. The rowcount
342 has thus to be -1.
343 """
344 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000345 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000346
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000347 def CheckRowcountExecutemany(self):
348 self.cu.execute("delete from test")
349 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000350 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000351
352 def CheckTotalChanges(self):
353 self.cu.execute("insert into test(name) values ('foo')")
354 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300355 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000356
357 # Checks for executemany:
358 # Sequences are required by the DB-API, iterators
359 # enhancements in pysqlite.
360
361 def CheckExecuteManySequence(self):
362 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
363
364 def CheckExecuteManyIterator(self):
365 class MyIter:
366 def __init__(self):
367 self.value = 5
368
Georg Brandla18af4e2007-04-21 15:47:16 +0000369 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000370 if self.value == 10:
371 raise StopIteration
372 else:
373 self.value += 1
374 return (self.value,)
375
376 self.cu.executemany("insert into test(income) values (?)", MyIter())
377
378 def CheckExecuteManyGenerator(self):
379 def mygen():
380 for i in range(5):
381 yield (i,)
382
383 self.cu.executemany("insert into test(income) values (?)", mygen())
384
385 def CheckExecuteManyWrongSqlArg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200386 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000387 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000388
389 def CheckExecuteManySelect(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300390 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000391 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000392
393 def CheckExecuteManyNotIterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300394 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000395 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000396
397 def CheckFetchIter(self):
398 # Optional DB-API extension.
399 self.cu.execute("delete from test")
400 self.cu.execute("insert into test(id) values (?)", (5,))
401 self.cu.execute("insert into test(id) values (?)", (6,))
402 self.cu.execute("select id from test order by id")
403 lst = []
404 for row in self.cu:
405 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000406 self.assertEqual(lst[0], 5)
407 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000408
409 def CheckFetchone(self):
410 self.cu.execute("select name from test")
411 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000412 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000413 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000414 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000415
416 def CheckFetchoneNoStatement(self):
417 cur = self.cx.cursor()
418 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000419 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000420
421 def CheckArraySize(self):
422 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000423 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000424
425 # now set to 2
426 self.cu.arraysize = 2
427
428 # now make the query return 3 rows
429 self.cu.execute("delete from test")
430 self.cu.execute("insert into test(name) values ('A')")
431 self.cu.execute("insert into test(name) values ('B')")
432 self.cu.execute("insert into test(name) values ('C')")
433 self.cu.execute("select name from test")
434 res = self.cu.fetchmany()
435
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000436 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000437
438 def CheckFetchmany(self):
439 self.cu.execute("select name from test")
440 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000441 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000442 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000443 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000444
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000445 def CheckFetchmanyKwArg(self):
446 """Checks if fetchmany works with keyword arguments"""
447 self.cu.execute("select name from test")
448 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000449 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000450
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000451 def CheckFetchall(self):
452 self.cu.execute("select name from test")
453 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000454 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000455 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000456 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000457
458 def CheckSetinputsizes(self):
459 self.cu.setinputsizes([3, 4, 5])
460
461 def CheckSetoutputsize(self):
462 self.cu.setoutputsize(5, 0)
463
464 def CheckSetoutputsizeNoColumn(self):
465 self.cu.setoutputsize(42)
466
467 def CheckCursorConnection(self):
468 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000469 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000470
471 def CheckWrongCursorCallable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300472 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000473 def f(): pass
474 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000475
476 def CheckCursorWrongClass(self):
477 class Foo: pass
478 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300479 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000480 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481
Berker Peksage0b70cd2016-06-14 15:25:36 +0300482 def CheckLastRowIDOnReplace(self):
483 """
484 INSERT OR REPLACE and REPLACE INTO should produce the same behavior.
485 """
486 sql = '{} INTO test(id, unique_test) VALUES (?, ?)'
487 for statement in ('INSERT OR REPLACE', 'REPLACE'):
488 with self.subTest(statement=statement):
489 self.cu.execute(sql.format(statement), (1, 'foo'))
490 self.assertEqual(self.cu.lastrowid, 1)
491
492 def CheckLastRowIDOnIgnore(self):
493 self.cu.execute(
494 "insert or ignore into test(unique_test) values (?)",
495 ('test',))
496 self.assertEqual(self.cu.lastrowid, 2)
497 self.cu.execute(
498 "insert or ignore into test(unique_test) values (?)",
499 ('test',))
500 self.assertEqual(self.cu.lastrowid, 2)
501
502 def CheckLastRowIDInsertOR(self):
503 results = []
504 for statement in ('FAIL', 'ABORT', 'ROLLBACK'):
505 sql = 'INSERT OR {} INTO test(unique_test) VALUES (?)'
506 with self.subTest(statement='INSERT OR {}'.format(statement)):
507 self.cu.execute(sql.format(statement), (statement,))
508 results.append((statement, self.cu.lastrowid))
509 with self.assertRaises(sqlite.IntegrityError):
510 self.cu.execute(sql.format(statement), (statement,))
511 results.append((statement, self.cu.lastrowid))
512 expected = [
513 ('FAIL', 2), ('FAIL', 2),
514 ('ABORT', 3), ('ABORT', 3),
515 ('ROLLBACK', 4), ('ROLLBACK', 4),
516 ]
517 self.assertEqual(results, expected)
518
519
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000520class ThreadTests(unittest.TestCase):
521 def setUp(self):
522 self.con = sqlite.connect(":memory:")
523 self.cur = self.con.cursor()
524 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
525
526 def tearDown(self):
527 self.cur.close()
528 self.con.close()
529
530 def CheckConCursor(self):
531 def run(con, errors):
532 try:
533 cur = con.cursor()
534 errors.append("did not raise ProgrammingError")
535 return
536 except sqlite.ProgrammingError:
537 return
538 except:
539 errors.append("raised wrong exception")
540
541 errors = []
542 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
543 t.start()
544 t.join()
545 if len(errors) > 0:
546 self.fail("\n".join(errors))
547
548 def CheckConCommit(self):
549 def run(con, errors):
550 try:
551 con.commit()
552 errors.append("did not raise ProgrammingError")
553 return
554 except sqlite.ProgrammingError:
555 return
556 except:
557 errors.append("raised wrong exception")
558
559 errors = []
560 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
561 t.start()
562 t.join()
563 if len(errors) > 0:
564 self.fail("\n".join(errors))
565
566 def CheckConRollback(self):
567 def run(con, errors):
568 try:
569 con.rollback()
570 errors.append("did not raise ProgrammingError")
571 return
572 except sqlite.ProgrammingError:
573 return
574 except:
575 errors.append("raised wrong exception")
576
577 errors = []
578 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
579 t.start()
580 t.join()
581 if len(errors) > 0:
582 self.fail("\n".join(errors))
583
584 def CheckConClose(self):
585 def run(con, errors):
586 try:
587 con.close()
588 errors.append("did not raise ProgrammingError")
589 return
590 except sqlite.ProgrammingError:
591 return
592 except:
593 errors.append("raised wrong exception")
594
595 errors = []
596 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
597 t.start()
598 t.join()
599 if len(errors) > 0:
600 self.fail("\n".join(errors))
601
602 def CheckCurImplicitBegin(self):
603 def run(cur, errors):
604 try:
605 cur.execute("insert into test(name) values ('a')")
606 errors.append("did not raise ProgrammingError")
607 return
608 except sqlite.ProgrammingError:
609 return
610 except:
611 errors.append("raised wrong exception")
612
613 errors = []
614 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
615 t.start()
616 t.join()
617 if len(errors) > 0:
618 self.fail("\n".join(errors))
619
620 def CheckCurClose(self):
621 def run(cur, errors):
622 try:
623 cur.close()
624 errors.append("did not raise ProgrammingError")
625 return
626 except sqlite.ProgrammingError:
627 return
628 except:
629 errors.append("raised wrong exception")
630
631 errors = []
632 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
633 t.start()
634 t.join()
635 if len(errors) > 0:
636 self.fail("\n".join(errors))
637
638 def CheckCurExecute(self):
639 def run(cur, errors):
640 try:
641 cur.execute("select name from test")
642 errors.append("did not raise ProgrammingError")
643 return
644 except sqlite.ProgrammingError:
645 return
646 except:
647 errors.append("raised wrong exception")
648
649 errors = []
650 self.cur.execute("insert into test(name) values ('a')")
651 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
652 t.start()
653 t.join()
654 if len(errors) > 0:
655 self.fail("\n".join(errors))
656
657 def CheckCurIterNext(self):
658 def run(cur, errors):
659 try:
660 row = cur.fetchone()
661 errors.append("did not raise ProgrammingError")
662 return
663 except sqlite.ProgrammingError:
664 return
665 except:
666 errors.append("raised wrong exception")
667
668 errors = []
669 self.cur.execute("insert into test(name) values ('a')")
670 self.cur.execute("select name from test")
671 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
672 t.start()
673 t.join()
674 if len(errors) > 0:
675 self.fail("\n".join(errors))
676
677class ConstructorTests(unittest.TestCase):
678 def CheckDate(self):
679 d = sqlite.Date(2004, 10, 28)
680
681 def CheckTime(self):
682 t = sqlite.Time(12, 39, 35)
683
684 def CheckTimestamp(self):
685 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
686
687 def CheckDateFromTicks(self):
688 d = sqlite.DateFromTicks(42)
689
690 def CheckTimeFromTicks(self):
691 t = sqlite.TimeFromTicks(42)
692
693 def CheckTimestampFromTicks(self):
694 ts = sqlite.TimestampFromTicks(42)
695
696 def CheckBinary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000697 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000698
699class ExtensionTests(unittest.TestCase):
700 def CheckScriptStringSql(self):
701 con = sqlite.connect(":memory:")
702 cur = con.cursor()
703 cur.executescript("""
704 -- bla bla
705 /* a stupid comment */
706 create table a(i);
707 insert into a(i) values (5);
708 """)
709 cur.execute("select i from a")
710 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000711 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000712
Gerhard Häringf9cee222010-03-05 15:20:03 +0000713 def CheckScriptSyntaxError(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000714 con = sqlite.connect(":memory:")
715 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300716 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000717 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000718
719 def CheckScriptErrorNormal(self):
720 con = sqlite.connect(":memory:")
721 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300722 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000723 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000724
Berker Peksagc4154402016-06-12 13:41:47 +0300725 def CheckCursorExecutescriptAsBytes(self):
726 con = sqlite.connect(":memory:")
727 cur = con.cursor()
728 with self.assertRaises(ValueError) as cm:
729 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
730 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
731
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000732 def CheckConnectionExecute(self):
733 con = sqlite.connect(":memory:")
734 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000735 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000736
737 def CheckConnectionExecutemany(self):
738 con = sqlite.connect(":memory:")
739 con.execute("create table test(foo)")
740 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
741 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000742 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
743 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000744
745 def CheckConnectionExecutescript(self):
746 con = sqlite.connect(":memory:")
747 con.executescript("create table test(foo); insert into test(foo) values (5);")
748 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000749 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000750
Gerhard Häringf9cee222010-03-05 15:20:03 +0000751class ClosedConTests(unittest.TestCase):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000752 def CheckClosedConCursor(self):
753 con = sqlite.connect(":memory:")
754 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300755 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000756 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000757
758 def CheckClosedConCommit(self):
759 con = sqlite.connect(":memory:")
760 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300761 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000762 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000763
764 def CheckClosedConRollback(self):
765 con = sqlite.connect(":memory:")
766 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300767 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000768 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000769
770 def CheckClosedCurExecute(self):
771 con = sqlite.connect(":memory:")
772 cur = con.cursor()
773 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300774 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000775 cur.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000776
Gerhard Häringf9cee222010-03-05 15:20:03 +0000777 def CheckClosedCreateFunction(self):
778 con = sqlite.connect(":memory:")
779 con.close()
780 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300781 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000782 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000783
784 def CheckClosedCreateAggregate(self):
785 con = sqlite.connect(":memory:")
786 con.close()
787 class Agg:
788 def __init__(self):
789 pass
790 def step(self, x):
791 pass
792 def finalize(self):
793 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300794 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000795 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000796
797 def CheckClosedSetAuthorizer(self):
798 con = sqlite.connect(":memory:")
799 con.close()
800 def authorizer(*args):
801 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300802 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000803 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000804
805 def CheckClosedSetProgressCallback(self):
806 con = sqlite.connect(":memory:")
807 con.close()
808 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300809 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000810 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000811
812 def CheckClosedCall(self):
813 con = sqlite.connect(":memory:")
814 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300815 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000816 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000817
818class ClosedCurTests(unittest.TestCase):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000819 def CheckClosed(self):
820 con = sqlite.connect(":memory:")
821 cur = con.cursor()
822 cur.close()
823
824 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
825 if method_name in ("execute", "executescript"):
826 params = ("select 4 union select 5",)
827 elif method_name == "executemany":
828 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
829 else:
830 params = []
831
Berker Peksag1003b342016-06-12 22:34:49 +0300832 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000833 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000834 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000835
Berker Peksag4bf580d2016-09-07 02:04:34 +0300836
837class SqliteOnConflictTests(unittest.TestCase):
838 """
839 Tests for SQLite's "insert on conflict" feature.
840
841 See https://www.sqlite.org/lang_conflict.html for details.
842 """
843
844 def setUp(self):
845 self.cx = sqlite.connect(":memory:")
846 self.cu = self.cx.cursor()
847 self.cu.execute("""
848 CREATE TABLE test(
849 id INTEGER PRIMARY KEY, name TEXT, unique_name TEXT UNIQUE
850 );
851 """)
852
853 def tearDown(self):
854 self.cu.close()
855 self.cx.close()
856
857 def CheckOnConflictRollbackWithExplicitTransaction(self):
858 self.cx.isolation_level = None # autocommit mode
859 self.cu = self.cx.cursor()
860 # Start an explicit transaction.
861 self.cu.execute("BEGIN")
862 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
863 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
864 with self.assertRaises(sqlite.IntegrityError):
865 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
866 # Use connection to commit.
867 self.cx.commit()
868 self.cu.execute("SELECT name, unique_name from test")
869 # Transaction should have rolled back and nothing should be in table.
870 self.assertEqual(self.cu.fetchall(), [])
871
872 def CheckOnConflictAbortRaisesWithExplicitTransactions(self):
873 # Abort cancels the current sql statement but doesn't change anything
874 # about the current transaction.
875 self.cx.isolation_level = None # autocommit mode
876 self.cu = self.cx.cursor()
877 # Start an explicit transaction.
878 self.cu.execute("BEGIN")
879 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
880 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
881 with self.assertRaises(sqlite.IntegrityError):
882 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
883 self.cx.commit()
884 self.cu.execute("SELECT name, unique_name FROM test")
885 # Expect the first two inserts to work, third to do nothing.
886 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
887
888 def CheckOnConflictRollbackWithoutTransaction(self):
889 # Start of implicit transaction
890 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
891 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
892 with self.assertRaises(sqlite.IntegrityError):
893 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
894 self.cu.execute("SELECT name, unique_name FROM test")
895 # Implicit transaction is rolled back on error.
896 self.assertEqual(self.cu.fetchall(), [])
897
898 def CheckOnConflictAbortRaisesWithoutTransactions(self):
899 # Abort cancels the current sql statement but doesn't change anything
900 # about the current transaction.
901 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
902 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
903 with self.assertRaises(sqlite.IntegrityError):
904 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
905 # Make sure all other values were inserted.
906 self.cu.execute("SELECT name, unique_name FROM test")
907 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
908
909 def CheckOnConflictFail(self):
910 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
911 with self.assertRaises(sqlite.IntegrityError):
912 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
913 self.assertEqual(self.cu.fetchall(), [])
914
915 def CheckOnConflictIgnore(self):
916 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
917 # Nothing should happen.
918 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
919 self.cu.execute("SELECT unique_name FROM test")
920 self.assertEqual(self.cu.fetchall(), [('foo',)])
921
922 def CheckOnConflictReplace(self):
923 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Data!', 'foo')")
924 # There shouldn't be an IntegrityError exception.
925 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Very different data!', 'foo')")
926 self.cu.execute("SELECT name, unique_name FROM test")
927 self.assertEqual(self.cu.fetchall(), [('Very different data!', 'foo')])
928
929
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000930def suite():
931 module_suite = unittest.makeSuite(ModuleTests, "Check")
932 connection_suite = unittest.makeSuite(ConnectionTests, "Check")
933 cursor_suite = unittest.makeSuite(CursorTests, "Check")
934 thread_suite = unittest.makeSuite(ThreadTests, "Check")
935 constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
936 ext_suite = unittest.makeSuite(ExtensionTests, "Check")
Gerhard Häringf9cee222010-03-05 15:20:03 +0000937 closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
938 closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
Berker Peksag4bf580d2016-09-07 02:04:34 +0300939 on_conflict_suite = unittest.makeSuite(SqliteOnConflictTests, "Check")
940 return unittest.TestSuite((
941 module_suite, connection_suite, cursor_suite, thread_suite,
942 constructor_suite, ext_suite, closed_con_suite, closed_cur_suite,
943 on_conflict_suite,
944 ))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000945
946def test():
947 runner = unittest.TextTestRunner()
948 runner.run(suite())
949
950if __name__ == "__main__":
951 test()