File indexing completed on 2024-03-24 16:10:47

0001 /* This file is part of the KDE project
0002    Copyright (C) 2015-2019 Jarosław Staniek <staniek@kde.org>
0003 
0004    This program is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This program is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this program; see the file COPYING.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KDB_TESTUTILS_H
0021 #define KDB_TESTUTILS_H
0022 
0023 #include "kdbtestutils_export.h"
0024 
0025 #include <KDbConnection>
0026 #include <KDbConnectionOptions>
0027 #include <KDbDriver>
0028 #include <KDbDriverManager>
0029 
0030 #include <QPointer>
0031 #include <QTest>
0032 
0033 class KDbNativeStatementBuilder;
0034 
0035 Q_DECLARE_METATYPE(KDbField::TypeGroup)
0036 Q_DECLARE_METATYPE(KDbField::Type)
0037 Q_DECLARE_METATYPE(KDb::Signedness)
0038 Q_DECLARE_METATYPE(QList<KDbField::Type>)
0039 Q_DECLARE_METATYPE(KDb::BLOBEscapingType)
0040 
0041 //! @internal for KDB_VERIFY
0042 template<typename T>
0043 const T* KDB_POINTER_WRAPPER(const T &t) { return &t; }
0044 
0045 //! @internal for KDB_VERIFY
0046 template<typename T>
0047 const T* KDB_POINTER_WRAPPER(const T *t) { return t; }
0048 
0049 //! @internal for KDB_VERIFY
0050 template<typename T>
0051 T* KDB_POINTER_WRAPPER(T *t) { return t; }
0052 
0053 //! @internal for KDB_VERIFY
0054 template<typename T>
0055 T* KDB_POINTER_WRAPPER(const QPointer<T> &t) { return t.data(); }
0056 
0057 //! @internal for KDB_VERIFY
0058 template<typename T>
0059 T* KDB_POINTER_WRAPPER(const QScopedPointer<T> &t) { return t.data(); }
0060 
0061 namespace QTest
0062 {
0063 KDBTESTUTILS_EXPORT bool qCompare(const KDbEscapedString &val1, const KDbEscapedString &val2,
0064                                   const char *actual, const char *expected, const char *file,
0065                                   int line);
0066 KDBTESTUTILS_EXPORT bool qCompare(const KDbEscapedString &val1, const char *val2,
0067                                   const char *actual, const char *expected, const char *file,
0068                                   int line);
0069 KDBTESTUTILS_EXPORT bool qCompare(const char *val1, const KDbEscapedString &val2,
0070                                   const char *actual, const char *expected, const char *file,
0071                                   int line);
0072 KDBTESTUTILS_EXPORT bool qCompare(const KDbEscapedString &val1, const QString &val2,
0073                                   const char *actual, const char *expected, const char *file,
0074                                   int line);
0075 KDBTESTUTILS_EXPORT bool qCompare(const QString &val1, const KDbEscapedString &val2,
0076                                   const char *actual, const char *expected, const char *file,
0077                                   int line);
0078 
0079 KDBTESTUTILS_EXPORT bool qCompare(const QStringList &val1, const QStringList &val2,
0080                                   const char *actual, const char *expected, const char *file,
0081                                   int line);
0082 
0083 KDBTESTUTILS_EXPORT bool qCompare(const QByteArray &val1, const char *val2, const char *actual,
0084                                   const char *expected, const char *file, int line);
0085 KDBTESTUTILS_EXPORT bool qCompare(const QString &val1, const char *val2, const char *actual,
0086                                   const char *expected, const char *file, int line);
0087 }
0088 
0089 //! Calls @a call and verifies status of @a resultable
0090 //! On error displays the status on debug and does the same as QVERIFY with @a errorMessage
0091 #define KDB_VERIFY(resultable, call, errorMessage) \
0092     do { \
0093         bool KDB_VERIFY_ok = (call); \
0094         const KDbResultable *KDB_VERIFY_resultablePtr = KDB_POINTER_WRAPPER(resultable); \
0095         if (KDB_VERIFY_resultablePtr->result().isError()) { \
0096             qDebug() << KDB_VERIFY_resultablePtr->result(); \
0097         } \
0098         if (!QTest::qVerify(KDB_VERIFY_ok && !KDB_VERIFY_resultablePtr->result().isError(), # call, (errorMessage), __FILE__, __LINE__)) {\
0099             return; \
0100         } \
0101     } \
0102     while (false)
0103 
0104 //! Calls @a call and verifies status of @a resultable
0105 //! On error displays the status on debug and does the same as QVERIFY with @a errorMessage
0106 #define KDB_EXPECT_FAIL(resultable, call, expectedErrorCode, errorMessage) \
0107     do { \
0108         bool KDB_VERIFY_ok = (call); \
0109         const KDbResultable *KDB_VERIFY_resultablePtr = KDB_POINTER_WRAPPER(resultable); \
0110         if (KDB_VERIFY_resultablePtr->result().isError()) { \
0111             qDebug() << KDB_VERIFY_resultablePtr->result(); \
0112         } \
0113         QVERIFY(KDB_VERIFY_resultablePtr->result().isError()); \
0114         if (!QTest::qVerify(!KDB_VERIFY_ok, # call, (errorMessage), __FILE__, __LINE__)) {\
0115             return; \
0116         } \
0117         if (!QTest::qCompare(KDB_VERIFY_resultablePtr->result().code(), expectedErrorCode, # call, # expectedErrorCode, __FILE__, __LINE__)) {\
0118             return; \
0119         } \
0120     } \
0121     while (false)
0122 
0123 //! Declares method @a name that returns false on test failure, it can be called as utility function.
0124 //! Also declared internal method name ## Internal which performs the actual test.
0125 //! This way users of this method can call QVERIFY(utils.<name>());
0126 #define KDBTEST_METHOD_DECL(name, argsDecl, args) \
0127 public: \
0128     Q_REQUIRED_RESULT bool name argsDecl { name ## Internal args ; return !QTest::currentTestFailed(); } \
0129 private Q_SLOTS: \
0130     void name ## Internal argsDecl
0131 
0132 //! Test utilities that provide basic database features
0133 class KDBTESTUTILS_EXPORT KDbTestUtils : public QObject
0134 {
0135     Q_OBJECT
0136 public:
0137     KDbTestUtils();
0138 
0139     ~KDbTestUtils();
0140 
0141     KDbDriverManager manager;
0142     QPointer<KDbDriver> driver;
0143 
0144     /**
0145      * Returns associated connection
0146      */
0147     KDbConnection* connection();
0148 
0149     /**
0150      * Returns builder for generating KDb SQL statements
0151      */
0152     KDbNativeStatementBuilder* kdbBuilder();
0153 
0154     /**
0155      * Returns builder for generating driver-native SQL statements
0156      */
0157     KDbNativeStatementBuilder* driverBuilder();
0158 
0159     KDBTEST_METHOD_DECL(testDriverManager, (), ());
0160     KDBTEST_METHOD_DECL(testSqliteDriver, (), ());
0161 
0162     //! Connects to a database
0163     //! @since 3.2
0164     KDBTEST_METHOD_DECL(testConnect,
0165                         (const KDbConnectionData &cdata,
0166                          const KDbConnectionOptions &options = KDbConnectionOptions()),
0167                         (cdata, options));
0168 
0169     KDBTEST_METHOD_DECL(testUse, (), ());
0170 
0171     //! Convenience method that performs testConnect and testUse in one go
0172     //! @since 3.2
0173     KDBTEST_METHOD_DECL(testConnectAndUse,
0174                         (const KDbConnectionData &cdata,
0175                          const KDbConnectionOptions &options = KDbConnectionOptions()),
0176                         (cdata, options));
0177 
0178     //! Overload of testConnectAndUse for file-based databases
0179     //! @since 3.2
0180     KDBTEST_METHOD_DECL(testConnectAndUse,
0181                         (const QString &path,
0182                          const KDbConnectionOptions &options = KDbConnectionOptions()),
0183                         (path, options));
0184 
0185     //! Creates database with name @a dbName
0186     //! Does not use the database.
0187     //! @todo don't hardcode SQLite here
0188     //! @note dbName should not include ".kexi" extension or path
0189     KDBTEST_METHOD_DECL(testCreateDb, (const QString &dbName), (dbName));
0190 
0191     //! Creates database with name @a dbName, then uses it and creates test tables
0192     //! The database stays used.
0193     //! @note dbName should not include ".kexi" extension or path
0194     KDBTEST_METHOD_DECL(testCreateDbWithTables, (const QString &dbName), (dbName));
0195     KDBTEST_METHOD_DECL(testProperties, (), ());
0196     KDBTEST_METHOD_DECL(testCreateTables, (), ());
0197     KDBTEST_METHOD_DECL(testDisconnect, (), ());
0198     KDBTEST_METHOD_DECL(testDropDb, (), ());
0199     KDBTEST_METHOD_DECL(testDisconnectAndDropDb, (), ());
0200 
0201 protected:
0202     void testDisconnectPrivate();
0203     void testDriver(const QString &driverId, bool fileBased, const QStringList &expectedMimeTypes,
0204                     const QStringList &possiblyInvalidMimeTypes);
0205     void testDriverManagerInternal(bool forceEmpty);
0206 
0207 private:
0208     Q_DISABLE_COPY(KDbTestUtils)
0209     class Private;
0210     Private * const d;
0211 };
0212 
0213 #endif