From cda4b89f5088f3c06833401ca5eceb1f7218a89d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Rombauts?= Date: Mon, 27 Jun 2016 13:18:23 +0200 Subject: [PATCH] A few more unit tests for backups, statement and database - should get us to 100% on Backup --- tests/Backup_test.cpp | 48 +++++++++++++++-- tests/Database_test.cpp | 7 +-- tests/Statement_test.cpp | 110 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 154 insertions(+), 11 deletions(-) diff --git a/tests/Backup_test.cpp b/tests/Backup_test.cpp index e64f95c..c4783c3 100644 --- a/tests/Backup_test.cpp +++ b/tests/Backup_test.cpp @@ -3,7 +3,8 @@ * @ingroup tests * @brief Test of a SQLite Backup. * - * Copyright (c) 2015-2015 Shibao HONG (shibaohong@outlook.com) + * Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com) + * Copyright (c) 2016 Sebastien Rombauts (sebastien.rombauts@gmail.com) * * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt * or copy at http://opensource.org/licenses/MIT) @@ -24,11 +25,46 @@ TEST(Backup, initException) { srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)"); ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")")); ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")")); - EXPECT_THROW(SQLite::Backup backup(srcDB, "src", srcDB, "src"), SQLite::Exception); + EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception); + EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception); + const std::string name("main"); + EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception); remove("backup_test.db3"); } -TEST(Backup, executeStep) { +TEST(Backup, executeStepOne) { + remove("backup_test.db3"); + remove("backup_test.db3.backup"); + SQLite::Database srcDB("backup_test.db3", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)"); + ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")")); + ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")")); + + SQLite::Database destDB("backup_test.db3.backup", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + SQLite::Backup backup(destDB, "main", srcDB, "main"); + int res = backup.executeStep(1); // backup only one page at a time + ASSERT_EQ(SQLITE_OK, res); + const int total = backup.totalPageCount(); + ASSERT_EQ(2, total); + int remaining = backup.remainingPageCount(); + ASSERT_EQ(1, remaining); + res = backup.executeStep(1); // backup the second and last page + ASSERT_EQ(SQLITE_DONE, res); + remaining = backup.remainingPageCount(); + ASSERT_EQ(0, remaining); + + SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC"); + ASSERT_TRUE(query.executeStep()); + EXPECT_EQ(1, query.getColumn(0).getInt()); + EXPECT_STREQ("first", query.getColumn(1)); + ASSERT_TRUE(query.executeStep()); + EXPECT_EQ(2, query.getColumn(0).getInt()); + EXPECT_STREQ("second", query.getColumn(1)); + remove("backup_test.db3"); + remove("backup_test.db3.backup"); +} + +TEST(Backup, executeStepAll) { remove("backup_test.db3"); remove("backup_test.db3.backup"); SQLite::Database srcDB("backup_test.db3", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); @@ -38,8 +74,12 @@ TEST(Backup, executeStep) { SQLite::Database destDB("backup_test.db3.backup", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); SQLite::Backup backup(destDB, srcDB); - const int res = backup.executeStep(); + const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once ASSERT_EQ(res, SQLITE_DONE); + const int total = backup.totalPageCount(); + ASSERT_EQ(2, total); + const int remaining = backup.remainingPageCount(); + ASSERT_EQ(0, remaining); SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC"); ASSERT_TRUE(query.executeStep()); diff --git a/tests/Database_test.cpp b/tests/Database_test.cpp index 9269106..f87dba3 100644 --- a/tests/Database_test.cpp +++ b/tests/Database_test.cpp @@ -31,7 +31,7 @@ void assertion_failed(const char* apFile, const long apLine, const char* apFunc, TEST(Database, ctorExecCreateDropExist) { remove("test.db3"); { - // Try to open an unexisting database + // Try to open a non-existing database std::string filename = "test.db3"; EXPECT_THROW(SQLite::Database not_found(filename), SQLite::Exception); @@ -58,7 +58,7 @@ TEST(Database, ctorExecCreateDropExist) { TEST(Database, createCloseReopen) { remove("test.db3"); { - // Try to open the unexisting database + // Try to open the non-existing database EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception); // Create a new database @@ -153,7 +153,8 @@ TEST(Database, exec) { EXPECT_EQ(2, db.getTotalChanges()); // third row : insert the "third" text value into new row of id 3 - EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\")")); + const std::string insert("INSERT INTO test VALUES (NULL, \"third\")"); + EXPECT_EQ(1, db.exec(insert)); EXPECT_EQ(3, db.getLastInsertRowid()); EXPECT_EQ(3, db.getTotalChanges()); diff --git a/tests/Statement_test.cpp b/tests/Statement_test.cpp index 5efed02..f47b4ad 100644 --- a/tests/Statement_test.cpp +++ b/tests/Statement_test.cpp @@ -33,7 +33,7 @@ TEST(Statement, invalid) { EXPECT_EQ(SQLITE_OK, db.getExtendedErrorCode()); // Compile a SQL query with no parameter - SQLite::Statement query(db, "SELECT * FROM test"); + SQLite::Statement query(db, "SELECT * FROM test"); EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str()); EXPECT_EQ(2, query.getColumnCount ()); EXPECT_FALSE(query.isOk()); @@ -86,6 +86,108 @@ TEST(Statement, invalid) { // TODO: test every kind of binding + clearBindings() +TEST(Statement, executeStep) { + // Create a new database + SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + EXPECT_EQ(SQLITE_OK, db.getErrorCode()); + + // Create a new table + EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL)")); + EXPECT_EQ(SQLITE_OK, db.getErrorCode()); + + // Create a first row + EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)")); + EXPECT_EQ(1, db.getLastInsertRowid()); + + // Compile a SQL query + SQLite::Statement query(db, "SELECT * FROM test"); + EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str()); + EXPECT_EQ(4, query.getColumnCount()); + + // Get the first row + query.executeStep(); + EXPECT_TRUE (query.isOk()); + EXPECT_FALSE(query.isDone()); + const sqlite3_int64 id = query.getColumn(0); + const std::string msg = query.getColumn(1); + const int integer = query.getColumn(2); + const double real = query.getColumn(3); + EXPECT_EQ(1, id); + EXPECT_EQ("first", msg); + EXPECT_EQ(123, integer); + EXPECT_EQ(0.123, real); + + // Step one more time to discover there is nothing more + query.executeStep(); + EXPECT_FALSE(query.isOk()); + EXPECT_TRUE (query.isDone()); // "done" is "the end" + + // Step after "the end" throw an exception + EXPECT_THROW(query.executeStep(), SQLite::Exception); +} + +TEST(Statement, isColumnNull) { + // Create a new database + SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + ASSERT_EQ(SQLITE_OK, db.getErrorCode()); + + // Create a new table + EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT, int INTEGER, double REAL)")); + ASSERT_EQ(SQLITE_OK, db.getErrorCode()); + + // Create a first row with no null values, then other rows with each time a NULL value + ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, 0.123)")); + ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 123, 0.123)")); + ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", NULL, 0.123)")); + ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, NULL)")); + + // Compile a SQL query + const std::string select("SELECT * FROM test"); + SQLite::Statement query(db, select); + EXPECT_EQ(select, query.getQuery()); + EXPECT_EQ(3, query.getColumnCount()); + + // Get the first non-null row + query.executeStep(); + EXPECT_TRUE (query.isOk()); + EXPECT_FALSE(query.isDone()); + EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception); + EXPECT_EQ(false, query.isColumnNull(0)); + EXPECT_EQ(false, query.isColumnNull(1)); + EXPECT_EQ(false, query.isColumnNull(2)); + EXPECT_THROW(query.isColumnNull(3), SQLite::Exception); + + // Get the second row with null text + query.executeStep(); + EXPECT_TRUE (query.isOk()); + EXPECT_FALSE(query.isDone()); + EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception); + EXPECT_EQ(true, query.isColumnNull(0)); + EXPECT_EQ(false, query.isColumnNull(1)); + EXPECT_EQ(false, query.isColumnNull(2)); + EXPECT_THROW(query.isColumnNull(3), SQLite::Exception); + + // Get the second row with null integer + query.executeStep(); + EXPECT_TRUE (query.isOk()); + EXPECT_FALSE(query.isDone()); + EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception); + EXPECT_EQ(false, query.isColumnNull(0)); + EXPECT_EQ(true, query.isColumnNull(1)); + EXPECT_EQ(false, query.isColumnNull(2)); + EXPECT_THROW(query.isColumnNull(3), SQLite::Exception); + + // Get the third row with null float + query.executeStep(); + EXPECT_TRUE (query.isOk()); + EXPECT_FALSE(query.isDone()); + EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception); + EXPECT_EQ(false, query.isColumnNull(0)); + EXPECT_EQ(false, query.isColumnNull(1)); + EXPECT_EQ(true, query.isColumnNull(2)); + EXPECT_THROW(query.isColumnNull(3), SQLite::Exception); +} + TEST(Statement, getColumnByName) { // Create a new database SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); @@ -103,14 +205,14 @@ TEST(Statement, getColumnByName) { EXPECT_EQ(1, db.getTotalChanges()); // Compile a SQL query - SQLite::Statement query(db, "SELECT * FROM test"); + SQLite::Statement query(db, "SELECT * FROM test"); EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str()); EXPECT_EQ(4, query.getColumnCount()); query.executeStep(); EXPECT_TRUE (query.isOk()); EXPECT_FALSE(query.isDone()); - // Look for unexisting columns + // Look for non-existing columns EXPECT_THROW(query.getColumn("unknown"), SQLite::Exception); EXPECT_THROW(query.getColumn(""), SQLite::Exception); @@ -128,7 +230,7 @@ TEST(Statement, getName) { EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)")); // Compile a SQL query, using the "id" column name as-is, but aliasing the "msg" column with new name "value" - SQLite::Statement query(db, "SELECT id, msg as value FROM test"); + SQLite::Statement query(db, "SELECT id, msg as value FROM test"); query.executeStep(); const std::string name0 = query.getColumnName(0);