Skip to content

Commit 959abb5

Browse files
author
Kareem Zidane
authored
Merge pull request #160 from cs50/tests/params
v7.0.2
2 parents a06139d + eb57b43 commit 959abb5

File tree

3 files changed

+69
-61
lines changed

3 files changed

+69
-61
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
package_dir={"": "src"},
1717
packages=["cs50"],
1818
url="https://github.com/cs50/python-cs50",
19-
version="7.0.1"
19+
version="7.0.2"
2020
)

src/cs50/_statement.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,21 @@ def _substitute_named_or_pyformat_markers(self):
197197
Raises a ``RuntimeError`` if any parameters are missing or unused.
198198
"""
199199

200-
unused_params = set(self._kwargs.keys())
200+
unused_params = {param_name: True for param_name in self._kwargs.keys()}
201201
for token_index, param_name in self._placeholders.items():
202202
if param_name not in self._kwargs:
203203
raise RuntimeError(f"missing value for placeholder ({param_name})")
204204

205205
self._tokens[token_index] = self._kwargs[param_name]
206-
unused_params.remove(param_name)
206+
unused_params[param_name] = False
207207

208-
if len(unused_params) > 0:
209-
joined_unused_params = get_human_readable_list(sorted(unused_params))
208+
sorted_unique_unused_param_names = sorted(set(
209+
param_name for param_name, unused in unused_params.items() if unused))
210+
if len(sorted_unique_unused_param_names) > 0:
211+
joined_unused_params = get_human_readable_list(sorted_unique_unused_param_names)
210212
raise RuntimeError(
211-
f"unused value{'' if len(unused_params) == 1 else 's'} ({joined_unused_params})")
213+
f"unused value{'' if len(sorted_unique_unused_param_names) == 1 else 's'}"
214+
+ " ({joined_unused_params})")
212215

213216
def _escape_verbatim_colons(self):
214217
"""Escapes verbatim colons from string literal and identifier tokens so they aren't treated

tests/sql.py

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def test_delete_returns_affected_rows(self):
2727
def test_insert_returns_last_row_id(self):
2828
self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('foo')"), 1)
2929
self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('bar')"), 2)
30+
self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('qux')"), 3)
3031

3132
def test_select_all(self):
3233
self.assertEqual(self.db.execute("SELECT * FROM cs50"), [])
@@ -131,55 +132,13 @@ def test_rollback(self):
131132
def test_identifier_case(self):
132133
self.assertIn("count", self.db.execute("SELECT 1 AS count")[0])
133134

134-
def tearDown(self):
135-
self.db.execute("DROP TABLE IF EXISTS cs50")
136-
self.db.execute("DROP TABLE IF EXISTS foo")
137-
self.db.execute("DROP TABLE IF EXISTS bar")
138-
139-
class MySQLTests(SQLTests):
140-
@classmethod
141-
def setUpClass(self):
142-
self.db = SQL("mysql://[email protected]/test")
143-
144-
def setUp(self):
145-
self.db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER NOT NULL AUTO_INCREMENT, val VARCHAR(16), bin BLOB, PRIMARY KEY (id))")
146-
self.db.execute("DELETE FROM cs50")
147-
148-
class PostgresTests(SQLTests):
149-
@classmethod
150-
def setUpClass(self):
151-
self.db = SQL("postgresql://postgres:[email protected]/test")
152-
153-
def setUp(self):
154-
self.db.execute("CREATE TABLE IF NOT EXISTS cs50 (id SERIAL PRIMARY KEY, val VARCHAR(16), bin BYTEA)")
155-
self.db.execute("DELETE FROM cs50")
156-
157-
def test_cte(self):
158-
self.assertEqual(self.db.execute("WITH foo AS ( SELECT 1 AS bar ) SELECT bar FROM foo"), [{"bar": 1}])
159-
160-
def test_postgres_scheme(self):
161-
db = SQL("postgres://postgres:[email protected]/test")
162-
db.execute("SELECT 1")
163-
164-
class SQLiteTests(SQLTests):
165-
@classmethod
166-
def setUpClass(self):
167-
open("test.db", "w").close()
168-
self.db = SQL("sqlite:///test.db")
169-
170-
def setUp(self):
171-
self.db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
172-
self.db.execute("DELETE FROM cs50")
173-
174-
def test_lastrowid(self):
175-
self.db.execute("CREATE TABLE foo(id INTEGER PRIMARY KEY AUTOINCREMENT, firstname TEXT, lastname TEXT)")
176-
self.assertEqual(self.db.execute("INSERT INTO foo (firstname, lastname) VALUES('firstname', 'lastname')"), 1)
177-
self.assertRaises(ValueError, self.db.execute, "INSERT INTO foo (id, firstname, lastname) VALUES(1, 'firstname', 'lastname')")
178-
self.assertEqual(self.db.execute("INSERT OR IGNORE INTO foo (id, firstname, lastname) VALUES(1, 'firstname', 'lastname')"), None)
135+
def test_none(self):
136+
self.db.execute("CREATE TABLE foo (val INTEGER)")
137+
self.db.execute("SELECT * FROM foo WHERE val = ?", None)
179138

180139
def test_integrity_constraints(self):
181140
self.db.execute("CREATE TABLE foo(id INTEGER PRIMARY KEY)")
182-
self.assertEqual(self.db.execute("INSERT INTO foo VALUES(1)"), 1)
141+
self.db.execute("INSERT INTO foo VALUES(1)")
183142
self.assertRaises(ValueError, self.db.execute, "INSERT INTO foo VALUES(1)")
184143

185144
def test_foreign_key_support(self):
@@ -188,7 +147,7 @@ def test_foreign_key_support(self):
188147
self.assertRaises(ValueError, self.db.execute, "INSERT INTO bar VALUES(50)")
189148

190149
def test_qmark(self):
191-
self.db.execute("CREATE TABLE foo (firstname STRING, lastname STRING)")
150+
self.db.execute("CREATE TABLE foo (firstname VARCHAR(255), lastname VARCHAR(255))")
192151

193152
self.db.execute("INSERT INTO foo VALUES (?, 'bar')", "baz")
194153
self.assertEqual(self.db.execute("SELECT * FROM foo"), [{"firstname": "baz", "lastname": "bar"}])
@@ -218,7 +177,7 @@ def test_qmark(self):
218177
self.assertEqual(self.db.execute("SELECT * FROM foo"), [{"firstname": "bar", "lastname": "baz"}])
219178
self.db.execute("DELETE FROM foo")
220179

221-
self.db.execute("CREATE TABLE bar (firstname STRING)")
180+
self.db.execute("CREATE TABLE bar (firstname VARCHAR(255))")
222181

223182
self.db.execute("INSERT INTO bar VALUES (?)", "baz")
224183
self.assertEqual(self.db.execute("SELECT * FROM bar"), [{"firstname": "baz"}])
@@ -242,7 +201,7 @@ def test_qmark(self):
242201
self.assertRaises(RuntimeError, self.db.execute, "INSERT INTO foo VALUES (?, ?)", 'bar', baz='baz')
243202

244203
def test_named(self):
245-
self.db.execute("CREATE TABLE foo (firstname STRING, lastname STRING)")
204+
self.db.execute("CREATE TABLE foo (firstname VARCHAR(255), lastname VARCHAR(255))")
246205

247206
self.db.execute("INSERT INTO foo VALUES (:baz, 'bar')", baz="baz")
248207
self.assertEqual(self.db.execute("SELECT * FROM foo"), [{"firstname": "baz", "lastname": "bar"}])
@@ -264,7 +223,11 @@ def test_named(self):
264223
self.assertEqual(self.db.execute("SELECT * FROM foo"), [{"firstname": "bar", "lastname": "baz"}])
265224
self.db.execute("DELETE FROM foo")
266225

267-
self.db.execute("CREATE TABLE bar (firstname STRING)")
226+
self.db.execute("INSERT INTO foo VALUES (:baz, :baz)", baz="baz")
227+
self.assertEqual(self.db.execute("SELECT * FROM foo"), [{"firstname": "baz", "lastname": "baz"}])
228+
self.db.execute("DELETE FROM foo")
229+
230+
self.db.execute("CREATE TABLE bar (firstname VARCHAR(255))")
268231
self.db.execute("INSERT INTO bar VALUES (:baz)", baz="baz")
269232
self.assertEqual(self.db.execute("SELECT * FROM bar"), [{"firstname": "baz"}])
270233

@@ -274,7 +237,7 @@ def test_named(self):
274237
self.assertRaises(RuntimeError, self.db.execute, "INSERT INTO foo VALUES (:bar, :baz)", 'baz', bar='bar')
275238

276239
def test_numeric(self):
277-
self.db.execute("CREATE TABLE foo (firstname STRING, lastname STRING)")
240+
self.db.execute("CREATE TABLE foo (firstname VARCHAR(255), lastname VARCHAR(255))")
278241

279242
self.db.execute("INSERT INTO foo VALUES (:1, 'bar')", "baz")
280243
self.assertEqual(self.db.execute("SELECT * FROM foo"), [{"firstname": "baz", "lastname": "bar"}])
@@ -296,7 +259,7 @@ def test_numeric(self):
296259
self.assertEqual(self.db.execute("SELECT * FROM foo"), [{"firstname": "bar", "lastname": "baz"}])
297260
self.db.execute("DELETE FROM foo")
298261

299-
self.db.execute("CREATE TABLE bar (firstname STRING)")
262+
self.db.execute("CREATE TABLE bar (firstname VARCHAR(255))")
300263
self.db.execute("INSERT INTO bar VALUES (:1)", "baz")
301264
self.assertEqual(self.db.execute("SELECT * FROM bar"), [{"firstname": "baz"}])
302265

@@ -308,9 +271,51 @@ def test_numeric(self):
308271
def test_cte(self):
309272
self.assertEqual(self.db.execute("WITH foo AS ( SELECT 1 AS bar ) SELECT bar FROM foo"), [{"bar": 1}])
310273

311-
def test_none(self):
312-
self.db.execute("CREATE TABLE foo (val INTEGER)")
313-
self.db.execute("SELECT * FROM foo WHERE val = ?", None)
274+
def tearDown(self):
275+
self.db.execute("DROP TABLE IF EXISTS cs50")
276+
self.db.execute("DROP TABLE IF EXISTS bar")
277+
self.db.execute("DROP TABLE IF EXISTS foo")
278+
279+
class MySQLTests(SQLTests):
280+
@classmethod
281+
def setUpClass(self):
282+
self.db = SQL("mysql://[email protected]/test")
283+
284+
def setUp(self):
285+
self.db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER NOT NULL AUTO_INCREMENT, val VARCHAR(16), bin BLOB, PRIMARY KEY (id))")
286+
self.db.execute("DELETE FROM cs50")
287+
288+
class PostgresTests(SQLTests):
289+
@classmethod
290+
def setUpClass(self):
291+
self.db = SQL("postgresql://postgres:[email protected]/test")
292+
293+
def setUp(self):
294+
self.db.execute("CREATE TABLE IF NOT EXISTS cs50 (id SERIAL PRIMARY KEY, val VARCHAR(16), bin BYTEA)")
295+
self.db.execute("DELETE FROM cs50")
296+
297+
def test_cte(self):
298+
self.assertEqual(self.db.execute("WITH foo AS ( SELECT 1 AS bar ) SELECT bar FROM foo"), [{"bar": 1}])
299+
300+
def test_postgres_scheme(self):
301+
db = SQL("postgres://postgres:[email protected]/test")
302+
db.execute("SELECT 1")
303+
304+
class SQLiteTests(SQLTests):
305+
@classmethod
306+
def setUpClass(self):
307+
open("test.db", "w").close()
308+
self.db = SQL("sqlite:///test.db")
309+
310+
def setUp(self):
311+
self.db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
312+
self.db.execute("DELETE FROM cs50")
313+
314+
def test_lastrowid(self):
315+
self.db.execute("CREATE TABLE foo(id INTEGER PRIMARY KEY AUTOINCREMENT, firstname TEXT, lastname TEXT)")
316+
self.assertEqual(self.db.execute("INSERT INTO foo (firstname, lastname) VALUES('firstname', 'lastname')"), 1)
317+
self.assertRaises(ValueError, self.db.execute, "INSERT INTO foo (id, firstname, lastname) VALUES(1, 'firstname', 'lastname')")
318+
self.assertEqual(self.db.execute("INSERT OR IGNORE INTO foo (id, firstname, lastname) VALUES(1, 'firstname', 'lastname')"), None)
314319

315320
if __name__ == "__main__":
316321
suite = unittest.TestSuite([

0 commit comments

Comments
 (0)