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"