blob: 2b85ef99f0233df8245d3df0c42c4b02bc374155 [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):
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100175 self.addCleanup(unlink, TESTFN)
176 with sqlite.connect(TESTFN) as cx:
177 cx.execute('create table test(id integer)')
178 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
179 cx.execute('insert into test(id) values(0)')
180 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
181 with self.assertRaises(sqlite.OperationalError):
182 cx.execute('insert into test(id) values(1)')
183
184
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000185class CursorTests(unittest.TestCase):
186 def setUp(self):
187 self.cx = sqlite.connect(":memory:")
188 self.cu = self.cx.cursor()
Berker Peksage0b70cd2016-06-14 15:25:36 +0300189 self.cu.execute(
190 "create table test(id integer primary key, name text, "
191 "income number, unique_test text unique)"
192 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000193 self.cu.execute("insert into test(name) values (?)", ("foo",))
194
195 def tearDown(self):
196 self.cu.close()
197 self.cx.close()
198
199 def CheckExecuteNoArgs(self):
200 self.cu.execute("delete from test")
201
202 def CheckExecuteIllegalSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300203 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000204 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000205
206 def CheckExecuteTooMuchSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300207 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000208 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000209
210 def CheckExecuteTooMuchSql2(self):
211 self.cu.execute("select 5+4; -- foo bar")
212
213 def CheckExecuteTooMuchSql3(self):
214 self.cu.execute("""
215 select 5+4;
216
217 /*
218 foo
219 */
220 """)
221
222 def CheckExecuteWrongSqlArg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200223 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000224 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000225
226 def CheckExecuteArgInt(self):
227 self.cu.execute("insert into test(id) values (?)", (42,))
228
229 def CheckExecuteArgFloat(self):
230 self.cu.execute("insert into test(income) values (?)", (2500.32,))
231
232 def CheckExecuteArgString(self):
233 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
234
Petri Lehtinen023fe332012-02-01 22:18:19 +0200235 def CheckExecuteArgStringWithZeroByte(self):
236 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
237
238 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
239 row = self.cu.fetchone()
240 self.assertEqual(row[0], "Hu\x00go")
241
Berker Peksagc4154402016-06-12 13:41:47 +0300242 def CheckExecuteNonIterable(self):
243 with self.assertRaises(ValueError) as cm:
244 self.cu.execute("insert into test(id) values (?)", 42)
245 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
246
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000247 def CheckExecuteWrongNoOfArgs1(self):
248 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300249 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000250 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000251
252 def CheckExecuteWrongNoOfArgs2(self):
253 # too little parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300254 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256
257 def CheckExecuteWrongNoOfArgs3(self):
258 # no parameters, parameters are needed
Berker Peksag1003b342016-06-12 22:34:49 +0300259 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000261
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000262 def CheckExecuteParamList(self):
263 self.cu.execute("insert into test(name) values ('foo')")
264 self.cu.execute("select name from test where name=?", ["foo"])
265 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000266 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000267
268 def CheckExecuteParamSequence(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300269 class L:
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000270 def __len__(self):
271 return 1
272 def __getitem__(self, x):
273 assert x == 0
274 return "foo"
275
276 self.cu.execute("insert into test(name) values ('foo')")
277 self.cu.execute("select name from test where name=?", L())
278 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000279 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000280
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300281 def CheckExecuteParamSequenceBadLen(self):
282 # Issue41662: Error in __len__() was overridden with ProgrammingError.
283 class L:
284 def __len__(self):
285 1/0
286 def __getitem__(slf, x):
287 raise AssertionError
288
289 self.cu.execute("insert into test(name) values ('foo')")
290 with self.assertRaises(ZeroDivisionError):
291 self.cu.execute("select name from test where name=?", L())
292
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000293 def CheckExecuteDictMapping(self):
294 self.cu.execute("insert into test(name) values ('foo')")
295 self.cu.execute("select name from test where name=:name", {"name": "foo"})
296 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000297 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000298
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000299 def CheckExecuteDictMapping_Mapping(self):
300 class D(dict):
301 def __missing__(self, key):
302 return "foo"
303
304 self.cu.execute("insert into test(name) values ('foo')")
305 self.cu.execute("select name from test where name=:name", D())
306 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000307 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000308
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000309 def CheckExecuteDictMappingTooLittleArgs(self):
310 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300311 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000312 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313
314 def CheckExecuteDictMappingNoArgs(self):
315 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300316 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000317 self.cu.execute("select name from test where name=:name")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000318
319 def CheckExecuteDictMappingUnnamed(self):
320 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300321 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000322 self.cu.execute("select name from test where name=?", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000323
324 def CheckClose(self):
325 self.cu.close()
326
327 def CheckRowcountExecute(self):
328 self.cu.execute("delete from test")
329 self.cu.execute("insert into test(name) values ('foo')")
330 self.cu.execute("insert into test(name) values ('foo')")
331 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000332 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000333
Georg Brandlf78e02b2008-06-10 17:40:04 +0000334 def CheckRowcountSelect(self):
335 """
336 pysqlite does not know the rowcount of SELECT statements, because we
337 don't fetch all rows after executing the select statement. The rowcount
338 has thus to be -1.
339 """
340 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000341 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000342
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343 def CheckRowcountExecutemany(self):
344 self.cu.execute("delete from test")
345 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000346 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000347
348 def CheckTotalChanges(self):
349 self.cu.execute("insert into test(name) values ('foo')")
350 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300351 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000352
353 # Checks for executemany:
354 # Sequences are required by the DB-API, iterators
355 # enhancements in pysqlite.
356
357 def CheckExecuteManySequence(self):
358 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
359
360 def CheckExecuteManyIterator(self):
361 class MyIter:
362 def __init__(self):
363 self.value = 5
364
Georg Brandla18af4e2007-04-21 15:47:16 +0000365 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000366 if self.value == 10:
367 raise StopIteration
368 else:
369 self.value += 1
370 return (self.value,)
371
372 self.cu.executemany("insert into test(income) values (?)", MyIter())
373
374 def CheckExecuteManyGenerator(self):
375 def mygen():
376 for i in range(5):
377 yield (i,)
378
379 self.cu.executemany("insert into test(income) values (?)", mygen())
380
381 def CheckExecuteManyWrongSqlArg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200382 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000383 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000384
385 def CheckExecuteManySelect(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300386 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000387 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000388
389 def CheckExecuteManyNotIterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300390 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000391 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000392
393 def CheckFetchIter(self):
394 # Optional DB-API extension.
395 self.cu.execute("delete from test")
396 self.cu.execute("insert into test(id) values (?)", (5,))
397 self.cu.execute("insert into test(id) values (?)", (6,))
398 self.cu.execute("select id from test order by id")
399 lst = []
400 for row in self.cu:
401 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000402 self.assertEqual(lst[0], 5)
403 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000404
405 def CheckFetchone(self):
406 self.cu.execute("select name from test")
407 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000408 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000409 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000410 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000411
412 def CheckFetchoneNoStatement(self):
413 cur = self.cx.cursor()
414 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000415 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000416
417 def CheckArraySize(self):
418 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000419 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000420
421 # now set to 2
422 self.cu.arraysize = 2
423
424 # now make the query return 3 rows
425 self.cu.execute("delete from test")
426 self.cu.execute("insert into test(name) values ('A')")
427 self.cu.execute("insert into test(name) values ('B')")
428 self.cu.execute("insert into test(name) values ('C')")
429 self.cu.execute("select name from test")
430 res = self.cu.fetchmany()
431
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000432 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000433
434 def CheckFetchmany(self):
435 self.cu.execute("select name from test")
436 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000437 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000438 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000439 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000440
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000441 def CheckFetchmanyKwArg(self):
442 """Checks if fetchmany works with keyword arguments"""
443 self.cu.execute("select name from test")
444 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000445 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000446
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000447 def CheckFetchall(self):
448 self.cu.execute("select name from test")
449 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000450 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000451 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000452 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000453
454 def CheckSetinputsizes(self):
455 self.cu.setinputsizes([3, 4, 5])
456
457 def CheckSetoutputsize(self):
458 self.cu.setoutputsize(5, 0)
459
460 def CheckSetoutputsizeNoColumn(self):
461 self.cu.setoutputsize(42)
462
463 def CheckCursorConnection(self):
464 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000465 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000466
467 def CheckWrongCursorCallable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300468 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000469 def f(): pass
470 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000471
472 def CheckCursorWrongClass(self):
473 class Foo: pass
474 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300475 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000476 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000477
Berker Peksage0b70cd2016-06-14 15:25:36 +0300478 def CheckLastRowIDOnReplace(self):
479 """
480 INSERT OR REPLACE and REPLACE INTO should produce the same behavior.
481 """
482 sql = '{} INTO test(id, unique_test) VALUES (?, ?)'
483 for statement in ('INSERT OR REPLACE', 'REPLACE'):
484 with self.subTest(statement=statement):
485 self.cu.execute(sql.format(statement), (1, 'foo'))
486 self.assertEqual(self.cu.lastrowid, 1)
487
488 def CheckLastRowIDOnIgnore(self):
489 self.cu.execute(
490 "insert or ignore into test(unique_test) values (?)",
491 ('test',))
492 self.assertEqual(self.cu.lastrowid, 2)
493 self.cu.execute(
494 "insert or ignore into test(unique_test) values (?)",
495 ('test',))
496 self.assertEqual(self.cu.lastrowid, 2)
497
498 def CheckLastRowIDInsertOR(self):
499 results = []
500 for statement in ('FAIL', 'ABORT', 'ROLLBACK'):
501 sql = 'INSERT OR {} INTO test(unique_test) VALUES (?)'
502 with self.subTest(statement='INSERT OR {}'.format(statement)):
503 self.cu.execute(sql.format(statement), (statement,))
504 results.append((statement, self.cu.lastrowid))
505 with self.assertRaises(sqlite.IntegrityError):
506 self.cu.execute(sql.format(statement), (statement,))
507 results.append((statement, self.cu.lastrowid))
508 expected = [
509 ('FAIL', 2), ('FAIL', 2),
510 ('ABORT', 3), ('ABORT', 3),
511 ('ROLLBACK', 4), ('ROLLBACK', 4),
512 ]
513 self.assertEqual(results, expected)
514
515
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000516class ThreadTests(unittest.TestCase):
517 def setUp(self):
518 self.con = sqlite.connect(":memory:")
519 self.cur = self.con.cursor()
520 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
521
522 def tearDown(self):
523 self.cur.close()
524 self.con.close()
525
526 def CheckConCursor(self):
527 def run(con, errors):
528 try:
529 cur = con.cursor()
530 errors.append("did not raise ProgrammingError")
531 return
532 except sqlite.ProgrammingError:
533 return
534 except:
535 errors.append("raised wrong exception")
536
537 errors = []
538 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
539 t.start()
540 t.join()
541 if len(errors) > 0:
542 self.fail("\n".join(errors))
543
544 def CheckConCommit(self):
545 def run(con, errors):
546 try:
547 con.commit()
548 errors.append("did not raise ProgrammingError")
549 return
550 except sqlite.ProgrammingError:
551 return
552 except:
553 errors.append("raised wrong exception")
554
555 errors = []
556 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
557 t.start()
558 t.join()
559 if len(errors) > 0:
560 self.fail("\n".join(errors))
561
562 def CheckConRollback(self):
563 def run(con, errors):
564 try:
565 con.rollback()
566 errors.append("did not raise ProgrammingError")
567 return
568 except sqlite.ProgrammingError:
569 return
570 except:
571 errors.append("raised wrong exception")
572
573 errors = []
574 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
575 t.start()
576 t.join()
577 if len(errors) > 0:
578 self.fail("\n".join(errors))
579
580 def CheckConClose(self):
581 def run(con, errors):
582 try:
583 con.close()
584 errors.append("did not raise ProgrammingError")
585 return
586 except sqlite.ProgrammingError:
587 return
588 except:
589 errors.append("raised wrong exception")
590
591 errors = []
592 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
593 t.start()
594 t.join()
595 if len(errors) > 0:
596 self.fail("\n".join(errors))
597
598 def CheckCurImplicitBegin(self):
599 def run(cur, errors):
600 try:
601 cur.execute("insert into test(name) values ('a')")
602 errors.append("did not raise ProgrammingError")
603 return
604 except sqlite.ProgrammingError:
605 return
606 except:
607 errors.append("raised wrong exception")
608
609 errors = []
610 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
611 t.start()
612 t.join()
613 if len(errors) > 0:
614 self.fail("\n".join(errors))
615
616 def CheckCurClose(self):
617 def run(cur, errors):
618 try:
619 cur.close()
620 errors.append("did not raise ProgrammingError")
621 return
622 except sqlite.ProgrammingError:
623 return
624 except:
625 errors.append("raised wrong exception")
626
627 errors = []
628 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
629 t.start()
630 t.join()
631 if len(errors) > 0:
632 self.fail("\n".join(errors))
633
634 def CheckCurExecute(self):
635 def run(cur, errors):
636 try:
637 cur.execute("select name from test")
638 errors.append("did not raise ProgrammingError")
639 return
640 except sqlite.ProgrammingError:
641 return
642 except:
643 errors.append("raised wrong exception")
644
645 errors = []
646 self.cur.execute("insert into test(name) values ('a')")
647 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
648 t.start()
649 t.join()
650 if len(errors) > 0:
651 self.fail("\n".join(errors))
652
653 def CheckCurIterNext(self):
654 def run(cur, errors):
655 try:
656 row = cur.fetchone()
657 errors.append("did not raise ProgrammingError")
658 return
659 except sqlite.ProgrammingError:
660 return
661 except:
662 errors.append("raised wrong exception")
663
664 errors = []
665 self.cur.execute("insert into test(name) values ('a')")
666 self.cur.execute("select name from test")
667 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
668 t.start()
669 t.join()
670 if len(errors) > 0:
671 self.fail("\n".join(errors))
672
673class ConstructorTests(unittest.TestCase):
674 def CheckDate(self):
675 d = sqlite.Date(2004, 10, 28)
676
677 def CheckTime(self):
678 t = sqlite.Time(12, 39, 35)
679
680 def CheckTimestamp(self):
681 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
682
683 def CheckDateFromTicks(self):
684 d = sqlite.DateFromTicks(42)
685
686 def CheckTimeFromTicks(self):
687 t = sqlite.TimeFromTicks(42)
688
689 def CheckTimestampFromTicks(self):
690 ts = sqlite.TimestampFromTicks(42)
691
692 def CheckBinary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000693 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000694
695class ExtensionTests(unittest.TestCase):
696 def CheckScriptStringSql(self):
697 con = sqlite.connect(":memory:")
698 cur = con.cursor()
699 cur.executescript("""
700 -- bla bla
701 /* a stupid comment */
702 create table a(i);
703 insert into a(i) values (5);
704 """)
705 cur.execute("select i from a")
706 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000707 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000708
Gerhard Häringf9cee222010-03-05 15:20:03 +0000709 def CheckScriptSyntaxError(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000710 con = sqlite.connect(":memory:")
711 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300712 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000713 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000714
715 def CheckScriptErrorNormal(self):
716 con = sqlite.connect(":memory:")
717 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300718 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000719 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000720
Berker Peksagc4154402016-06-12 13:41:47 +0300721 def CheckCursorExecutescriptAsBytes(self):
722 con = sqlite.connect(":memory:")
723 cur = con.cursor()
724 with self.assertRaises(ValueError) as cm:
725 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
726 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
727
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000728 def CheckConnectionExecute(self):
729 con = sqlite.connect(":memory:")
730 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000731 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000732
733 def CheckConnectionExecutemany(self):
734 con = sqlite.connect(":memory:")
735 con.execute("create table test(foo)")
736 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
737 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000738 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
739 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000740
741 def CheckConnectionExecutescript(self):
742 con = sqlite.connect(":memory:")
743 con.executescript("create table test(foo); insert into test(foo) values (5);")
744 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000745 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000746
Gerhard Häringf9cee222010-03-05 15:20:03 +0000747class ClosedConTests(unittest.TestCase):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000748 def CheckClosedConCursor(self):
749 con = sqlite.connect(":memory:")
750 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300751 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000752 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000753
754 def CheckClosedConCommit(self):
755 con = sqlite.connect(":memory:")
756 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300757 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000758 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000759
760 def CheckClosedConRollback(self):
761 con = sqlite.connect(":memory:")
762 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300763 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000764 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000765
766 def CheckClosedCurExecute(self):
767 con = sqlite.connect(":memory:")
768 cur = con.cursor()
769 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300770 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000771 cur.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000772
Gerhard Häringf9cee222010-03-05 15:20:03 +0000773 def CheckClosedCreateFunction(self):
774 con = sqlite.connect(":memory:")
775 con.close()
776 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300777 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000778 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000779
780 def CheckClosedCreateAggregate(self):
781 con = sqlite.connect(":memory:")
782 con.close()
783 class Agg:
784 def __init__(self):
785 pass
786 def step(self, x):
787 pass
788 def finalize(self):
789 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300790 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000791 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000792
793 def CheckClosedSetAuthorizer(self):
794 con = sqlite.connect(":memory:")
795 con.close()
796 def authorizer(*args):
797 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300798 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000799 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000800
801 def CheckClosedSetProgressCallback(self):
802 con = sqlite.connect(":memory:")
803 con.close()
804 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300805 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000806 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000807
808 def CheckClosedCall(self):
809 con = sqlite.connect(":memory:")
810 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300811 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000812 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000813
814class ClosedCurTests(unittest.TestCase):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000815 def CheckClosed(self):
816 con = sqlite.connect(":memory:")
817 cur = con.cursor()
818 cur.close()
819
820 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
821 if method_name in ("execute", "executescript"):
822 params = ("select 4 union select 5",)
823 elif method_name == "executemany":
824 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
825 else:
826 params = []
827
Berker Peksag1003b342016-06-12 22:34:49 +0300828 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000829 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000830 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000831
Berker Peksag4bf580d2016-09-07 02:04:34 +0300832
833class SqliteOnConflictTests(unittest.TestCase):
834 """
835 Tests for SQLite's "insert on conflict" feature.
836
837 See https://www.sqlite.org/lang_conflict.html for details.
838 """
839
840 def setUp(self):
841 self.cx = sqlite.connect(":memory:")
842 self.cu = self.cx.cursor()
843 self.cu.execute("""
844 CREATE TABLE test(
845 id INTEGER PRIMARY KEY, name TEXT, unique_name TEXT UNIQUE
846 );
847 """)
848
849 def tearDown(self):
850 self.cu.close()
851 self.cx.close()
852
853 def CheckOnConflictRollbackWithExplicitTransaction(self):
854 self.cx.isolation_level = None # autocommit mode
855 self.cu = self.cx.cursor()
856 # Start an explicit transaction.
857 self.cu.execute("BEGIN")
858 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
859 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
860 with self.assertRaises(sqlite.IntegrityError):
861 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
862 # Use connection to commit.
863 self.cx.commit()
864 self.cu.execute("SELECT name, unique_name from test")
865 # Transaction should have rolled back and nothing should be in table.
866 self.assertEqual(self.cu.fetchall(), [])
867
868 def CheckOnConflictAbortRaisesWithExplicitTransactions(self):
869 # Abort cancels the current sql statement but doesn't change anything
870 # about the current transaction.
871 self.cx.isolation_level = None # autocommit mode
872 self.cu = self.cx.cursor()
873 # Start an explicit transaction.
874 self.cu.execute("BEGIN")
875 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
876 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
877 with self.assertRaises(sqlite.IntegrityError):
878 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
879 self.cx.commit()
880 self.cu.execute("SELECT name, unique_name FROM test")
881 # Expect the first two inserts to work, third to do nothing.
882 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
883
884 def CheckOnConflictRollbackWithoutTransaction(self):
885 # Start of implicit transaction
886 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
887 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
888 with self.assertRaises(sqlite.IntegrityError):
889 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
890 self.cu.execute("SELECT name, unique_name FROM test")
891 # Implicit transaction is rolled back on error.
892 self.assertEqual(self.cu.fetchall(), [])
893
894 def CheckOnConflictAbortRaisesWithoutTransactions(self):
895 # Abort cancels the current sql statement but doesn't change anything
896 # about the current transaction.
897 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
898 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
899 with self.assertRaises(sqlite.IntegrityError):
900 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
901 # Make sure all other values were inserted.
902 self.cu.execute("SELECT name, unique_name FROM test")
903 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
904
905 def CheckOnConflictFail(self):
906 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
907 with self.assertRaises(sqlite.IntegrityError):
908 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
909 self.assertEqual(self.cu.fetchall(), [])
910
911 def CheckOnConflictIgnore(self):
912 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
913 # Nothing should happen.
914 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
915 self.cu.execute("SELECT unique_name FROM test")
916 self.assertEqual(self.cu.fetchall(), [('foo',)])
917
918 def CheckOnConflictReplace(self):
919 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Data!', 'foo')")
920 # There shouldn't be an IntegrityError exception.
921 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Very different data!', 'foo')")
922 self.cu.execute("SELECT name, unique_name FROM test")
923 self.assertEqual(self.cu.fetchall(), [('Very different data!', 'foo')])
924
925
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000926def suite():
927 module_suite = unittest.makeSuite(ModuleTests, "Check")
928 connection_suite = unittest.makeSuite(ConnectionTests, "Check")
929 cursor_suite = unittest.makeSuite(CursorTests, "Check")
930 thread_suite = unittest.makeSuite(ThreadTests, "Check")
931 constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
932 ext_suite = unittest.makeSuite(ExtensionTests, "Check")
Gerhard Häringf9cee222010-03-05 15:20:03 +0000933 closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
934 closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
Berker Peksag4bf580d2016-09-07 02:04:34 +0300935 on_conflict_suite = unittest.makeSuite(SqliteOnConflictTests, "Check")
936 return unittest.TestSuite((
937 module_suite, connection_suite, cursor_suite, thread_suite,
938 constructor_suite, ext_suite, closed_con_suite, closed_cur_suite,
939 on_conflict_suite,
940 ))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000941
942def test():
943 runner = unittest.TextTestRunner()
944 runner.run(suite())
945
946if __name__ == "__main__":
947 test()