diff options
Diffstat (limited to 'tests/unit/unittest/sqlitedatabase-test.cpp')
-rw-r--r-- | tests/unit/unittest/sqlitedatabase-test.cpp | 140 |
1 files changed, 137 insertions, 3 deletions
diff --git a/tests/unit/unittest/sqlitedatabase-test.cpp b/tests/unit/unittest/sqlitedatabase-test.cpp index 66c1aa8387..a93100c3e0 100644 --- a/tests/unit/unittest/sqlitedatabase-test.cpp +++ b/tests/unit/unittest/sqlitedatabase-test.cpp @@ -28,6 +28,7 @@ #include "spydummy.h" #include <sqlitedatabase.h> +#include <sqlitereadstatement.h> #include <sqlitetable.h> #include <sqlitewritestatement.h> #include <utf8string.h> @@ -38,6 +39,8 @@ #include <QTemporaryFile> #include <QVariant> +#include <functional> + namespace { using testing::Contains; @@ -50,27 +53,46 @@ using Sqlite::Table; class SqliteDatabase : public ::testing::Test { protected: - void SetUp() override + SqliteDatabase() { database.setJournalMode(JournalMode::Memory); database.setDatabaseFilePath(databaseFilePath); auto &table = database.addTable(); table.setName("test"); + table.addColumn("id", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}}); table.addColumn("name"); database.open(); } - void TearDown() override + ~SqliteDatabase() { if (database.isOpen()) database.close(); } + std::vector<Utils::SmallString> names() const + { + return Sqlite::ReadStatement("SELECT name FROM test", database).values<Utils::SmallString>(8); + } + + static void updateHookCallback( + void *object, int type, char const *database, char const *table, long long rowId) + { + static_cast<SqliteDatabase *>(object)->callback(static_cast<Sqlite::ChangeType>(type), + database, + table, + rowId); + } + +protected: SpyDummy spyDummy; QString databaseFilePath{":memory:"}; - Sqlite::Database database; + mutable Sqlite::Database database; Sqlite::TransactionInterface &transactionInterface = database; + MockFunction<void(Sqlite::ChangeType tupe, char const *, char const *, long long)> callbackMock; + std::function<void(Sqlite::ChangeType tupe, char const *, char const *, long long)> + callback = callbackMock.AsStdFunction(); }; TEST_F(SqliteDatabase, SetDatabaseFilePath) @@ -220,4 +242,116 @@ TEST_F(SqliteDatabase, Rollback) ASSERT_NO_THROW(transactionInterface.rollback()); } +TEST_F(SqliteDatabase, SetUpdateHookSet) +{ + database.setUpdateHook(this, updateHookCallback); + + EXPECT_CALL(callbackMock, Call(_, _, _, _)); + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); +} + +TEST_F(SqliteDatabase, SetNullUpdateHook) +{ + database.setUpdateHook(this, updateHookCallback); + + database.setUpdateHook(nullptr, nullptr); + + EXPECT_CALL(callbackMock, Call(_, _, _, _)).Times(0); + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); +} + +TEST_F(SqliteDatabase, ResetUpdateHook) +{ + database.setUpdateHook(this, updateHookCallback); + + database.resetUpdateHook(); + + EXPECT_CALL(callbackMock, Call(_, _, _, _)).Times(0); + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); +} + +TEST_F(SqliteDatabase, DeleteUpdateHookCall) +{ + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + database.setUpdateHook(this, updateHookCallback); + + EXPECT_CALL(callbackMock, Call(Eq(Sqlite::ChangeType::Delete), _, _, _)); + + Sqlite::WriteStatement("DELETE FROM test WHERE name = 42", database).execute(); +} + +TEST_F(SqliteDatabase, InsertUpdateHookCall) +{ + database.setUpdateHook(this, updateHookCallback); + + EXPECT_CALL(callbackMock, Call(Eq(Sqlite::ChangeType::Insert), _, _, _)); + + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); } + +TEST_F(SqliteDatabase, UpdateUpdateHookCall) +{ + database.setUpdateHook(this, updateHookCallback); + + EXPECT_CALL(callbackMock, Call(Eq(Sqlite::ChangeType::Insert), _, _, _)); + + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); +} + +TEST_F(SqliteDatabase, RowIdUpdateHookCall) +{ + database.setUpdateHook(this, updateHookCallback); + + EXPECT_CALL(callbackMock, Call(_, _, _, Eq(42))); + + Sqlite::WriteStatement("INSERT INTO test(rowid, name) VALUES (?,?)", database).write(42, "foo"); +} + +TEST_F(SqliteDatabase, DatabaseUpdateHookCall) +{ + database.setUpdateHook(this, updateHookCallback); + + EXPECT_CALL(callbackMock, Call(_, StrEq("main"), _, _)); + + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); +} + +TEST_F(SqliteDatabase, TableUpdateHookCall) +{ + database.setUpdateHook(this, updateHookCallback); + + EXPECT_CALL(callbackMock, Call(_, _, StrEq("test"), _)); + + Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); +} + +TEST_F(SqliteDatabase, SessionsCommit) +{ + database.setAttachedTables({"test"}); + Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(1, "foo"); + + Sqlite::ImmediateSessionTransaction transaction{database}; + Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(2, "bar"); + transaction.commit(); + Sqlite::WriteStatement("INSERT OR REPLACE INTO test(id, name) VALUES (?,?)", database).write(2, "hoo"); + database.applyAndUpdateSessions(); + + ASSERT_THAT(names(), ElementsAre("foo", "bar")); +} + +TEST_F(SqliteDatabase, SessionsRollback) +{ + database.setAttachedTables({"test"}); + Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(1, "foo"); + + { + Sqlite::ImmediateSessionTransaction transaction{database}; + Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(2, "bar"); + } + Sqlite::WriteStatement("INSERT OR REPLACE INTO test(id, name) VALUES (?,?)", database).write(2, "hoo"); + database.applyAndUpdateSessions(); + + ASSERT_THAT(names(), ElementsAre("foo", "hoo")); +} + +} // namespace |