1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
// SPDX-FileCopyrightText: 2022 Jonah BrĂ¼chert <jbb@kaidan.im>
//
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
#include <QTest>
#include <QTimer>
#include <QSignalSpy>
#include <QCoro/QCoroTask>
#include <QCoro/QCoroFuture>
#include <threadeddatabase.h>
#define QCORO_VERIFY(statement) \
do {\
if (!QTest::qVerify(static_cast<bool>(statement), #statement, "", __FILE__, __LINE__))\
co_return;\
} while (false)
#define QCORO_COMPARE(actual, expected) \
do {\
if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
co_return;\
} while (false)
struct TestCustom {
using ColumnTypes = std::tuple<int, QString>;
static auto fromSql(ColumnTypes &&columns) {
auto [id, data] = columns;
return TestCustom { id, data };
}
public:
int id;
QString data;
};
struct TestDefault {
using ColumnTypes = std::tuple<int, QString>;
public:
int id;
QString data;
};
class SqliteTest : public QObject {
Q_OBJECT
Q_SIGNAL void finished();
static QCoro::Task<std::unique_ptr<ThreadedDatabase>> initDatabase() {
DatabaseConfiguration cfg;
cfg.setDatabaseName(QStringLiteral(":memory:"));
cfg.setType(DatabaseType::SQLite);
Q_ASSERT(cfg.type() == QStringLiteral("QSQLITE"));
auto db = ThreadedDatabase::establishConnection(cfg);
co_await db->execute(QStringLiteral("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, data TEXT)"));
co_await db->execute(QStringLiteral("INSERT INTO test (data) VALUES (?)"), QStringLiteral("Hello World"));
co_return db;
}
QCoro::Task<> testDeserializationCoro() {
auto db = co_await initDatabase();
// Custom deserializer
auto opt = co_await db->getResult<TestCustom>(QStringLiteral("SELECT * FROM test LIMIT 1"));
QCORO_VERIFY(opt.has_value());
auto list = co_await db->getResults<TestCustom>(QStringLiteral("SELECT * FROM test"));
QCORO_COMPARE(list.size(), 1);
co_await db->execute(QStringLiteral("INSERT INTO test (data) VALUES (?)"), QStringLiteral("FutureSQL"));
list = co_await db->getResults<TestCustom>(QStringLiteral("SELECT * from test ORDER BY id ASC"));
QCORO_COMPARE(list.size(), 2);
QCORO_COMPARE(list.at(0).data, u"Hello World");
// default deserializer
auto opt2 = co_await db->getResult<TestDefault>(QStringLiteral("SELECT * FROM test LIMIT 1"));
QCORO_VERIFY(opt2.has_value());
auto list2 = co_await db->getResults<TestDefault>(QStringLiteral("SELECT * from test ORDER BY id ASC"));
QCORO_COMPARE(list2.size(), 2);
QCORO_COMPARE(list2.at(0).data, u"Hello World");
Q_EMIT finished();
}
QCoro::Task<> testMigrationCoro() {
DatabaseConfiguration cfg;
cfg.setDatabaseName(QStringLiteral(":memory:"));
cfg.setType(DatabaseType::SQLite);
auto db = ThreadedDatabase::establishConnection(cfg);
co_await db->runMigrations(QStringLiteral(TEST_DIR "/migrations/"));
Q_EMIT finished();
}
private Q_SLOTS:
void testDeserialization() {
QMetaObject::invokeMethod(this, &SqliteTest::testDeserializationCoro);
QSignalSpy spy(this, &SqliteTest::finished);
spy.wait();
QVERIFY(spy.count() == 1);
}
void testMigration() {
QMetaObject::invokeMethod(this, &SqliteTest::testMigrationCoro);
QSignalSpy spy(this, &SqliteTest::finished);
spy.wait();
QVERIFY(spy.count() == 1);
}
};
QTEST_MAIN(SqliteTest)
#include "sqlitetest.moc"
|