File indexing completed on 2024-12-08 12:44:36

0001 // SPDX-FileCopyrightText: 2022 Jonah BrĂ¼chert <jbb@kaidan.im>
0002 //
0003 // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0004 
0005 #include <QTest>
0006 #include <QTimer>
0007 #include <QSignalSpy>
0008 
0009 #include <QCoro/QCoroTask>
0010 #include <QCoro/QCoroFuture>
0011 
0012 #include <threadeddatabase.h>
0013 
0014 #define QCORO_VERIFY(statement) \
0015 do {\
0016     if (!QTest::qVerify(static_cast<bool>(statement), #statement, "", __FILE__, __LINE__))\
0017         co_return;\
0018 } while (false)
0019 
0020 #define QCORO_COMPARE(actual, expected) \
0021 do {\
0022     if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
0023         co_return;\
0024 } while (false)
0025 
0026 struct TestCustom {
0027     using ColumnTypes = std::tuple<int, QString>;
0028 
0029     static auto fromSql(ColumnTypes &&columns) {
0030         auto [id, data] = columns;
0031         return TestCustom { id, data };
0032     }
0033 
0034 public:
0035     int id;
0036     QString data;
0037 };
0038 
0039 struct TestDefault {
0040     using ColumnTypes = std::tuple<int, QString>;
0041 
0042 public:
0043     int id;
0044     QString data;
0045 };
0046 
0047 class SqliteTest : public QObject {
0048     Q_OBJECT
0049     Q_SIGNAL void finished();
0050 
0051     static QCoro::Task<std::unique_ptr<ThreadedDatabase>> initDatabase() {
0052         DatabaseConfiguration cfg;
0053         cfg.setDatabaseName(QStringLiteral(":memory:"));
0054         cfg.setType(DatabaseType::SQLite);
0055         Q_ASSERT(cfg.type() == QStringLiteral("QSQLITE"));
0056 
0057         auto db = ThreadedDatabase::establishConnection(cfg);
0058 
0059         co_await db->execute(QStringLiteral("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, data TEXT)"));
0060         co_await db->execute(QStringLiteral("INSERT INTO test (data) VALUES (?)"), QStringLiteral("Hello World"));
0061 
0062         co_return db;
0063     }
0064 
0065     QCoro::Task<> testDeserializationCoro() {
0066         auto db = co_await initDatabase();
0067 
0068         // Custom deserializer
0069         auto opt = co_await db->getResult<TestCustom>(QStringLiteral("SELECT * FROM test LIMIT 1"));
0070         QCORO_VERIFY(opt.has_value());
0071         auto list = co_await db->getResults<TestCustom>(QStringLiteral("SELECT * FROM test"));
0072         QCORO_COMPARE(list.size(), 1);
0073         co_await db->execute(QStringLiteral("INSERT INTO test (data) VALUES (?)"), QStringLiteral("FutureSQL"));
0074         list = co_await db->getResults<TestCustom>(QStringLiteral("SELECT * from test ORDER BY id ASC"));
0075         QCORO_COMPARE(list.size(), 2);
0076         QCORO_COMPARE(list.at(0).data, u"Hello World");
0077 
0078         // default deserializer
0079         auto opt2 = co_await db->getResult<TestDefault>(QStringLiteral("SELECT * FROM test LIMIT 1"));
0080         QCORO_VERIFY(opt2.has_value());
0081         auto list2 = co_await db->getResults<TestDefault>(QStringLiteral("SELECT * from test ORDER BY id ASC"));
0082         QCORO_COMPARE(list2.size(), 2);
0083         QCORO_COMPARE(list2.at(0).data, u"Hello World");
0084 
0085         Q_EMIT finished();
0086     }
0087 
0088     QCoro::Task<> testMigrationCoro() {
0089         DatabaseConfiguration cfg;
0090         cfg.setDatabaseName(QStringLiteral(":memory:"));
0091         cfg.setType(DatabaseType::SQLite);
0092 
0093         auto db = ThreadedDatabase::establishConnection(cfg);
0094         co_await db->runMigrations(QStringLiteral(TEST_DIR "/migrations/"));
0095 
0096         Q_EMIT finished();
0097     }
0098 
0099 private Q_SLOTS:
0100     void testDeserialization() {
0101         QMetaObject::invokeMethod(this, &SqliteTest::testDeserializationCoro);
0102 
0103         QSignalSpy spy(this, &SqliteTest::finished);
0104         spy.wait();
0105         QVERIFY(spy.count() == 1);
0106     }
0107 
0108     void testMigration() {
0109         QMetaObject::invokeMethod(this, &SqliteTest::testMigrationCoro);
0110 
0111         QSignalSpy spy(this, &SqliteTest::finished);
0112         spy.wait();
0113         QVERIFY(spy.count() == 1);
0114     }
0115 };
0116 
0117 QTEST_MAIN(SqliteTest)
0118 
0119 #include "sqlitetest.moc"