Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:12:23

0001 // Copyright (C) 2021 The Qt Company Ltd.
0002 // Copyright (C) 2020 Intel Corporation.
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0004 
0005 #ifndef QTEST_H
0006 #define QTEST_H
0007 
0008 #if 0
0009 #pragma qt_class(QTest)
0010 #endif
0011 
0012 #include <QtTest/qttestglobal.h>
0013 #include <QtTest/qtestcase.h>
0014 #include <QtTest/qtestdata.h>
0015 #include <QtTest/qbenchmark.h>
0016 
0017 #include <QtCore/qbitarray.h>
0018 #include <QtCore/qbytearray.h>
0019 #include <QtCore/qcborarray.h>
0020 #include <QtCore/qcborcommon.h>
0021 #include <QtCore/qcbormap.h>
0022 #include <QtCore/qcborvalue.h>
0023 #include <QtCore/qstring.h>
0024 #include <QtCore/qstringlist.h>
0025 #include <QtCore/qcborcommon.h>
0026 #include <QtCore/qdatetime.h>
0027 #if QT_CONFIG(itemmodel)
0028 #include <QtCore/qabstractitemmodel.h>
0029 #endif
0030 #include <QtCore/qobject.h>
0031 #include <QtCore/qvariant.h>
0032 #include <QtCore/qurl.h>
0033 #include <QtCore/quuid.h>
0034 
0035 #if defined(TESTCASE_LOWDPI)
0036 #include <QtCore/qcoreapplication.h>
0037 #endif
0038 
0039 #include <QtCore/qpoint.h>
0040 #include <QtCore/qsize.h>
0041 #include <QtCore/qrect.h>
0042 
0043 #include <initializer_list>
0044 #include <memory>
0045 
0046 QT_BEGIN_NAMESPACE
0047 
0048 namespace QTest
0049 {
0050 
0051 template <> inline char *toString(const QStringView &str)
0052 {
0053     return QTest::toPrettyUnicode(str);
0054 }
0055 
0056 template<> inline char *toString(const QString &str)
0057 {
0058     return toString(QStringView(str));
0059 }
0060 
0061 template<> inline char *toString(const QLatin1StringView &str)
0062 {
0063     return toString(QString(str));
0064 }
0065 
0066 template<> inline char *toString(const QByteArray &ba)
0067 {
0068     return QTest::toPrettyCString(ba.constData(), ba.size());
0069 }
0070 
0071 template<> inline char *toString(const QBitArray &ba)
0072 {
0073     qsizetype size = ba.size();
0074     char *str = new char[size + 1];
0075     for (qsizetype i = 0; i < size; ++i)
0076         str[i] = "01"[ba.testBit(i)];
0077     str[size] = '\0';
0078     return str;
0079 }
0080 
0081 #if QT_CONFIG(datestring)
0082 template<> inline char *toString(const QTime &time)
0083 {
0084     return time.isValid()
0085         ? qstrdup(qPrintable(time.toString(u"hh:mm:ss.zzz")))
0086         : qstrdup("Invalid QTime");
0087 }
0088 
0089 template<> inline char *toString(const QDate &date)
0090 {
0091     return date.isValid()
0092         ? qstrdup(qPrintable(date.toString(u"yyyy/MM/dd")))
0093         : qstrdup("Invalid QDate");
0094 }
0095 
0096 template<> inline char *toString(const QDateTime &dateTime)
0097 {
0098     return dateTime.isValid()
0099         ? qstrdup(qPrintable(dateTime.toString(u"yyyy/MM/dd hh:mm:ss.zzz[t]")))
0100         : qstrdup("Invalid QDateTime");
0101 }
0102 #endif // datestring
0103 
0104 template<> inline char *toString(const QCborError &c)
0105 {
0106     // use the Q_ENUM formatting
0107     return toString(c.c);
0108 }
0109 
0110 template<> inline char *toString(const QChar &c)
0111 {
0112     const ushort uc = c.unicode();
0113     if (uc < 128) {
0114         char msg[32] = {'\0'};
0115         qsnprintf(msg, sizeof(msg), "QChar: '%c' (0x%x)", char(uc), unsigned(uc));
0116         return qstrdup(msg);
0117     }
0118     return qstrdup(qPrintable(QString::fromLatin1("QChar: '%1' (0x%2)").arg(c).arg(QString::number(static_cast<int>(c.unicode()), 16))));
0119 }
0120 
0121 #if QT_CONFIG(itemmodel)
0122 template<> inline char *toString(const QModelIndex &idx)
0123 {
0124     char msg[128];
0125     qsnprintf(msg, sizeof(msg), "QModelIndex(%d,%d,%p,%p)", idx.row(), idx.column(), idx.internalPointer(), idx.model());
0126     return qstrdup(msg);
0127 }
0128 #endif
0129 
0130 template<> inline char *toString(const QPoint &p)
0131 {
0132     char msg[128] = {'\0'};
0133     qsnprintf(msg, sizeof(msg), "QPoint(%d,%d)", p.x(), p.y());
0134     return qstrdup(msg);
0135 }
0136 
0137 template<> inline char *toString(const QSize &s)
0138 {
0139     char msg[128] = {'\0'};
0140     qsnprintf(msg, sizeof(msg), "QSize(%dx%d)", s.width(), s.height());
0141     return qstrdup(msg);
0142 }
0143 
0144 template<> inline char *toString(const QRect &s)
0145 {
0146     char msg[256] = {'\0'};
0147     qsnprintf(msg, sizeof(msg), "QRect(%d,%d %dx%d) (bottomright %d,%d)",
0148               s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom());
0149     return qstrdup(msg);
0150 }
0151 
0152 template<> inline char *toString(const QPointF &p)
0153 {
0154     char msg[64] = {'\0'};
0155     qsnprintf(msg, sizeof(msg), "QPointF(%g,%g)", p.x(), p.y());
0156     return qstrdup(msg);
0157 }
0158 
0159 template<> inline char *toString(const QSizeF &s)
0160 {
0161     char msg[64] = {'\0'};
0162     qsnprintf(msg, sizeof(msg), "QSizeF(%gx%g)", s.width(), s.height());
0163     return qstrdup(msg);
0164 }
0165 
0166 template<> inline char *toString(const QRectF &s)
0167 {
0168     char msg[256] = {'\0'};
0169     qsnprintf(msg, sizeof(msg), "QRectF(%g,%g %gx%g) (bottomright %g,%g)",
0170               s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom());
0171     return qstrdup(msg);
0172 }
0173 
0174 template<> inline char *toString(const QUrl &uri)
0175 {
0176     if (!uri.isValid())
0177         return qstrdup(qPrintable(QLatin1StringView("Invalid URL: ") + uri.errorString()));
0178     return qstrdup(uri.toEncoded().constData());
0179 }
0180 
0181 template <> inline char *toString(const QUuid &uuid)
0182 {
0183     return qstrdup(uuid.toByteArray().constData());
0184 }
0185 
0186 template<> inline char *toString(const QVariant &v)
0187 {
0188     QByteArray vstring("QVariant(");
0189     if (v.isValid()) {
0190         QByteArray type(v.typeName());
0191         if (type.isEmpty()) {
0192             type = QByteArray::number(v.userType());
0193         }
0194         vstring.append(type);
0195         if (!v.isNull()) {
0196             vstring.append(',');
0197             if (v.canConvert<QString>()) {
0198                 vstring.append(v.toString().toLocal8Bit());
0199             }
0200             else {
0201                 vstring.append("<value not representable as string>");
0202             }
0203         }
0204     }
0205     vstring.append(')');
0206 
0207     return qstrdup(vstring.constData());
0208 }
0209 
0210 template<> inline char *toString(const QPartialOrdering &o)
0211 {
0212     if (o == QPartialOrdering::Less)
0213         return qstrdup("Less");
0214     if (o == QPartialOrdering::Equivalent)
0215         return qstrdup("Equivalent");
0216     if (o == QPartialOrdering::Greater)
0217         return qstrdup("Greater");
0218     if (o == QPartialOrdering::Unordered)
0219         return qstrdup("Unordered");
0220     return qstrdup("<invalid>");
0221 }
0222 
0223 namespace Internal {
0224 struct QCborValueFormatter
0225 {
0226     enum { BufferLen = 256 };
0227     static char *formatSimpleType(QCborSimpleType st)
0228     {
0229         char *buf = new char[BufferLen];
0230         qsnprintf(buf, BufferLen, "QCborValue(QCborSimpleType(%d))", int(st));
0231         return buf;
0232     }
0233 
0234     static char *formatTag(QCborTag tag, const QCborValue &taggedValue)
0235     {
0236         QScopedArrayPointer<char> hold(format(taggedValue));
0237         char *buf = new char[BufferLen];
0238         qsnprintf(buf, BufferLen, "QCborValue(QCborTag(%llu), %s)", tag, hold.get());
0239         return buf;
0240     }
0241 
0242     static char *innerFormat(QCborValue::Type t, const char *str)
0243     {
0244         static const QMetaEnum typeEnum = []() {
0245             int idx = QCborValue::staticMetaObject.indexOfEnumerator("Type");
0246             return QCborValue::staticMetaObject.enumerator(idx);
0247         }();
0248 
0249         char *buf = new char[BufferLen];
0250         const char *typeName = typeEnum.valueToKey(t);
0251         if (typeName)
0252             qsnprintf(buf, BufferLen, "QCborValue(%s, %s)", typeName, str);
0253         else
0254             qsnprintf(buf, BufferLen, "QCborValue(<unknown type 0x%02x>)", t);
0255         return buf;
0256     }
0257 
0258     template<typename T> static char *format(QCborValue::Type type, const T &t)
0259     {
0260         QScopedArrayPointer<char> hold(QTest::toString(t));
0261         return innerFormat(type, hold.get());
0262     }
0263 
0264     static char *format(const QCborValue &v)
0265     {
0266         switch (v.type()) {
0267         case QCborValue::Integer:
0268             return format(v.type(), v.toInteger());
0269         case QCborValue::ByteArray:
0270             return format(v.type(), v.toByteArray());
0271         case QCborValue::String:
0272             return format(v.type(), v.toString());
0273         case QCborValue::Array:
0274             return innerFormat(v.type(), QScopedArrayPointer<char>(format(v.toArray())).get());
0275         case QCborValue::Map:
0276             return innerFormat(v.type(), QScopedArrayPointer<char>(format(v.toMap())).get());
0277         case QCborValue::Tag:
0278             return formatTag(v.tag(), v.taggedValue());
0279         case QCborValue::SimpleType:
0280             break;
0281         case QCborValue::True:
0282             return qstrdup("QCborValue(true)");
0283         case QCborValue::False:
0284             return qstrdup("QCborValue(false)");
0285         case QCborValue::Null:
0286             return qstrdup("QCborValue(nullptr)");
0287         case QCborValue::Undefined:
0288             return qstrdup("QCborValue()");
0289         case QCborValue::Double:
0290             return format(v.type(), v.toDouble());
0291         case QCborValue::DateTime:
0292         case QCborValue::Url:
0293         case QCborValue::RegularExpression:
0294             return format(v.type(), v.taggedValue().toString());
0295         case QCborValue::Uuid:
0296             return format(v.type(), v.toUuid());
0297         case QCborValue::Invalid:
0298             return qstrdup("QCborValue(<invalid>)");
0299         }
0300 
0301         if (v.isSimpleType())
0302             return formatSimpleType(v.toSimpleType());
0303         return innerFormat(v.type(), "");
0304     }
0305 
0306     static char *format(const QCborArray &a)
0307     {
0308         QByteArray out(1, '[');
0309         const char *comma = "";
0310         for (QCborValueConstRef v : a) {
0311             QScopedArrayPointer<char> s(format(v));
0312             out += comma;
0313             out += s.get();
0314             comma = ", ";
0315         }
0316         out += ']';
0317         return qstrdup(out.constData());
0318     }
0319 
0320     static char *format(const QCborMap &m)
0321     {
0322         QByteArray out(1, '{');
0323         const char *comma = "";
0324         for (auto pair : m) {
0325             QScopedArrayPointer<char> key(format(pair.first));
0326             QScopedArrayPointer<char> value(format(pair.second));
0327             out += comma;
0328             out += key.get();
0329             out += ": ";
0330             out += value.get();
0331             comma = ", ";
0332         }
0333         out += '}';
0334         return qstrdup(out.constData());
0335     }
0336 };
0337 }
0338 
0339 template<> inline char *toString(const QCborValue &v)
0340 {
0341     return Internal::QCborValueFormatter::format(v);
0342 }
0343 
0344 template<> inline char *toString(const QCborValueRef &v)
0345 {
0346     return toString(QCborValue(v));
0347 }
0348 
0349 template<> inline char *toString(const QCborArray &a)
0350 {
0351     return Internal::QCborValueFormatter::format(a);
0352 }
0353 
0354 template<> inline char *toString(const QCborMap &m)
0355 {
0356     return Internal::QCborValueFormatter::format(m);
0357 }
0358 
0359 template <typename Rep, typename Period> char *toString(std::chrono::duration<Rep, Period> dur)
0360 {
0361     QString r;
0362     QDebug d(&r);
0363     d.nospace() << qSetRealNumberPrecision(9) << dur;
0364     if constexpr (Period::num != 1 || Period::den != 1) {
0365         // include the equivalent value in seconds, in parentheses
0366         using namespace std::chrono;
0367         d << " (" << duration_cast<duration<qreal>>(dur).count() << "s)";
0368     }
0369     return qstrdup(std::move(r).toUtf8().constData());
0370 }
0371 
0372 template <typename T1, typename T2>
0373 inline char *toString(const std::pair<T1, T2> &pair)
0374 {
0375     const QScopedArrayPointer<char> first(toString(pair.first));
0376     const QScopedArrayPointer<char> second(toString(pair.second));
0377     return formatString("std::pair(", ")", 2, first.data(), second.data());
0378 }
0379 
0380 template <typename Tuple, std::size_t... I>
0381 inline char *tupleToString(const Tuple &tuple, std::index_sequence<I...>) {
0382     using UP = std::unique_ptr<char[]>;
0383     // Generate a table of N + 1 elements where N is the number of
0384     // elements in the tuple.
0385     // The last element is needed to support the empty tuple use case.
0386     const UP data[] = {
0387         UP(toString(std::get<I>(tuple)))..., UP{}
0388     };
0389     return formatString("std::tuple(", ")", sizeof...(I), data[I].get()...);
0390 }
0391 
0392 template <class... Types>
0393 inline char *toString(const std::tuple<Types...> &tuple)
0394 {
0395     return tupleToString(tuple, std::make_index_sequence<sizeof...(Types)>{});
0396 }
0397 
0398 inline char *toString(std::nullptr_t)
0399 {
0400     return toString(QStringView(u"nullptr"));
0401 }
0402 
0403 template<>
0404 inline bool qCompare(QString const &t1, QLatin1StringView const &t2, const char *actual,
0405                      const char *expected, const char *file, int line)
0406 {
0407     return qCompare(t1, QString(t2), actual, expected, file, line);
0408 }
0409 template<>
0410 inline bool qCompare(QLatin1StringView const &t1, QString const &t2, const char *actual,
0411                      const char *expected, const char *file, int line)
0412 {
0413     return qCompare(QString(t1), t2, actual, expected, file, line);
0414 }
0415 
0416 // Compare sequences of equal size
0417 template <typename ActualIterator, typename ExpectedIterator>
0418 bool _q_compareSequence(ActualIterator actualIt, ActualIterator actualEnd,
0419                         ExpectedIterator expectedBegin, ExpectedIterator expectedEnd,
0420                         const char *actual, const char *expected,
0421                         const char *file, int line)
0422 {
0423     char msg[1024];
0424     msg[0] = '\0';
0425 
0426     const qsizetype actualSize = actualEnd - actualIt;
0427     const qsizetype expectedSize = expectedEnd - expectedBegin;
0428     bool isOk = actualSize == expectedSize;
0429 
0430     if (!isOk) {
0431         qsnprintf(msg, sizeof(msg), "Compared lists have different sizes.\n"
0432                   "   Actual   (%s) size: %zd\n"
0433                   "   Expected (%s) size: %zd", actual, actualSize,
0434                   expected, expectedSize);
0435     }
0436 
0437     for (auto expectedIt = expectedBegin; isOk && expectedIt < expectedEnd; ++actualIt, ++expectedIt) {
0438         if (!(*actualIt == *expectedIt)) {
0439             const qsizetype i = qsizetype(expectedIt - expectedBegin);
0440             char *val1 = toString(*actualIt);
0441             char *val2 = toString(*expectedIt);
0442 
0443             qsnprintf(msg, sizeof(msg), "Compared lists differ at index %zd.\n"
0444                       "   Actual   (%s): %s\n"
0445                       "   Expected (%s): %s", i, actual, val1 ? val1 : "<null>",
0446                       expected, val2 ? val2 : "<null>");
0447             isOk = false;
0448 
0449             delete [] val1;
0450             delete [] val2;
0451         }
0452     }
0453     return compare_helper(isOk, msg, actual, expected, file, line);
0454 }
0455 
0456 namespace Internal {
0457 
0458 #if defined(TESTCASE_LOWDPI)
0459 void disableHighDpi()
0460 {
0461     qputenv("QT_ENABLE_HIGHDPI_SCALING", "0");
0462 }
0463 Q_CONSTRUCTOR_FUNCTION(disableHighDpi);
0464 #endif
0465 
0466 } // namespace Internal
0467 
0468 template <typename T>
0469 inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual, const char *expected,
0470                      const char *file, int line)
0471 {
0472     return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
0473                                      actual, expected, file, line);
0474 }
0475 
0476 template <typename T, int N>
0477 bool qCompare(QList<T> const &t1, std::initializer_list<T> t2,
0478               const char *actual, const char *expected,
0479               const char *file, int line)
0480 {
0481     return _q_compareSequence(t1.cbegin(), t1.cend(), t2.cbegin(), t2.cend(),
0482                                      actual, expected, file, line);
0483 }
0484 
0485 // Compare QList against array
0486 template <typename T, int N>
0487 bool qCompare(QList<T> const &t1, const T (& t2)[N],
0488               const char *actual, const char *expected,
0489               const char *file, int line)
0490 {
0491     return _q_compareSequence(t1.cbegin(), t1.cend(), t2, t2 + N,
0492                                      actual, expected, file, line);
0493 }
0494 
0495 template <typename T>
0496 inline bool qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected,
0497                     const char *file, int line)
0498 {
0499     using Int = typename QFlags<T>::Int;
0500     return qCompare(Int(t1), Int(t2), actual, expected, file, line);
0501 }
0502 
0503 template <typename T>
0504 inline bool qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected,
0505                     const char *file, int line)
0506 {
0507     using Int = typename QFlags<T>::Int;
0508     return qCompare(Int(t1), Int(t2), actual, expected, file, line);
0509 }
0510 
0511 template<>
0512 inline bool qCompare(qint64 const &t1, qint32 const &t2, const char *actual,
0513                     const char *expected, const char *file, int line)
0514 {
0515     return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
0516 }
0517 
0518 template<>
0519 inline bool qCompare(qint64 const &t1, quint32 const &t2, const char *actual,
0520                     const char *expected, const char *file, int line)
0521 {
0522     return qCompare(t1, static_cast<qint64>(t2), actual, expected, file, line);
0523 }
0524 
0525 template<>
0526 inline bool qCompare(quint64 const &t1, quint32 const &t2, const char *actual,
0527                     const char *expected, const char *file, int line)
0528 {
0529     return qCompare(t1, static_cast<quint64>(t2), actual, expected, file, line);
0530 }
0531 
0532 template<>
0533 inline bool qCompare(qint32 const &t1, qint64 const &t2, const char *actual,
0534                     const char *expected, const char *file, int line)
0535 {
0536     return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
0537 }
0538 
0539 template<>
0540 inline bool qCompare(quint32 const &t1, qint64 const &t2, const char *actual,
0541                     const char *expected, const char *file, int line)
0542 {
0543     return qCompare(static_cast<qint64>(t1), t2, actual, expected, file, line);
0544 }
0545 
0546 template<>
0547 inline bool qCompare(quint32 const &t1, quint64 const &t2, const char *actual,
0548                     const char *expected, const char *file, int line)
0549 {
0550     return qCompare(static_cast<quint64>(t1), t2, actual, expected, file, line);
0551 }
0552 namespace Internal {
0553 
0554 template <typename T>
0555 class HasInitMain // SFINAE test for the presence of initMain()
0556 {
0557 private:
0558     using YesType = char[1];
0559     using NoType = char[2];
0560 
0561     template <typename C> static YesType& test( decltype(&C::initMain) ) ;
0562     template <typename C> static NoType& test(...);
0563 
0564 public:
0565     enum { value = sizeof(test<T>(nullptr)) == sizeof(YesType) };
0566 };
0567 
0568 template<typename T>
0569 typename std::enable_if<HasInitMain<T>::value, void>::type callInitMain()
0570 {
0571     T::initMain();
0572 }
0573 
0574 template<typename T>
0575 typename std::enable_if<!HasInitMain<T>::value, void>::type callInitMain()
0576 {
0577 }
0578 
0579 } // namespace Internal
0580 
0581 } // namespace QTest
0582 QT_END_NAMESPACE
0583 
0584 #ifdef QT_TESTCASE_BUILDDIR
0585 #  define QTEST_SET_MAIN_SOURCE_PATH  QTest::setMainSourcePath(__FILE__, QT_TESTCASE_BUILDDIR);
0586 #else
0587 #  define QTEST_SET_MAIN_SOURCE_PATH  QTest::setMainSourcePath(__FILE__);
0588 #endif
0589 
0590 // Hooks for coverage-testing of QTestLib itself:
0591 #if QT_CONFIG(testlib_selfcover) && defined(__COVERAGESCANNER__)
0592 struct QtCoverageScanner
0593 {
0594     QtCoverageScanner(const char *name)
0595     {
0596         __coveragescanner_clear();
0597         __coveragescanner_testname(name);
0598     }
0599     ~QtCoverageScanner()
0600     {
0601         __coveragescanner_save();
0602         __coveragescanner_testname("");
0603     }
0604 };
0605 #define TESTLIB_SELFCOVERAGE_START(name) QtCoverageScanner _qtCoverageScanner(name);
0606 #else
0607 #define TESTLIB_SELFCOVERAGE_START(name)
0608 #endif
0609 
0610 #if !defined(QTEST_BATCH_TESTS)
0611 // Internal (but used by some testlib selftests to hack argc and argv).
0612 // Tests should normally implement initMain() if they have set-up to do before
0613 // instantiating the test class.
0614 #define QTEST_MAIN_WRAPPER(TestObject, ...) \
0615 int main(int argc, char *argv[]) \
0616 { \
0617     TESTLIB_SELFCOVERAGE_START(#TestObject) \
0618     QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
0619     __VA_ARGS__ \
0620     TestObject tc; \
0621     QTEST_SET_MAIN_SOURCE_PATH \
0622     return QTest::qExec(&tc, argc, argv); \
0623 }
0624 #else
0625 // BATCHED_TEST_NAME is defined for each test in a batch in cmake. Some odd
0626 // targets, like snippets, don't define it though. Play safe by providing a
0627 // default value.
0628 #if !defined(BATCHED_TEST_NAME)
0629 #define BATCHED_TEST_NAME "other"
0630 #endif
0631 #define QTEST_MAIN_WRAPPER(TestObject, ...) \
0632 \
0633 void qRegister##TestObject() \
0634 { \
0635     auto runTest = [](int argc, char** argv) -> int { \
0636         TESTLIB_SELFCOVERAGE_START(TestObject) \
0637         QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
0638         __VA_ARGS__ \
0639         TestObject tc; \
0640         QTEST_SET_MAIN_SOURCE_PATH \
0641         return QTest::qExec(&tc, argc, argv); \
0642     }; \
0643     QTest::qRegisterTestCase(QStringLiteral(BATCHED_TEST_NAME), runTest); \
0644 } \
0645 \
0646 Q_CONSTRUCTOR_FUNCTION(qRegister##TestObject)
0647 #endif
0648 
0649 // For when you don't even want a QApplication:
0650 #define QTEST_APPLESS_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject)
0651 
0652 #include <QtTest/qtestsystem.h>
0653 
0654 #if defined(QT_NETWORK_LIB)
0655 #  include <QtTest/qtest_network.h>
0656 #endif
0657 
0658 // Internal
0659 #define QTEST_QAPP_SETUP(klaz) \
0660     klaz app(argc, argv); \
0661     app.setAttribute(Qt::AA_Use96Dpi, true);
0662 
0663 #if defined(QT_WIDGETS_LIB)
0664 #  include <QtTest/qtest_widgets.h>
0665 #  ifdef QT_KEYPAD_NAVIGATION
0666 #    define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone);
0667 #  else
0668 #    define QTEST_DISABLE_KEYPAD_NAVIGATION
0669 #  endif
0670 // Internal
0671 #  define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QApplication) QTEST_DISABLE_KEYPAD_NAVIGATION
0672 #elif defined(QT_GUI_LIB)
0673 #  include <QtTest/qtest_gui.h>
0674 // Internal
0675 #  define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QGuiApplication)
0676 #else
0677 // Internal
0678 #  define QTEST_MAIN_SETUP() QTEST_QAPP_SETUP(QCoreApplication)
0679 #endif // QT_GUI_LIB
0680 
0681 // For most tests:
0682 #define QTEST_MAIN(TestObject) QTEST_MAIN_WRAPPER(TestObject, QTEST_MAIN_SETUP())
0683 
0684 // For command-line tests
0685 #define QTEST_GUILESS_MAIN(TestObject) \
0686     QTEST_MAIN_WRAPPER(TestObject, QTEST_QAPP_SETUP(QCoreApplication))
0687 
0688 #endif