diff --git a/.gitignore b/.gitignore index f75ca9b..5a13495 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ !.gitignore !.travis.yml dist/ +*.db *.egg-info/ +*.pyc diff --git a/.travis.yml b/.travis.yml index f097728..a20df42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,20 @@ language: python -python: '3.4' +python: +- '2.7' +- '3.4' branches: except: "/^v\\d/" -install: true -script: true +services: +- mysql +- postgresql +install: +- python setup.py install +- pip install mysqlclient +- pip install psycopg2 +before_script: +- mysql -e 'CREATE DATABASE IF NOT EXISTS test;' +- psql -c 'create database test;' -U postgres +script: python tests/sqltests.py deploy: - provider: script script: 'curl --fail --data "{ \"tag_name\": \"v$(python setup.py --version)\", diff --git a/setup.py b/setup.py index 2342a33..6b7fce7 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ install_requires=["SQLAlchemy"], keywords="cs50", name="cs50", + package_dir={"": "src"}, packages=["cs50"], url="https://github.com/cs50/python-cs50", version="2.2.0" diff --git a/src/cs50/__pycache__/__init__.cpython-34.pyc b/src/cs50/__pycache__/__init__.cpython-34.pyc deleted file mode 100644 index c4a23a2..0000000 Binary files a/src/cs50/__pycache__/__init__.cpython-34.pyc and /dev/null differ diff --git a/src/cs50/__pycache__/__init__.cpython-36.pyc b/src/cs50/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 7eb8ca4..0000000 Binary files a/src/cs50/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/src/cs50/__pycache__/cs50.cpython-34.pyc b/src/cs50/__pycache__/cs50.cpython-34.pyc deleted file mode 100644 index dd8d33b..0000000 Binary files a/src/cs50/__pycache__/cs50.cpython-34.pyc and /dev/null differ diff --git a/src/cs50/__pycache__/cs50.cpython-36.pyc b/src/cs50/__pycache__/cs50.cpython-36.pyc deleted file mode 100644 index b444481..0000000 Binary files a/src/cs50/__pycache__/cs50.cpython-36.pyc and /dev/null differ diff --git a/src/cs50/__pycache__/sql.cpython-34.pyc b/src/cs50/__pycache__/sql.cpython-34.pyc deleted file mode 100644 index 8e56731..0000000 Binary files a/src/cs50/__pycache__/sql.cpython-34.pyc and /dev/null differ diff --git a/tests/sqltests.py b/tests/sqltests.py index d2204a1..8e518b4 100644 --- a/tests/sqltests.py +++ b/tests/sqltests.py @@ -1,7 +1,12 @@ -import unittest from cs50.sql import SQL +import sys +import unittest +import warnings class SQLTests(unittest.TestCase): + def multi_inserts_enabled(self): + return True + def test_delete_returns_affected_rows(self): rows = [ {"id": 1, "val": "foo"}, @@ -22,6 +27,8 @@ def test_delete_returns_affected_rows(self): def test_insert_returns_last_row_id(self): self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('foo')"), 1) self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('bar')"), 2) + if self.multi_inserts_enabled(): + self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('baz'); INSERT INTO cs50(val) VALUES('qux')"), 4) def test_select_all(self): self.assertEqual(self.db.execute("SELECT * FROM cs50"), []) @@ -70,54 +77,44 @@ def test_update_returns_affected_rows(self): self.assertEqual(self.db.execute("UPDATE cs50 SET val = 'foo' WHERE id > 1"), 2) self.assertEqual(self.db.execute("UPDATE cs50 SET val = 'foo' WHERE id = -50"), 0) -class MySQLTests(SQLTests): - @classmethod - def setUpClass(self): - self.db = SQL("mysql://root@localhost/cs50_sql_tests") - - def setUp(self): - self.db.execute("CREATE TABLE cs50 (id INTEGER NOT NULL AUTO_INCREMENT, val VARCHAR(16), PRIMARY KEY (id))") - def tearDown(self): self.db.execute("DROP TABLE cs50") @classmethod def tearDownClass(self): - self.db.execute("DROP TABLE IF EXISTS cs50") + try: + self.db.execute("DROP TABLE IF EXISTS cs50") + except Warning as e: + # suppress "unknown table" + if not str(e).startswith("(1051"): + raise e -class PostgresTests(SQLTests): +class MySQLTests(SQLTests): @classmethod def setUpClass(self): - self.db = SQL("postgresql://postgres:postgres@localhost/cs50_sql_tests") + self.db = SQL("mysql://root@localhost/test") def setUp(self): - self.db.execute("CREATE TABLE cs50 (id SERIAL PRIMARY KEY, val VARCHAR(16))") - - def tearDown(self): - self.db.execute("DROP TABLE cs50") + self.db.execute("CREATE TABLE cs50 (id INTEGER NOT NULL AUTO_INCREMENT, val VARCHAR(16), PRIMARY KEY (id))") +class PostgresTests(SQLTests): @classmethod - def tearDownClass(self): - self.db.execute("DROP TABLE IF EXISTS cs50") + def setUpClass(self): + self.db = SQL("postgresql://postgres@localhost/test") - def test_insert_returns_last_row_id(self): - self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('foo')"), 1) - self.assertEqual(self.db.execute("INSERT INTO cs50(val) VALUES('bar')"), 2) + def setUp(self): + self.db.execute("CREATE TABLE cs50 (id SERIAL PRIMARY KEY, val VARCHAR(16))") class SQLiteTests(SQLTests): @classmethod def setUpClass(self): - self.db = SQL("sqlite:///cs50_sql_tests.db") + self.db = SQL("sqlite:///test.db") def setUp(self): self.db.execute("CREATE TABLE cs50(id INTEGER PRIMARY KEY, val TEXT)") - def tearDown(self): - self.db.execute("DROP TABLE cs50") - - @classmethod - def tearDownClass(self): - self.db.execute("DROP TABLE IF EXISTS cs50") + def multi_inserts_enabled(self): + return False if __name__ == "__main__": suite = unittest.TestSuite([ @@ -126,4 +123,4 @@ def tearDownClass(self): unittest.TestLoader().loadTestsFromTestCase(PostgresTests) ]) - unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful())