aboutsummaryrefslogtreecommitdiffstats
path: root/tests/unit/unittest/sqlitedatabase-test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/unittest/sqlitedatabase-test.cpp')
-rw-r--r--tests/unit/unittest/sqlitedatabase-test.cpp140
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