diff options
Diffstat (limited to 'tests')
294 files changed, 6430 insertions, 1153 deletions
diff --git a/tests/auto/cmake/test_moc_macro_target/interface/myinterface.h b/tests/auto/cmake/test_moc_macro_target/interface/myinterface.h index 2558406486..becfe3037c 100644 --- a/tests/auto/cmake/test_moc_macro_target/interface/myinterface.h +++ b/tests/auto/cmake/test_moc_macro_target/interface/myinterface.h @@ -34,11 +34,17 @@ #ifndef MYINTERFACE_H #define MYINTERFACE_H +#include <qglobal.h> + class MyInterface { }; +QT_BEGIN_NAMESPACE + Q_DECLARE_INTERFACE(MyInterface, "org.cmake.example.MyInterface") +QT_END_NAMESPACE + #endif diff --git a/tests/auto/corelib/global/qflags/qflags.pro b/tests/auto/corelib/global/qflags/qflags.pro index 9e80d5634b..3f78bc045b 100644 --- a/tests/auto/corelib/global/qflags/qflags.pro +++ b/tests/auto/corelib/global/qflags/qflags.pro @@ -3,3 +3,4 @@ TARGET = tst_qflags QT = core testlib SOURCES = tst_qflags.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +contains(QT_CONFIG, c++11): CONFIG += c++11 c++14 diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 4c74ac166b..15fe93298d 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -94,6 +94,16 @@ void tst_QFlags::testFlagMultiBits() const template <unsigned int N, typename T> bool verifyConstExpr(T n) { return n == N; } +Q_DECL_RELAXED_CONSTEXPR Qt::MouseButtons testRelaxedConstExpr() +{ + Qt::MouseButtons value; + value = Qt::LeftButton | Qt::RightButton; + value |= Qt::MiddleButton; + value &= ~Qt::LeftButton; + value ^= Qt::RightButton; + return value; +} + void tst_QFlags::constExpr() { #ifdef Q_COMPILER_CONSTEXPR @@ -115,6 +125,10 @@ void tst_QFlags::constExpr() QVERIFY(verifyConstExpr<Qt::MouseButtons(Qt::RightButton) | 0xff>(0xff)); QVERIFY(!verifyConstExpr<Qt::RightButton>(!Qt::MouseButtons(Qt::LeftButton))); + +#if defined(__cpp_constexpr) && __cpp_constexpr-0 >= 201304 + QVERIFY(verifyConstExpr<testRelaxedConstExpr()>(Qt::MiddleButton)); +#endif #endif } diff --git a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp index c0b4ff654a..3304a09061 100644 --- a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp +++ b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp @@ -41,14 +41,22 @@ class tst_QGetPutEnv : public QObject Q_OBJECT private slots: void getSetCheck(); + void intValue_data(); + void intValue(); }; void tst_QGetPutEnv::getSetCheck() { const char varName[] = "should_not_exist"; + bool ok; + QVERIFY(!qEnvironmentVariableIsSet(varName)); QVERIFY(qEnvironmentVariableIsEmpty(varName)); + ok = true; + QCOMPARE(qEnvironmentVariableIntValue(varName), 0); + QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); + QVERIFY(!ok); QByteArray result = qgetenv(varName); QCOMPARE(result, QByteArray()); @@ -57,12 +65,20 @@ void tst_QGetPutEnv::getSetCheck() QVERIFY(qEnvironmentVariableIsSet(varName)); QVERIFY(qEnvironmentVariableIsEmpty(varName)); + ok = true; + QCOMPARE(qEnvironmentVariableIntValue(varName), 0); + QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); + QVERIFY(!ok); #endif QVERIFY(qputenv(varName, QByteArray("supervalue"))); QVERIFY(qEnvironmentVariableIsSet(varName)); QVERIFY(!qEnvironmentVariableIsEmpty(varName)); + ok = true; + QCOMPARE(qEnvironmentVariableIntValue(varName), 0); + QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); + QVERIFY(!ok); result = qgetenv(varName); QVERIFY(result == "supervalue"); @@ -72,9 +88,61 @@ void tst_QGetPutEnv::getSetCheck() QVERIFY(qunsetenv(varName)); QVERIFY(!qEnvironmentVariableIsSet(varName)); QVERIFY(qEnvironmentVariableIsEmpty(varName)); + ok = true; + QCOMPARE(qEnvironmentVariableIntValue(varName), 0); + QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); + QVERIFY(!ok); result = qgetenv(varName); QCOMPARE(result, QByteArray()); } +void tst_QGetPutEnv::intValue_data() +{ + QTest::addColumn<QByteArray>("value"); + QTest::addColumn<int>("expected"); + QTest::addColumn<bool>("ok"); + + // most non-success cases already tested in getSetCheck() + +#define ROW(x, i, b) \ + QTest::newRow(#x) << QByteArray(#x) << (i) << (b) + ROW(auto, 0, false); + ROW(0, 0, true); + ROW(1, 1, true); + ROW(010, 8, true); + ROW(0x10, 16, true); + ROW(-1, -1, true); + ROW(-010, -8, true); + // ROW(0xffffffff, -1, true); // could be expected, but not how QByteArray::toInt() works + ROW(0xffffffff, 0, false); + const int bases[] = {10, 8, 16}; + for (size_t i = 0; i < sizeof bases / sizeof *bases; ++i) { + QTest::newRow(qPrintable(QString().sprintf("INT_MAX, base %d", bases[i]))) + << QByteArray::number(INT_MAX) << INT_MAX << true; + QTest::newRow(qPrintable(QString().sprintf("INT_MAX+1, base %d", bases[i]))) + << QByteArray::number(qlonglong(INT_MAX) + 1) << 0 << false; + QTest::newRow(qPrintable(QString().sprintf("INT_MIN, base %d", bases[i]))) + << QByteArray::number(INT_MIN) << INT_MIN << true; + QTest::newRow(qPrintable(QString().sprintf("INT_MIN-1, base %d", bases[i]))) + << QByteArray::number(qlonglong(INT_MIN) - 1) << 0 << false; + }; +} + +void tst_QGetPutEnv::intValue() +{ + const char varName[] = "should_not_exist"; + + QFETCH(QByteArray, value); + QFETCH(int, expected); + QFETCH(bool, ok); + + bool actualOk = !ok; + + QVERIFY(qputenv(varName, value)); + QCOMPARE(qEnvironmentVariableIntValue(varName), expected); + QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), expected); + QCOMPARE(actualOk, ok); +} + QTEST_MAIN(tst_QGetPutEnv) #include "tst_qgetputenv.moc" diff --git a/tests/auto/corelib/global/qlogging/app/app.pro b/tests/auto/corelib/global/qlogging/app/app.pro index a7f6e68448..4789efc478 100644 --- a/tests/auto/corelib/global/qlogging/app/app.pro +++ b/tests/auto/corelib/global/qlogging/app/app.pro @@ -12,5 +12,5 @@ SOURCES += main.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 DEFINES += QT_MESSAGELOGCONTEXT -gcc:!mingw: QMAKE_LFLAGS += -rdynamic +gcc:!mingw:!haiku: QMAKE_LFLAGS += -rdynamic diff --git a/tests/auto/corelib/global/qlogging/app/main.cpp b/tests/auto/corelib/global/qlogging/app/main.cpp index 33b16ed8e5..81d02f93cf 100644 --- a/tests/auto/corelib/global/qlogging/app/main.cpp +++ b/tests/auto/corelib/global/qlogging/app/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -73,6 +73,7 @@ int main(int argc, char **argv) qSetMessagePattern("[%{type}] %{message}"); qDebug("qDebug"); + qInfo("qInfo"); qWarning("qWarning"); qCritical("qCritical"); diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 140b349c64..b3beefa2fb 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt-project.org/legal ** @@ -730,10 +730,11 @@ void tst_qmessagehandler::qMessagePattern_data() << "static destructor" << "debug tst_qlogging 65 MyClass::myFunction from_a_function 34" << "debug tst_qlogging 75 main qDebug" - << "warning tst_qlogging 76 main qWarning" - << "critical tst_qlogging 77 main qCritical" - << "warning tst_qlogging 80 main qDebug with category" - << "debug tst_qlogging 84 main qDebug2"); + << "info tst_qlogging 76 main qInfo" + << "warning tst_qlogging 77 main qWarning" + << "critical tst_qlogging 78 main qCritical" + << "warning tst_qlogging 81 main qDebug with category" + << "debug tst_qlogging 85 main qDebug2"); QTest::newRow("invalid") << "PREFIX: %{unknown} %{message}" << false << (QList<QByteArray>() @@ -765,9 +766,9 @@ void tst_qmessagehandler::qMessagePattern_data() << "A DEBUG qDebug " << "A qWarning "); - QTest::newRow("pid") << "%{pid}: %{message}" + QTest::newRow("pid-tid") << "%{pid}/%{threadid}: %{message}" << true << QList<QByteArray>(); // can't match anything, just test validity - QTest::newRow("threadid") << "ThreadId:%{threadid}: %{message}" + QTest::newRow("qthreadptr") << "ThreadId:%{qthreadptr}: %{message}" << true << (QList<QByteArray>() << "ThreadId:0x"); @@ -877,6 +878,7 @@ void tst_qmessagehandler::setMessagePattern() //qDebug() << output; QByteArray expected = "static constructor\n" "[debug] qDebug\n" + "[info] qInfo\n" "[warning] qWarning\n" "[critical] qCritical\n" "[warning] qDebug with category\n"; @@ -908,10 +910,13 @@ void tst_qmessagehandler::formatLogMessage_data() << QtDebugMsg << BA("main.cpp") << 1 << BA("func") << BA("") << "msg"; // test the if conditions - QString format = "[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}"; + QString format = "[%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}"; QTest::newRow("if-debug") << format << "[D] msg" << QtDebugMsg << BA("") << 0 << BA("func") << QByteArray() << "msg"; + QTest::newRow("if_info") + << format << "[I] msg" + << QtInfoMsg << BA("") << 0 << BA("func") << QByteArray() << "msg"; QTest::newRow("if_warning") << format << "[W] msg" << QtWarningMsg << BA("") << 0 << BA("func") << QByteArray() << "msg"; diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index 015a13775d..4718b83df0 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -52,6 +52,7 @@ private slots: void stateSaver() const; void veryLongWarningMessage() const; void qDebugQChar() const; + void qDebugQString() const; void qDebugQStringRef() const; void qDebugQLatin1String() const; void qDebugQByteArray() const; @@ -344,6 +345,54 @@ void tst_QDebug::qDebugQChar() const } +void tst_QDebug::qDebugQString() const +{ + /* Use a basic string. */ + { + QString file, function; + int line = 0; + const QString in(QLatin1String("input")); + const QStringRef inRef(&in); + + MessageHandlerSetter mhs(myMessageHandler); + { qDebug() << inRef; } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"input\"")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + } + + /* simpler tests from now on */ + MessageHandlerSetter mhs(myMessageHandler); + + QString string = "Hello"; + qDebug() << string; + QCOMPARE(s_msg, QString("\"Hello\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, string); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + string); + + string = QLatin1String("\nSm\xF8rg\xE5sbord\\"); + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, string); + + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\nSm\\u00F8rg\\u00E5sbord\\\\\"")); + + // surrogate pairs (including broken pairings) + ushort utf16[] = { 0xDC00, 0xD800, 0xDC00, 'x', 0xD800, 0xDC00, 0xD800, 0 }; + string = QString::fromUtf16(utf16); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\uDC00\\U00010000x\\U00010000\\uD800\"")); +} + void tst_QDebug::qDebugQStringRef() const { /* Use a basic string. */ @@ -403,6 +452,24 @@ void tst_QDebug::qDebugQLatin1String() const QCOMPARE(QString::fromLatin1(s_file), file); QCOMPARE(s_line, line); QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + QLatin1String string("\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString(string)); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString(string)); + + string = QLatin1String("\nSm\xF8rg\xE5sbord\\"); + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString(string)); + + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\nSm\\u00F8rg\\u00E5sbord\\\\\"")); } void tst_QDebug::qDebugQByteArray() const @@ -423,6 +490,28 @@ void tst_QDebug::qDebugQByteArray() const QCOMPARE(QString::fromLatin1(s_file), file); QCOMPARE(s_line, line); QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + QByteArray ba = "\"Hello\""; + qDebug() << ba; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << ba; + QCOMPARE(s_msg, QString::fromLatin1(ba)); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << ba; + QCOMPARE(s_msg, " " + QString::fromLatin1(ba)); + + ba = "\nSm\xC3\xB8rg\xC3\xA5sbord\\"; + qDebug().noquote().nospace() << ba; + QCOMPARE(s_msg, QString::fromUtf8(ba)); + + qDebug() << ba; + QCOMPARE(s_msg, QString("\"\\nSm\\xC3\\xB8rg\\xC3\\xA5sbord\\\\\"")); + + // ensure that it closes hex escape sequences correctly + qDebug() << QByteArray("\377FFFF"); + QCOMPARE(s_msg, QString("\"\\xFF\"\"FFFF\"")); } enum TestEnum { diff --git a/tests/auto/corelib/io/qfileselector/platforms/+windows/test2 b/tests/auto/corelib/io/qfileselector/platforms/+unix/test3 index e69de29bb2..e69de29bb2 100644 --- a/tests/auto/corelib/io/qfileselector/platforms/+windows/test2 +++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/test3 diff --git a/tests/auto/corelib/io/qfileselector/platforms/+windows/+winnt/test b/tests/auto/corelib/io/qfileselector/platforms/+windows/+winnt/test new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/+windows/+winnt/test diff --git a/tests/auto/corelib/io/qfileselector/platforms/+windows/test3 b/tests/auto/corelib/io/qfileselector/platforms/+windows/test3 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/+windows/test3 diff --git a/tests/auto/corelib/io/qfileselector/platforms/+winnt/test2 b/tests/auto/corelib/io/qfileselector/platforms/+winnt/test2 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/+winnt/test2 diff --git a/tests/auto/corelib/io/qfileselector/platforms/test3 b/tests/auto/corelib/io/qfileselector/platforms/test3 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/test3 diff --git a/tests/auto/corelib/io/qfileselector/qfileselector.qrc b/tests/auto/corelib/io/qfileselector/qfileselector.qrc index 8fe7b841d2..661647f933 100644 --- a/tests/auto/corelib/io/qfileselector/qfileselector.qrc +++ b/tests/auto/corelib/io/qfileselector/qfileselector.qrc @@ -10,6 +10,8 @@ <file>extras/+custom3/+custom4/test</file> <file>extras/+custom3/+custom5/test</file> <file>extras/+custom5/+custom3/test</file> + + <!-- platforms/test: deepest possible selection --> <file>platforms/test</file> <file>platforms/+unix/+android/test</file> <file>platforms/+unix/+blackberry/test</file> @@ -17,18 +19,11 @@ <file>platforms/+unix/+darwin/+mac/+osx/test</file> <file>platforms/+unix/+darwin/+mac/test</file> <file>platforms/+unix/+darwin/test</file> - <file>platforms/+windows/+wince/test</file> - <file>platforms/+windows/test</file> - <file>platforms/+windows/test2</file> <file>platforms/+unix/+linux/test</file> <file>platforms/+unix/test</file> - <file>platforms/test2</file> - <file>platforms/+android/test2</file> - <file>platforms/+blackberry/test2</file> - <file>platforms/+ios/test2</file> - <file>platforms/+osx/test2</file> - <file>platforms/+linux/test2</file> - <file>platforms/+wince/test2</file> + <file>platforms/+windows/+wince/test</file> + <file>platforms/+windows/+winnt/test</file> + <file>platforms/+windows/test</file> <file>platforms/+android/test</file> <file>platforms/+blackberry/test</file> <file>platforms/+ios/test</file> @@ -37,5 +32,20 @@ <file>platforms/+mac/test</file> <file>platforms/+linux/test</file> <file>platforms/+wince/test</file> + + <!-- platforms/test2: shallow selection for the deepest selector --> + <file>platforms/test2</file> + <file>platforms/+android/test2</file> + <file>platforms/+blackberry/test2</file> + <file>platforms/+ios/test2</file> + <file>platforms/+osx/test2</file> + <file>platforms/+linux/test2</file> + <file>platforms/+wince/test2</file> + <file>platforms/+winnt/test2</file> + + <!-- platforms/test3: selection for the family only --> + <file>platforms/test3</file> + <file>platforms/+windows/test3</file> + <file>platforms/+unix/test3</file> </qresource> </RCC> diff --git a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp index 26bb4189d7..831db9e0b4 100644 --- a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp +++ b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp @@ -84,8 +84,10 @@ void tst_QFileSelector::basicTest_data() QString test("/test");// '/' is here so dir string can also be selector string QString test2("/test2"); + QString test3("/test3"); QString expectedPlatform1File(":/platforms"); QString expectedPlatform2File(""); //Only the last selector + QString expectedPlatform3File; // Only the first selector (the family) #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY) && \ !defined(Q_OS_DARWIN) && !defined(Q_OS_LINUX) /* We are only aware of specific unixes, and do not have test files for any of the others. @@ -96,14 +98,26 @@ void tst_QFileSelector::basicTest_data() + QString("unix/test"); expectedPlatform2File = QString(":/platforms/test2"); #else + QString distributionName; +# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD) + distributionName = QSysInfo::productType(); +# endif foreach (const QString &selector, QFileSelectorPrivate::platformSelectors()) { + // skip the Linux distribution name (if any) since we don't have files for them + if (selector == distributionName) + continue; + expectedPlatform1File = expectedPlatform1File + QLatin1Char('/') + QLatin1Char(selectorIndicator) + selector; expectedPlatform2File = selector; + if (expectedPlatform3File.isNull()) + expectedPlatform3File = selector; } expectedPlatform1File += test; expectedPlatform2File = QLatin1String(":/platforms/") + QLatin1Char(selectorIndicator) + expectedPlatform2File + test2; + expectedPlatform3File = QLatin1String(":/platforms/") + QLatin1Char(selectorIndicator) + + expectedPlatform3File + test3; #endif QTest::newRow("platform1") << QString(":/platforms/test") << QStringList() @@ -112,6 +126,9 @@ void tst_QFileSelector::basicTest_data() QTest::newRow("platform2") << QString(":/platforms/test2") << QStringList() << expectedPlatform2File; + QTest::newRow("platform3") << QString(":/platforms/test3") << QStringList() + << expectedPlatform3File; + QString resourceTestPath(":/extras/test"); QString custom1("custom1"); QTest::newRow("custom1-noselector") << resourceTestPath << QStringList() diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 0a952e9452..7f0b2a4e26 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -460,18 +460,9 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() #endif QTRY_VERIFY(fileChangedSpy.count() > 0); - - //according to Qt 4 documentation: - //void QFileSystemWatcher::directoryChanged ( const QString & path ) [signal] - //This signal is emitted when the directory at a specified path, is modified - //(e.g., when a file is added, -->modified<-- or deleted) or removed from disk. - //Note that if there are several changes during a short period of time, some - //of the changes might not emit this signal. However, the last change in the - //sequence of changes will always generate this signal. - QVERIFY(dirChangedSpy.count() < 2); + QCOMPARE(dirChangedSpy.count(), 0); fileChangedSpy.clear(); - dirChangedSpy.clear(); QFile secondFile(secondFileName); QVERIFY2(secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", secondFile)); QVERIFY2(secondFile.write(QByteArrayLiteral("Foo")) > 0, msgFileOperationFailed("write", secondFile)); diff --git a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp index 2e4740c8d9..dc0081f7ac 100644 --- a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp +++ b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -57,6 +57,7 @@ QByteArray qMyMessageFormatString(QtMsgType type, const QMessageLogContext &cont message.append(context.category); switch (type) { case QtDebugMsg: message.append(".debug"); break; + case QtInfoMsg: message.append(".info"); break; case QtWarningMsg: message.append(".warning"); break; case QtCriticalMsg:message.append(".critical"); break; case QtFatalMsg: message.append(".fatal"); break; @@ -339,6 +340,11 @@ private slots: qDebug("%s", "Check debug with no filter active"); QCOMPARE(logMessage, buf); + // Check default info + buf = QStringLiteral("default.info: Check info with no filter active"); + qInfo("%s", "Check info with no filter active"); + QCOMPARE(logMessage, buf); + // Check default warning buf = QStringLiteral("default.warning: Check warning with no filter active"); qWarning("%s", "Check warning with no filter active"); @@ -407,6 +413,13 @@ private slots: qCDebug(defaultCategory, "Check debug with no filter active"); QCOMPARE(logMessage, buf); + // Check default info + buf = QStringLiteral("default.info: Check info with no filter active"); + qCInfo(defaultCategory) << "Check info with no filter active"; + QCOMPARE(logMessage, buf); + qCInfo(defaultCategory, "Check info with no filter active"); + QCOMPARE(logMessage, buf); + // Check default warning buf = QStringLiteral("default.warning: Check warning with no filter active"); qCWarning(defaultCategory) << "Check warning with no filter active"; @@ -432,6 +445,11 @@ private slots: qCDebug(customCategory) << "Check debug with no filter active"; QCOMPARE(logMessage, buf); + // Check custom info + buf = QStringLiteral("custom.info: Check info with no filter active"); + qCInfo(customCategory) << "Check info with no filter active"; + QCOMPARE(logMessage, buf); + // Check custom warning buf = QStringLiteral("custom.warning: Check warning with no filter active"); qCWarning(customCategory) << "Check warning with no filter active"; @@ -493,7 +511,7 @@ private slots: usedefaultformat = false; } - // Check the Debug, Warning and critical without having category active. should be active. + // Check the Debug, Info, Warning and critical without having category active. should be active. void checkNoCategoryLogActive() { // Check default debug @@ -501,6 +519,11 @@ private slots: qDebug() << "Check default Debug with no log active"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + // Check default info + buf = QStringLiteral("default.info: Check default Info with no log active"); + qInfo() << "Check default Info with no log active"; + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + // Check default warning buf = QStringLiteral("default.warning: Check default Warning with no log active"); qWarning() << "Check default Warning with no log active"; @@ -514,8 +537,11 @@ private slots: // Check category debug buf = QStringLiteral("tst.log.debug: Check category Debug with no log active"); qCDebug(TST_LOG) << "Check category Debug with no log active"; - QCOMPARE(logMessage, buf); + // Check category info + buf = QStringLiteral("tst.log.info: Check category Info with no log active"); + qCInfo(TST_LOG) << "Check category Info with no log active"; + QCOMPARE(logMessage, buf); // Check default warning buf = QStringLiteral("tst.log.warning: Check category Warning with no log active"); @@ -550,6 +576,9 @@ private slots: qCDebug(TST_LOG) << "DebugType"; buf = QStringLiteral("tst.log.debug: DebugType"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + qCInfo(TST_LOG) << "InfoType"; + buf = QStringLiteral("tst.log.info: InfoType"); + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCWarning(TST_LOG) << "WarningType"; buf = QStringLiteral("tst.log.warning: WarningType"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -561,11 +590,13 @@ private slots: void checkLegacyLogs() { logMessage = ""; + // all are on by default qDebug() << "DefaultDebug"; QString buf = QStringLiteral("default.debug: DefaultDebug"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); - - // debug off by default, warning and critical are on + qInfo() << "DefaultInfo"; + buf = QStringLiteral("default.info: DefaultInfo"); + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning"; buf = QStringLiteral("default.warning: DefaultWarning"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -573,12 +604,16 @@ private slots: buf = QStringLiteral("default.critical: DefaultCritical"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); - // Enable debug - _config->addKey("default.debug", true); + // Disable debug + _config->addKey("default.debug", false); QLoggingCategory::setFilterRules(_config->array()); + logMessage = "no change"; qDebug() << "DefaultDebug1"; - buf = QStringLiteral("default.debug: DefaultDebug1"); + buf = QStringLiteral("no change"); + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + qInfo() << "DefaultInfo1"; + buf = QStringLiteral("default.info: DefaultInfo1"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning1"; buf = QStringLiteral("default.warning: DefaultWarning1"); @@ -587,7 +622,11 @@ private slots: buf = QStringLiteral("default.critical: DefaultCritical1"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); - // Disable warning + _config->clear(); + QLoggingCategory::setFilterRules(_config->array()); + + // Disable info, warning + _config->addKey("default.info", false); _config->addKey("default.warning", false); QLoggingCategory::setFilterRules(_config->array()); @@ -595,6 +634,9 @@ private slots: buf = QStringLiteral("default.debug: DefaultDebug2"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); logMessage = "no change"; + qInfo() << "DefaultInfo2"; + buf = QStringLiteral("no change"); + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning2"; buf = QStringLiteral("no change"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -611,6 +653,8 @@ private slots: qDebug() << "DefaultDebug3"; buf = QStringLiteral("no change"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + qInfo() << "DefaultInfo3"; + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning3"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical3"; @@ -619,6 +663,7 @@ private slots: // Enable default logs _config->addKey("default.critical", true); _config->addKey("default.warning", true); + _config->addKey("default.info", true); _config->addKey("default.debug", true); QLoggingCategory::setFilterRules(_config->array()); @@ -626,6 +671,9 @@ private slots: qDebug() << "DefaultDebug4"; buf = QStringLiteral("default.debug: DefaultDebug4"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + qInfo() << "DefaultInfo4"; + buf = QStringLiteral("default.info: DefaultInfo4"); + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning4"; buf = QStringLiteral("default.warning: DefaultWarning4"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -642,6 +690,8 @@ private slots: buf = QStringLiteral("no change"); qDebug() << "DefaultDebug5"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + qDebug() << "DefaultInfo5"; + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning5"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical5"; @@ -711,6 +761,7 @@ private slots: QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); logMessage = "no change"; buf = QStringLiteral("no change"); + qCInfo(Digia_Oulu_Office_com) << "Info: Digia.Oulu.Office.com 4"; qCWarning(Digia_Oulu_Office_com) << "Warning: Digia.Oulu.Office.com 4"; qCCritical(Digia_Berlin_Office_com) << "Critical: Digia.Berlin.Office.com 4"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -723,6 +774,9 @@ private slots: qCDebug(Digia_Oslo_Office_com) << "Debug: Digia.Oslo.Office.com 5"; buf = QStringLiteral("Digia.Oslo.Office.com.debug: Debug: Digia.Oslo.Office.com 5"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + qCInfo(Digia_Oulu_Office_com) << "Info: Digia.Oulu.Office.com 5"; + buf = QStringLiteral("Digia.Oulu.Office.com.info: Info: Digia.Oulu.Office.com 5"); + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCWarning(Digia_Oulu_Office_com) << "Warning: Digia.Oulu.Office.com 5"; buf = QStringLiteral("Digia.Oulu.Office.com.warning: Warning: Digia.Oulu.Office.com 5"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -737,6 +791,7 @@ private slots: logMessage = "no change"; buf = QStringLiteral("no change"); qCDebug(Digia_Oslo_Office_com) << "Debug: Digia.Oslo.Office.com 6"; + qCInfo(Digia_Oslo_Office_com) << "Info: Digia.Oslo.Office.com 6"; qCWarning(Digia_Oulu_Office_com) << "Warning: Digia.Oulu.Office.com 6"; qCCritical(Digia_Berlin_Office_com) << "Critical: Digia.Berlin.Office.com 6"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -747,6 +802,9 @@ private slots: qCDebug(Digia_Oslo_Office_com) << "Debug: Digia.Oslo.Office.com 7"; buf = QStringLiteral("Digia.Oslo.Office.com.debug: Debug: Digia.Oslo.Office.com 7"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + qCInfo(Digia_Oulu_Office_com) << "Info: Digia.Oulu.Office.com 7"; + buf = QStringLiteral("Digia.Oulu.Office.com.info: Info: Digia.Oulu.Office.com 7"); + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCWarning(Digia_Oulu_Office_com) << "Warning: Digia.Oulu.Office.com 7"; buf = QStringLiteral("Digia.Oulu.Office.com.warning: Warning: Digia.Oulu.Office.com 7"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -770,6 +828,10 @@ private slots: qCDebug(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + buf = QStringLiteral("LoggingCategoryObject.info: My Category Object"); + qCInfo(mycategoryobject) << "My Category Object"; + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + buf = QStringLiteral("LoggingCategoryObject.warning: My Category Object"); qCWarning(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); @@ -787,6 +849,10 @@ private slots: qCWarning(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + buf = QStringLiteral("LoggingCategoryObject.info: My Category Object"); + qCInfo(mycategoryobject) << "My Category Object"; + QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); + buf = QStringLiteral("LoggingCategoryObject.critical: My Category Object"); qCCritical(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); diff --git a/tests/auto/corelib/io/qprocess/test/test.pro b/tests/auto/corelib/io/qprocess/test/test.pro index 90afeddaa0..f77dacc87b 100644 --- a/tests/auto/corelib/io/qprocess/test/test.pro +++ b/tests/auto/corelib/io/qprocess/test/test.pro @@ -1,7 +1,7 @@ CONFIG += testcase CONFIG += parallel_test CONFIG -= app_bundle debug_and_release_target -QT = core testlib network +QT = core-private testlib network SOURCES = ../tst_qprocess.cpp TARGET = ../tst_qprocess diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 59042f6498..412d9316e9 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -44,6 +44,7 @@ #include <stdlib.h> #ifndef QT_NO_PROCESS +# include <private/qprocess_p.h> // only so we get QPROCESS_USE_SPAWN # if defined(Q_OS_WIN) # include <windows.h> # endif @@ -325,6 +326,9 @@ void tst_QProcess::startDetached() QProcess proc; QVERIFY(proc.startDetached("testProcessNormal/testProcessNormal", QStringList() << "arg1" << "arg2")); +#ifdef QPROCESS_USE_SPAWN + QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Continue); +#endif QCOMPARE(QProcess::startDetached("nonexistingexe"), false); } @@ -713,6 +717,9 @@ void tst_QProcess::waitForFinished() QCOMPARE(output.count("\n"), 10*1024); process.start("blurdybloop"); +#if defined(QPROCESS_USE_SPAWN) && !defined(Q_OS_QNX) + QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Abort); +#endif QVERIFY(!process.waitForFinished()); QCOMPARE(process.error(), QProcess::FailedToStart); } @@ -1223,21 +1230,24 @@ void tst_QProcess::processInAThread() void tst_QProcess::processesInMultipleThreads() { for (int i = 0; i < 10; ++i) { - TestThread thread1; - TestThread thread2; - TestThread thread3; - - thread1.start(); - thread2.start(); - thread3.start(); - - QVERIFY(thread2.wait(10000)); - QVERIFY(thread3.wait(10000)); - QVERIFY(thread1.wait(10000)); - - QCOMPARE(thread1.code(), 0); - QCOMPARE(thread2.code(), 0); - QCOMPARE(thread3.code(), 0); + // run from 1 to 10 threads, but run at least some tests + // with more threads than the ideal + int threadCount = i; + if (i > 7) + threadCount = qMax(threadCount, QThread::idealThreadCount() + 2); + + QVector<TestThread *> threads(threadCount); + for (int j = 0; j < threadCount; ++j) + threads[j] = new TestThread; + for (int j = 0; j < threadCount; ++j) + threads[j]->start(); + for (int j = 0; j < threadCount; ++j) { + QVERIFY(threads[j]->wait(10000)); + } + for (int j = 0; j < threadCount; ++j) { + QCOMPARE(threads[j]->code(), 0); + } + qDeleteAll(threads); } } @@ -1514,6 +1524,11 @@ void tst_QProcess::nativeArguments() void tst_QProcess::exitCodeTest() { for (int i = 0; i < 255; ++i) { +#ifdef QPROCESS_USE_SPAWN + // POSIX reserves exit code 127 when using posix_spawn + if (i == 127) + continue; +#endif QProcess process; process.start("testExitCodes/testExitCodes " + QString::number(i)); QVERIFY(process.waitForFinished(5000)); @@ -1525,6 +1540,9 @@ void tst_QProcess::exitCodeTest() //----------------------------------------------------------------------------- void tst_QProcess::failToStart() { +#if defined(QPROCESS_USE_SPAWN) && !defined(Q_OS_QNX) + QSKIP("QProcess cannot detect failure to start when using posix_spawn()"); +#endif qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState"); @@ -1592,6 +1610,9 @@ void tst_QProcess::failToStart() //----------------------------------------------------------------------------- void tst_QProcess::failToStartWithWait() { +#if defined(QPROCESS_USE_SPAWN) && !defined(Q_OS_QNX) + QSKIP("QProcess cannot detect failure to start when using posix_spawn()"); +#endif qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); @@ -1619,6 +1640,9 @@ void tst_QProcess::failToStartWithWait() //----------------------------------------------------------------------------- void tst_QProcess::failToStartWithEventLoop() { +#if defined(QPROCESS_USE_SPAWN) && !defined(Q_OS_QNX) + QSKIP("QProcess cannot detect failure to start when using posix_spawn()"); +#endif qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); @@ -1867,6 +1891,9 @@ void tst_QProcess::waitForReadyReadForNonexistantProcess() QVERIFY(!process.waitForReadyRead()); // used to crash process.start("doesntexist"); QVERIFY(!process.waitForReadyRead()); +#if defined(QPROCESS_USE_SPAWN) && !defined(Q_OS_QNX) + QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Abort); +#endif QCOMPARE(errorSpy.count(), 1); QCOMPARE(errorSpy.at(0).at(0).toInt(), 0); QCOMPARE(finishedSpy1.count(), 0); diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 21e020404b..8dc9838e4f 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -48,7 +48,8 @@ #define Q_XDG_PLATFORM #endif -static const int MaxStandardLocation = QStandardPaths::AppDataLocation; +// Update this when adding new enum values; update enumNames too +static const int MaxStandardLocation = QStandardPaths::AppConfigLocation; class tst_qstandardpaths : public QObject { @@ -61,6 +62,7 @@ private slots: void enableTestMode(); void testLocateAll(); void testDataLocation(); + void testAppConfigLocation(); void testFindExecutable_data(); void testFindExecutable(); void testFindExecutableLinkToDirectory(); @@ -122,7 +124,8 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths "DownloadLocation", "GenericCacheLocation", "GenericConfigLocation", - "AppDataLocation" + "AppDataLocation", + "AppConfigLocation" }; void tst_qstandardpaths::dump() @@ -305,6 +308,27 @@ void tst_qstandardpaths::testDataLocation() QCOMPARE(appDataDirs.at(1), QString::fromLatin1("/usr/local/share/Qt/QtTest")); QCOMPARE(appDataDirs.at(2), QString::fromLatin1("/usr/share/Qt/QtTest")); #endif + + // reset for other tests + QCoreApplication::setOrganizationName(QString()); + QCoreApplication::setApplicationName(QString()); +} + +void tst_qstandardpaths::testAppConfigLocation() +{ + // On all platforms where applications are not sandboxed, + // AppConfigLocation should be GenericConfigLocation / organization name / app name +#if !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WINRT) + const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/tst_qstandardpaths"); + QCoreApplication::setOrganizationName("Qt"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/Qt/tst_qstandardpaths"); + QCoreApplication::setApplicationName("QtTest"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/Qt/QtTest"); + // reset for other tests + QCoreApplication::setOrganizationName(QString()); + QCoreApplication::setApplicationName(QString()); +#endif } #ifndef Q_OS_WIN diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp index faa635fa96..84f9c53b21 100644 --- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp @@ -81,6 +81,7 @@ private slots: void readLineMaxlen_data(); void readLineMaxlen(); void readLinesFromBufferCRCR(); + void readLineOverload(); // all void readAllFromDevice_data(); @@ -593,6 +594,63 @@ void tst_QTextStream::readLinesFromBufferCRCR() } } +class ErrorDevice : public QIODevice +{ +protected: + qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE + { + Q_UNUSED(data) + Q_UNUSED(maxlen) + return -1; + } + + qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE + { + Q_UNUSED(data) + Q_UNUSED(len) + return -1; + } +}; + +void tst_QTextStream::readLineOverload() +{ + QByteArray data = "1\n2\n3"; + + QTextStream ts(&data); + QString line; + + ts.readLine(&line); + QCOMPARE(line, QStringLiteral("1")); + + ts.readLine(Q_NULLPTR, 0); // read the second line, but don't store it + + ts.readLine(&line); + QCOMPARE(line, QStringLiteral("3")); + + QVERIFY(!ts.readLine(&line)); + QVERIFY(line.isEmpty()); + + QFile file(m_rfc3261FilePath); + QVERIFY(file.open(QFile::ReadOnly)); + + ts.setDevice(&file); + line.reserve(1); + int maxLineCapacity = line.capacity(); + + while (ts.readLine(&line)) { + QVERIFY(line.capacity() >= maxLineCapacity); + maxLineCapacity = line.capacity(); + } + + line = "Test string"; + ErrorDevice errorDevice; + QVERIFY(errorDevice.open(QIODevice::ReadOnly)); + ts.setDevice(&errorDevice); + + QVERIFY(!ts.readLine(&line)); + QVERIFY(line.isEmpty()); +} + // ------------------------------------------------------------------------------ void tst_QTextStream::readLineFromString_data() { @@ -912,13 +970,28 @@ void tst_QTextStream::lineCount() } // ------------------------------------------------------------------------------ +struct CompareIndicesForArray +{ + int *array; + CompareIndicesForArray(int *array) : array(array) {} + bool operator() (const int i1, const int i2) + { + return array[i1] < array[i2]; + } +}; + void tst_QTextStream::performance() { // Phase #1 - test speed of reading a huge text file with QFile. QTime stopWatch; - int elapsed1 = 0; - int elapsed2 = 0; + const int N = 3; + const char * readMethods[N] = { + "QFile::readLine()", + "QTextStream::readLine()", + "QTextStream::readLine(QString *)" + }; + int elapsed[N] = {0, 0, 0}; stopWatch.restart(); int nlines1 = 0; @@ -930,7 +1003,7 @@ void tst_QTextStream::performance() file.readLine(); } - elapsed1 += stopWatch.elapsed(); + elapsed[0] = stopWatch.elapsed(); stopWatch.restart(); int nlines2 = 0; @@ -943,20 +1016,38 @@ void tst_QTextStream::performance() stream.readLine(); } - elapsed2 += stopWatch.elapsed(); + elapsed[1] = stopWatch.elapsed(); + stopWatch.restart(); + + int nlines3 = 0; + QFile file3(m_rfc3261FilePath); + QVERIFY(file3.open(QFile::ReadOnly)); + + QTextStream stream2(&file3); + QString line; + while (stream2.readLine(&line)) + ++nlines3; + + elapsed[2] = stopWatch.elapsed(); + QCOMPARE(nlines1, nlines2); + QCOMPARE(nlines2, nlines3); + + for (int i = 0; i < N; i++) { + qDebug("%s used %.3f seconds to read the file", readMethods[i], + elapsed[i] / 1000.0); + } + + int idx[N] = {0, 1, 2}; + std::sort(idx, idx + N, CompareIndicesForArray(elapsed)); - qDebug("QFile used %.2f seconds to read the file", - elapsed1 / 1000.0); - - qDebug("QTextStream used %.2f seconds to read the file", - elapsed2 / 1000.0); - if (elapsed2 > elapsed1) { - qDebug("QFile is %.2fx faster than QTextStream", - double(elapsed2) / double(elapsed1)); - } else { - qDebug("QTextStream is %.2fx faster than QFile", - double(elapsed1) / double(elapsed2)); + for (int i = 0; i < N-1; i++) { + int i1 = idx[i]; + int i2 = idx[i+1]; + qDebug("Reading by %s is %.2fx faster than by %s", + readMethods[i1], + double(elapsed[i2]) / double(elapsed[i1]), + readMethods[i2]); } } diff --git a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp index b6a0cc923d..67be1b1e45 100644 --- a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp @@ -211,7 +211,6 @@ void tst_QAbstractProxyModel::mapFromSource() QCOMPARE(model.mapFromSource(sourceIndex), mapFromSource); } -Q_DECLARE_METATYPE(QItemSelection) void tst_QAbstractProxyModel::mapSelectionFromSource_data() { QTest::addColumn<QItemSelection>("selection"); diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp index ef0ce77bbb..5a4d88d373 100644 --- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -86,6 +86,7 @@ private slots: void deselectRemovedMiddleRange(); void rangeOperatorLessThan_data(); void rangeOperatorLessThan(); + void setModel(); void testDifferentModels(); @@ -107,8 +108,6 @@ typedef QList<int> IntList; typedef QPair<int, int> IntPair; typedef QList<IntPair> PairList; -Q_DECLARE_METATYPE(QItemSelection) - class QStreamHelper: public QAbstractItemModel { public: @@ -2561,6 +2560,21 @@ void tst_QItemSelectionModel::rangeOperatorLessThan() QVERIFY(r4 < r2); } +void tst_QItemSelectionModel::setModel() +{ + QItemSelectionModel sel; + QVERIFY(!sel.model()); + QSignalSpy modelChangedSpy(&sel, SIGNAL(modelChanged(QAbstractItemModel*))); + QStringListModel model(QStringList() << "Blah" << "Blah" << "Blah"); + sel.setModel(&model); + QCOMPARE(sel.model(), &model); + QCOMPARE(modelChangedSpy.count(), 1); + sel.select(model.index(0), QItemSelectionModel::Select); + QVERIFY(!sel.selection().isEmpty()); + sel.setModel(0); + QVERIFY(sel.selection().isEmpty()); +} + void tst_QItemSelectionModel::testDifferentModels() { QStandardItemModel model1; diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 5bb7ffc401..645a0a724c 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -96,6 +96,7 @@ private slots: void changeSourceData_data(); void changeSourceData(); void changeSourceDataKeepsStableSorting_qtbug1548(); + void changeSourceDataForwardsRoles_qtbug35440(); void resortingDoesNotBreakTreeModels(); void sortFilterRole(); void selectionFilteredOut(); @@ -2087,6 +2088,37 @@ void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548() checkSortedTableModel(&model, rows); } +void tst_QSortFilterProxyModel::changeSourceDataForwardsRoles_qtbug35440() +{ + QStringList strings; + for (int i = 0; i < 100; ++i) + strings << QString::number(i); + + QStringListModel model(strings); + + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + proxy.sort(0, Qt::AscendingOrder); + + QSignalSpy spy(&proxy, &QAbstractItemModel::dataChanged); + QVERIFY(spy.isValid()); + QCOMPARE(spy.length(), 0); + + QModelIndex index; + + index = model.index(0, 0); + QVERIFY(index.isValid()); + model.setData(index, QStringLiteral("teststring"), Qt::DisplayRole); + QCOMPARE(spy.length(), 1); + QCOMPARE(spy.at(0).at(2).value<QVector<int> >(), QVector<int>() << Qt::DisplayRole); + + index = model.index(1, 0); + QVERIFY(index.isValid()); + model.setData(index, QStringLiteral("teststring2"), Qt::EditRole); + QCOMPARE(spy.length(), 2); + QCOMPARE(spy.at(1).at(2).value<QVector<int> >(), QVector<int>() << Qt::EditRole); +} + void tst_QSortFilterProxyModel::sortFilterRole() { QStandardItemModel model; diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 56a5a28c50..997ceaf7b9 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -90,7 +90,9 @@ private Q_SLOTS: void fromVariant(); void fromVariantMap(); + void fromVariantHash(); void toVariantMap(); + void toVariantHash(); void toVariantList(); void toJson(); @@ -1165,6 +1167,17 @@ void tst_QtJson::fromVariantMap() QCOMPARE(array.at(3).toString(), QLatin1String("foo")); } +void tst_QtJson::fromVariantHash() +{ + QVariantHash map; + map.insert(QLatin1String("key1"), QLatin1String("value1")); + map.insert(QLatin1String("key2"), QLatin1String("value2")); + QJsonObject object = QJsonObject::fromVariantHash(map); + QCOMPARE(object.size(), 2); + QCOMPARE(object.value(QLatin1String("key1")), QJsonValue(QLatin1String("value1"))); + QCOMPARE(object.value(QLatin1String("key2")), QJsonValue(QLatin1String("value2"))); +} + void tst_QtJson::toVariantMap() { QCOMPARE(QMetaType::Type(QJsonValue(QJsonObject()).toVariant().type()), QMetaType::QVariantMap); // QTBUG-32524 @@ -1196,6 +1209,35 @@ void tst_QtJson::toVariantMap() QCOMPARE(list.at(3), QVariant()); } +void tst_QtJson::toVariantHash() +{ + QJsonObject object; + QVariantHash hash = object.toVariantHash(); + QVERIFY(hash.isEmpty()); + + object.insert("Key", QString("Value")); + object.insert("null", QJsonValue()); + QJsonArray array; + array.append(true); + array.append(999.); + array.append(QLatin1String("string")); + array.append(QJsonValue()); + object.insert("Array", array); + + hash = object.toVariantHash(); + + QCOMPARE(hash.size(), 3); + QCOMPARE(hash.value("Key"), QVariant(QString("Value"))); + QCOMPARE(hash.value("null"), QVariant()); + QCOMPARE(hash.value("Array").type(), QVariant::List); + QVariantList list = hash.value("Array").toList(); + QCOMPARE(list.size(), 4); + QCOMPARE(list.at(0), QVariant(true)); + QCOMPARE(list.at(1), QVariant(999.)); + QCOMPARE(list.at(2), QVariant(QLatin1String("string"))); + QCOMPARE(list.at(3), QVariant()); +} + void tst_QtJson::toVariantList() { QCOMPARE(QMetaType::Type(QJsonValue(QJsonArray()).toVariant().type()), QMetaType::QVariantList); // QTBUG-32524 diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro index 4b3b2e824e..6b93439a56 100644 --- a/tests/auto/corelib/kernel/kernel.pro +++ b/tests/auto/corelib/kernel/kernel.pro @@ -9,6 +9,7 @@ SUBDIRS=\ qmetamethod \ qmetaproperty \ qmetatype \ + qmetaenum \ qmimedata \ qobject \ qpointer \ @@ -37,4 +38,4 @@ SUBDIRS=\ # This test is only applicable on Windows !win32*|winrt: SUBDIRS -= qwineventnotifier -android|qnx: SUBDIRS -= qsharedmemory qsystemsemaphore +android: SUBDIRS -= qsharedmemory qsystemsemaphore diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 442d9db85c..6ffe2bc6fe 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -109,11 +109,11 @@ void tst_QCoreApplication::qAppName() QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1(appName)); } -// "QCoreApplication::arguments() always parses arguments from actual command line on Windows -// making this test invalid." -#ifndef Q_OS_WIN void tst_QCoreApplication::argc() { +#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT) + QSKIP("QCoreApplication::arguments() parses arguments from actual command line on this platform."); +#endif { int argc = 1; char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; @@ -150,7 +150,6 @@ void tst_QCoreApplication::argc() QCOMPARE(app.arguments().count(), 1); } } -#endif class EventGenerator : public QObject { diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index 6f09399654..33b7084809 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -43,9 +43,7 @@ private slots: void sendEventsOnProcessEvents(); // this must be the first test void getSetCheck(); void qAppName(); -#ifndef Q_OS_WIN void argc(); -#endif void postEvent(); void removePostedEvents(); #ifndef QT_NO_THREAD diff --git a/tests/auto/corelib/kernel/qmetaenum/qmetaenum.pro b/tests/auto/corelib/kernel/qmetaenum/qmetaenum.pro new file mode 100644 index 0000000000..f045fc5d88 --- /dev/null +++ b/tests/auto/corelib/kernel/qmetaenum/qmetaenum.pro @@ -0,0 +1,5 @@ +CONFIG += testcase +CONFIG += parallel_test +TARGET = tst_qmetaenum +QT = core testlib +SOURCES = tst_qmetaenum.cpp diff --git a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp new file mode 100644 index 0000000000..280e5c9cca --- /dev/null +++ b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <QtCore/qobject.h> +#include <QtCore/qmetaobject.h> + +class tst_QMetaEnum : public QObject +{ + Q_OBJECT +public: + enum SuperEnum { SuperValue1 = 1 , SuperValue2 = 2 }; + Q_ENUM(SuperEnum) + +private slots: + void fromType(); +}; + +void tst_QMetaEnum::fromType() +{ + QMetaEnum meta = QMetaEnum::fromType<SuperEnum>(); + QVERIFY(meta.isValid()); + QCOMPARE(meta.name(), "SuperEnum"); + QCOMPARE(meta.enclosingMetaObject(), &staticMetaObject); + QCOMPARE(meta.keyCount(), 2); +} + +QTEST_MAIN(tst_QMetaEnum) +#include "tst_qmetaenum.moc" diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 1d39280afb..18de761e2a 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -50,6 +51,8 @@ private slots: void comparisonOperators(); void fromSignal(); + + void gadget(); }; struct CustomType { }; @@ -727,5 +730,51 @@ void tst_QMetaMethod::fromSignal() #undef FROMSIGNAL_HELPER } +class MyGadget { + Q_GADGET +public: + QString m_value; + Q_INVOKABLE void setValue(const QString &value) { m_value = value; } + Q_INVOKABLE QString getValue() { return m_value; } +}; + +void tst_QMetaMethod::gadget() +{ + int idx; + + idx = MyGadget::staticMetaObject.indexOfMethod("setValue(QString)"); + QVERIFY(idx >= 0); + QMetaMethod setValueMethod = MyGadget::staticMetaObject.method(idx); + QVERIFY(setValueMethod.isValid()); + + idx = MyGadget::staticMetaObject.indexOfMethod("getValue()"); + QVERIFY(idx >= 0); + QMetaMethod getValueMethod = MyGadget::staticMetaObject.method(idx); + QVERIFY(getValueMethod.isValid()); + + { + MyGadget gadget; + QString string; + + QVERIFY(getValueMethod.invokeOnGadget(&gadget, Q_RETURN_ARG(QString, string))); + QCOMPARE(string, gadget.m_value); + + QVERIFY(setValueMethod.invokeOnGadget(&gadget, Q_ARG(QString, QLatin1String("hello")))); + QCOMPARE(gadget.m_value, QLatin1String("hello")); + + QVERIFY(getValueMethod.invokeOnGadget(&gadget, Q_RETURN_ARG(QString, string))); + QCOMPARE(string, gadget.m_value); + } + + { + // Call with null should not crash + MyGadget *gadget = Q_NULLPTR; + QString string; + QVERIFY(!setValueMethod.invokeOnGadget(gadget, Q_ARG(QString, QLatin1String("hi")))); + QVERIFY(!getValueMethod.invokeOnGadget(gadget, Q_RETURN_ARG(QString, string))); + } +} + + QTEST_MAIN(tst_QMetaMethod) #include "tst_qmetamethod.moc" diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 8a7e945730..1774782262 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -46,15 +46,13 @@ struct MyStruct }; namespace MyNamespace { + // Used in tst_QMetaObject::checkScope class MyClass : public QObject { Q_OBJECT Q_PROPERTY(MyEnum myEnum READ myEnum WRITE setMyEnum) Q_PROPERTY(MyFlags myFlags READ myFlags WRITE setMyFlags) - Q_ENUMS(MyEnum) - Q_ENUMS(MyAnotherEnum) - Q_FLAGS(MyFlags) public: enum MyEnum { MyEnum1, @@ -85,17 +83,65 @@ namespace MyNamespace { m_flags(MyFlag1|MyFlag2) { } private: + Q_ENUM(MyEnum) + Q_ENUM(MyAnotherEnum) + Q_FLAG(MyFlags) + MyEnum m_enum; MyFlags m_flags; }; Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::MyFlags) + + + // test the old Q_ENUMS macro + class MyClass2 : public QObject + { + Q_OBJECT + Q_PROPERTY(MyEnum myEnum READ myEnum WRITE setMyEnum) + Q_PROPERTY(MyFlags myFlags READ myFlags WRITE setMyFlags) + + public: + enum MyEnum { + MyEnum1, + MyEnum2, + MyEnum3 + }; + enum MyAnotherEnum { + MyAnotherEnum1 = 1, + MyAnotherEnum2 = 2, + MyAnotherEnum3 = -1 + }; + enum MyFlag { + MyFlag1 = 0x01, + MyFlag2 = 0x02, + MyFlag3 = 0x04 + }; + Q_DECLARE_FLAGS(MyFlags, MyFlag) + + MyEnum myEnum() const { return m_enum; } + void setMyEnum(MyEnum val) { m_enum = val; } + + MyFlags myFlags() const { return m_flags; } + void setMyFlags(MyFlags val) { m_flags = val; } + + MyClass2(QObject *parent = 0) + : QObject(parent), + m_enum(MyEnum1), + m_flags(MyFlag1|MyFlag2) + { } + private: + Q_ENUMS(MyEnum MyAnotherEnum) + Q_FLAGS(MyFlags) + + MyEnum m_enum; + MyFlags m_flags; + }; } class tst_QMetaObject : public QObject { Q_OBJECT - Q_ENUMS(EnumType) Q_PROPERTY(EnumType value WRITE setValue READ getValue) Q_PROPERTY(EnumType value2 WRITE set_value READ get_value) Q_PROPERTY(MyStruct value3 WRITE setVal3 READ val3) @@ -109,6 +155,7 @@ class tst_QMetaObject : public QObject public: enum EnumType { EnumType1 }; + Q_ENUM(EnumType); void setValue(EnumType) {} EnumType getValue() const { return EnumType1; } @@ -154,6 +201,7 @@ private slots: void normalizedType_data(); void normalizedType(); void customPropertyType(); + void checkScope_data(); void checkScope(); void propertyNotify(); void propertyConstant(); @@ -177,6 +225,7 @@ private slots: void signal(); void signalIndex_data(); void signalIndex(); + void enumDebugStream(); signals: void value6Changed(); @@ -990,19 +1039,35 @@ void tst_QMetaObject::customPropertyType() QCOMPARE(prop.type(), QVariant::List); } +void tst_QMetaObject::checkScope_data() +{ + QTest::addColumn<QObject *>("object"); + QTest::addColumn<QByteArray>("name"); + + static MyNamespace::MyClass obj1; + static MyNamespace::MyClass2 obj2; + + QTest::newRow("MyClass") << static_cast<QObject*>(&obj1) << QByteArray("MyClass"); + QTest::newRow("MyClass2") << static_cast<QObject*>(&obj2) << QByteArray("MyClass2"); + +} + + void tst_QMetaObject::checkScope() { - MyNamespace::MyClass obj; + QFETCH(QObject *, object); + QFETCH(QByteArray, name); + QObject &obj = *object; bool ok; const QMetaObject *mo = obj.metaObject(); QMetaEnum me = mo->enumerator(mo->indexOfEnumerator("MyEnum")); QVERIFY(me.isValid()); QVERIFY(!me.isFlag()); - QCOMPARE(QLatin1String(me.scope()), QLatin1String("MyNamespace::MyClass")); - QCOMPARE(me.keyToValue("MyNamespace::MyClass::MyEnum2", &ok), 1); + QCOMPARE(QByteArray(me.scope()), QByteArray("MyNamespace::" + name)); + QCOMPARE(me.keyToValue("MyNamespace::" + name + "::MyEnum2", &ok), 1); QCOMPARE(ok, true); - QCOMPARE(me.keyToValue("MyClass::MyEnum2", &ok), -1); + QCOMPARE(me.keyToValue(name + "::MyEnum2", &ok), -1); QCOMPARE(ok, false); QCOMPARE(me.keyToValue("MyNamespace::MyEnum2", &ok), -1); QCOMPARE(ok, false); @@ -1027,10 +1092,10 @@ void tst_QMetaObject::checkScope() QMetaEnum mf = mo->enumerator(mo->indexOfEnumerator("MyFlags")); QVERIFY(mf.isValid()); QVERIFY(mf.isFlag()); - QCOMPARE(QLatin1String(mf.scope()), QLatin1String("MyNamespace::MyClass")); - QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2", &ok), 2); + QCOMPARE(QByteArray(mf.scope()), QByteArray("MyNamespace::" + name)); + QCOMPARE(mf.keysToValue("MyNamespace::" + name + "::MyFlag2", &ok), 2); QCOMPARE(ok, true); - QCOMPARE(mf.keysToValue("MyClass::MyFlag2", &ok), -1); + QCOMPARE(mf.keysToValue(name + "::MyFlag2", &ok), -1); QCOMPARE(ok, false); QCOMPARE(mf.keysToValue("MyNamespace::MyFlag2", &ok), -1); QCOMPARE(ok, false); @@ -1039,9 +1104,9 @@ void tst_QMetaObject::checkScope() QCOMPARE(mf.keysToValue("MyFlag", &ok), -1); QCOMPARE(ok, false); QCOMPARE(QLatin1String(mf.valueToKey(2)), QLatin1String("MyFlag2")); - QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag1|MyNamespace::MyClass::MyFlag2", &ok), 3); + QCOMPARE(mf.keysToValue("MyNamespace::" + name + "::MyFlag1|MyNamespace::" + name + "::MyFlag2", &ok), 3); QCOMPARE(ok, true); - QCOMPARE(mf.keysToValue("MyClass::MyFlag1|MyClass::MyFlag2", &ok), -1); + QCOMPARE(mf.keysToValue(name + "::MyFlag1|" + name + "::MyFlag2", &ok), -1); QCOMPARE(ok, false); QCOMPARE(mf.keysToValue("MyNamespace::MyFlag1|MyNamespace::MyFlag2", &ok), -1); QCOMPARE(ok, false); @@ -1049,9 +1114,9 @@ void tst_QMetaObject::checkScope() QCOMPARE(ok, true); QCOMPARE(mf.keysToValue("MyFlag2|MyFlag2", &ok), 2); QCOMPARE(ok, true); - QCOMPARE(mf.keysToValue("MyFlag1|MyNamespace::MyClass::MyFlag2", &ok), 3); + QCOMPARE(mf.keysToValue("MyFlag1|MyNamespace::" + name + "::MyFlag2", &ok), 3); QCOMPARE(ok, true); - QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2|MyNamespace::MyClass::MyFlag2", &ok), 2); + QCOMPARE(mf.keysToValue("MyNamespace::" + name + "::MyFlag2|MyNamespace::" + name + "::MyFlag2", &ok), 2); QCOMPARE(ok, true); QCOMPARE(QLatin1String(mf.valueToKeys(3)), QLatin1String("MyFlag1|MyFlag2")); } @@ -1142,7 +1207,6 @@ void tst_QMetaObject::metaMethod() QCOMPARE(str, QString("foo")); QCOMPARE(ret, QString("bar")); - QtTestObject obj; QString t1("1"); QString t2("2"); QString t3("3"); QString t4("4"); QString t5("5"); QString t6("6"); QString t7("7"); QString t8("8"); QString t9("9"); QString t10("X"); @@ -1348,5 +1412,12 @@ void tst_QMetaObject::signalIndex() SignalTestHelper::signalIndex(mm)); } +void tst_QMetaObject::enumDebugStream() +{ + QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyEnum(MyEnum2) world "); + MyNamespace::MyClass::MyEnum e = MyNamespace::MyClass::MyEnum2; + qDebug() << "hello" << e << "world"; +} + QTEST_MAIN(tst_QMetaObject) #include "tst_qmetaobject.moc" diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp index 5cac80191c..df76dfc47f 100644 --- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp +++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -50,6 +51,8 @@ private slots: void hasStdCppSet(); void isConstant(); void isFinal(); + void gadget(); + void readAndWriteWithLazyRegistration(); public: enum EnumType { EnumType1 }; @@ -103,5 +106,82 @@ void tst_QMetaProperty::isFinal() QVERIFY(!prop.isFinal()); } +class MyGadget { + Q_GADGET + Q_PROPERTY(QString value READ getValue WRITE setValue RESET resetValue) +public: + QString m_value; + void setValue(const QString &value) { m_value = value; } + QString getValue() { return m_value; } + void resetValue() { m_value = QLatin1Literal("reset"); } +}; + +void tst_QMetaProperty::gadget() +{ + const QMetaObject *mo = &MyGadget::staticMetaObject; + QMetaProperty valueProp = mo->property(mo->indexOfProperty("value")); + QVERIFY(valueProp.isValid()); + { + MyGadget g; + QString hello = QLatin1Literal("hello"); + QVERIFY(valueProp.writeOnGadget(&g, hello)); + QCOMPARE(g.m_value, QLatin1String("hello")); + QCOMPARE(valueProp.readOnGadget(&g), QVariant(hello)); + QVERIFY(valueProp.resetOnGadget(&g)); + QCOMPARE(valueProp.readOnGadget(&g), QVariant(QLatin1String("reset"))); + } +} + +struct CustomReadObject : QObject +{ + Q_OBJECT +}; + +struct CustomWriteObject : QObject +{ + Q_OBJECT +}; + +struct CustomWriteObjectChild : CustomWriteObject +{ + Q_OBJECT +}; + +struct TypeLazyRegistration : QObject +{ + Q_OBJECT + Q_PROPERTY(CustomReadObject *read MEMBER _read) + Q_PROPERTY(CustomWriteObject *write MEMBER _write) + + CustomReadObject *_read; + CustomWriteObject *_write; + +public: + TypeLazyRegistration() + : _read() + , _write() + {} +}; + +void tst_QMetaProperty::readAndWriteWithLazyRegistration() +{ + QCOMPARE(QMetaType::type("CustomReadObject*"), int(QMetaType::UnknownType)); + QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType)); + + TypeLazyRegistration o; + QVERIFY(o.property("read").isValid()); + QVERIFY(QMetaType::type("CustomReadObject*") != QMetaType::UnknownType); + QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType)); + + CustomWriteObjectChild data; + QVariant value = QVariant::fromValue(&data); // this register CustomWriteObjectChild + // check if base classes are not registered automatically, otherwise this test would be meaningless + QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType)); + QVERIFY(o.setProperty("write", value)); + QVERIFY(QMetaType::type("CustomWriteObject*") != QMetaType::UnknownType); + QCOMPARE(o.property("write").value<CustomWriteObjectChild*>(), &data); +} + + QTEST_MAIN(tst_QMetaProperty) #include "tst_qmetaproperty.moc" diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index a35896283a..c76892c24f 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -79,6 +79,10 @@ private slots: void normalizedTypes(); void typeName_data(); void typeName(); + void type_data(); + void type(); + void type_fromSubString_data(); + void type_fromSubString(); void create_data(); void create(); void createCopy_data(); @@ -109,6 +113,7 @@ private slots: void saveAndLoadBuiltin_data(); void saveAndLoadBuiltin(); void saveAndLoadCustom(); + void metaObject_data(); void metaObject(); void constexprMetaTypeIds(); void constRefs(); @@ -116,6 +121,7 @@ private slots: void convertCustomType(); void compareCustomType_data(); void compareCustomType(); + void compareCustomEqualOnlyType(); void customDebugStream(); }; @@ -385,6 +391,61 @@ void tst_QMetaType::typeName() QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData())); } +void tst_QMetaType::type_data() +{ + QTest::addColumn<QMetaType::Type>("aType"); + QTest::addColumn<QByteArray>("aTypeName"); + +#define TST_QMETATYPE_TYPE_DATA(MetaTypeName, MetaTypeId, RealType)\ + QTest::newRow(#RealType) << QMetaType::MetaTypeName << QByteArray( #RealType ); +#define TST_QMETATYPE_TYPE_DATA_ALIAS(MetaTypeName, MetaTypeId, AliasType, RealTypeString)\ + QTest::newRow(RealTypeString) << QMetaType::MetaTypeName << QByteArray( #AliasType ); + + QTest::newRow("empty") << QMetaType::UnknownType << QByteArray(); + + QT_FOR_EACH_STATIC_TYPE(TST_QMETATYPE_TYPE_DATA) + QT_FOR_EACH_STATIC_ALIAS_TYPE(TST_QMETATYPE_TYPE_DATA_ALIAS) + +#undef TST_QMETATYPE_TYPE_DATA +#undef TST_METATYPE_TYPE_DATA_ALIAS +} + +void tst_QMetaType::type() +{ + QFETCH(QMetaType::Type, aType); + QFETCH(QByteArray, aTypeName); + + // QMetaType::type(QByteArray) + QCOMPARE(QMetaType::type(aTypeName), int(aType)); + // QMetaType::type(const char *) + QCOMPARE(QMetaType::type(aTypeName.constData()), int(aType)); +} + +void tst_QMetaType::type_fromSubString_data() +{ + QTest::addColumn<int>("offset"); + QTest::addColumn<int>("size"); + QTest::addColumn<int>("expectedType"); + + // The test string is defined in the test function below + QTest::newRow("int") << 0 << 3 << int(QMetaType::Int); + QTest::newRow("boo") << 3 << 3 << 0; + QTest::newRow("bool") << 3 << 4 << int(QMetaType::Bool); + QTest::newRow("intbool") << 0 << 7 << 0; + QTest::newRow("QMetaType::Type") << 7 << 15 << ::qMetaTypeId<QMetaType::Type>(); + QTest::newRow("double") << 22 << 6 << int(QMetaType::Double); +} + +void tst_QMetaType::type_fromSubString() +{ + static const char *types = "intboolQMetaType::Typedoublexxx"; + QFETCH(int, offset); + QFETCH(int, size); + QFETCH(int, expectedType); + QByteArray ba = QByteArray::fromRawData(types + offset, size); + QCOMPARE(QMetaType::type(ba), expectedType); +} + #define FOR_EACH_PRIMITIVE_METATYPE(F) \ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \ QT_FOR_EACH_STATIC_CORE_POINTER(F) \ @@ -968,7 +1029,9 @@ void tst_QMetaType::flagsBinaryCompatibility5_0() QFETCH(quint32, id); QFETCH(quint32, flags); - QCOMPARE(quint32(QMetaType::typeFlags(id)), flags); + quint32 mask_5_0 = 0x1ff; // Only compare the values that were already defined in 5.0 + + QCOMPARE(quint32(QMetaType::typeFlags(id)) & mask_5_0, flags); } void tst_QMetaType::construct_data() @@ -1772,17 +1835,48 @@ void tst_QMetaType::saveAndLoadCustom() QCOMPARE(stream.status(), QDataStream::ReadPastEnd); } +class MyGadget { + Q_GADGET; +public: + enum MyEnum { Val1, Val2, Val3 }; + Q_ENUM(MyEnum) +}; + +Q_DECLARE_METATYPE(MyGadget); +Q_DECLARE_METATYPE(const QMetaObject *); +Q_DECLARE_METATYPE(Qt::ScrollBarPolicy); +Q_DECLARE_METATYPE(MyGadget::MyEnum); + +void tst_QMetaType::metaObject_data() +{ + QTest::addColumn<int>("type"); + QTest::addColumn<const QMetaObject*>("result"); + QTest::addColumn<bool>("isGadget"); + QTest::addColumn<bool>("isQObjectPtr"); + + QTest::newRow("QObject") << int(QMetaType::QObjectStar) << &QObject::staticMetaObject << false << true; + QTest::newRow("QFile*") << ::qMetaTypeId<QFile*>() << &QFile::staticMetaObject << false << true; + QTest::newRow("MyObject*") << ::qMetaTypeId<MyObject*>() << &MyObject::staticMetaObject << false << true; + QTest::newRow("int") << int(QMetaType::Int) << static_cast<const QMetaObject *>(0) << false << false; + QTest::newRow("QEasingCurve") << ::qMetaTypeId<QEasingCurve>() << &QEasingCurve::staticMetaObject << true << false; + QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false; + QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false; + QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false; +} + + void tst_QMetaType::metaObject() { - QCOMPARE(QMetaType::metaObjectForType(QMetaType::QObjectStar), &QObject::staticMetaObject); - QCOMPARE(QMetaType::metaObjectForType(::qMetaTypeId<QFile*>()), &QFile::staticMetaObject); - QCOMPARE(QMetaType::metaObjectForType(::qMetaTypeId<MyObject*>()), &MyObject::staticMetaObject); - QCOMPARE(QMetaType::metaObjectForType(QMetaType::Int), static_cast<const QMetaObject *>(0)); + QFETCH(int, type); + QFETCH(const QMetaObject *, result); + QFETCH(bool, isGadget); + QFETCH(bool, isQObjectPtr); - QCOMPARE(QMetaType(QMetaType::QObjectStar).metaObject(), &QObject::staticMetaObject); - QCOMPARE(QMetaType(::qMetaTypeId<QFile*>()).metaObject(), &QFile::staticMetaObject); - QCOMPARE(QMetaType(::qMetaTypeId<MyObject*>()).metaObject(), &MyObject::staticMetaObject); - QCOMPARE(QMetaType(QMetaType::Int).metaObject(), static_cast<const QMetaObject *>(0)); + QCOMPARE(QMetaType::metaObjectForType(type), result); + QMetaType mt(type); + QCOMPARE(mt.metaObject(), result); + QCOMPARE(!!(mt.flags() & QMetaType::IsGadget), isGadget); + QCOMPARE(!!(mt.flags() & QMetaType::PointerToQObject), isQObjectPtr); } #define METATYPE_ID_FUNCTION(Type, MetaTypeId, Name) \ @@ -1917,9 +2011,23 @@ bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs) { return !operator==(lhs, rhs); } + +struct CustomEqualsOnlyType +{ + explicit CustomEqualsOnlyType(int value = 0) : val(value) {} + virtual ~CustomEqualsOnlyType() {} + + int val; +}; +bool operator==(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs) +{ return lhs.val == rhs.val;} +bool operator!=(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs) +{ return !operator==(lhs, rhs); } + Q_DECLARE_METATYPE(CustomConvertibleType); Q_DECLARE_METATYPE(CustomConvertibleType2); Q_DECLARE_METATYPE(CustomDebugStreamableType); +Q_DECLARE_METATYPE(CustomEqualsOnlyType); template<typename T, typename U> U convert(const T &t) @@ -2196,6 +2304,81 @@ void tst_QMetaType::compareCustomType() QCOMPARE(unsorted, sorted); } +void tst_QMetaType::compareCustomEqualOnlyType() +{ + int metaTypeId = qRegisterMetaType<CustomEqualsOnlyType>(); + QMetaType::registerEqualsComparator<CustomEqualsOnlyType>(); + int result; + + CustomEqualsOnlyType val50(50); + CustomEqualsOnlyType val100(100); + CustomEqualsOnlyType val100x(100); + + QVariant variant50 = QVariant::fromValue(val50); + QVariant variant100 = QVariant::fromValue(val100); + QVariant variant100x = QVariant::fromValue(val100x); + + QVERIFY(variant50 != variant100); + QVERIFY(variant50 != variant100x); + QVERIFY(variant100 != variant50); + QVERIFY(variant100x != variant50); + QVERIFY(variant100 == variant100x); + QVERIFY(variant100 == variant100); + + // compare always fails + QVERIFY(!(variant50 < variant50)); + QVERIFY(!(variant50 < variant100)); + QVERIFY(!(variant100 < variant50)); + + // check QMetaType::compare works/doesn't crash for equals only comparators + bool wasSuccess = QMetaType::compare(variant50.constData(), variant50.constData(), + metaTypeId, &result); + QCOMPARE(result, 0); + QVERIFY(wasSuccess); + wasSuccess = QMetaType::compare(variant100.constData(), variant100x.constData(), + metaTypeId, &result); + QCOMPARE(result, 0); + QVERIFY(wasSuccess); + + wasSuccess = QMetaType::compare(variant50.constData(), variant100.constData(), + metaTypeId, &result); + QVERIFY(!wasSuccess); + + // check QMetaType::equals works for equals only comparator + wasSuccess = QMetaType::equals(variant50.constData(), variant50.constData(), + metaTypeId, &result); + QCOMPARE(result, 0); + QVERIFY(wasSuccess); + wasSuccess = QMetaType::equals(variant100.constData(), variant100.constData(), + metaTypeId, &result); + QCOMPARE(result, 0); + QVERIFY(wasSuccess); + wasSuccess = QMetaType::equals(variant100x.constData(), variant100x.constData(), + metaTypeId, &result); + QCOMPARE(result, 0); + QVERIFY(wasSuccess); + wasSuccess = QMetaType::equals(variant100.constData(), variant100x.constData(), + metaTypeId, &result); + QCOMPARE(result, 0); + QVERIFY(wasSuccess); + wasSuccess = QMetaType::equals(variant50.constData(), variant100.constData(), + metaTypeId, &result); + QCOMPARE(result, -1); + QVERIFY(wasSuccess); + wasSuccess = QMetaType::equals(variant50.constData(), variant100x.constData(), + metaTypeId, &result); + QCOMPARE(result, -1); + QVERIFY(wasSuccess); + + //check QMetaType::equals for type w/o equals comparator being registered + CustomMovable movable1; + CustomMovable movable2; + wasSuccess = QMetaType::equals(&movable1, &movable2, + qRegisterMetaType<CustomMovable>(), &result); + QVERIFY(!wasSuccess); + +} + struct MessageHandlerCustom : public MessageHandler { MessageHandlerCustom(const int typeId) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 83cdde5aa4..e5891658bb 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1502,7 +1502,6 @@ typedef QString CustomString; class PropertyObject : public QObject { Q_OBJECT - Q_ENUMS(Alpha Priority) Q_PROPERTY(Alpha alpha READ alpha WRITE setAlpha) Q_PROPERTY(Priority priority READ priority WRITE setPriority) @@ -1564,6 +1563,9 @@ private: float m_float; qreal m_qreal; CustomString m_customString; + + Q_ENUM(Alpha) + Q_ENUM(Priority) }; Q_DECLARE_METATYPE(PropertyObject::Priority) diff --git a/tests/auto/corelib/kernel/qsharedmemory/test/test.pro b/tests/auto/corelib/kernel/qsharedmemory/test/test.pro index 97ba1153df..fabd2cf7a3 100644 --- a/tests/auto/corelib/kernel/qsharedmemory/test/test.pro +++ b/tests/auto/corelib/kernel/qsharedmemory/test/test.pro @@ -3,6 +3,7 @@ CONFIG += testcase QT = core-private testlib mac:CONFIG -= app_bundle +linux:LIBS += -lrt SOURCES += tst_qsharedmemory.cpp TARGET = tst_qsharedmemory diff --git a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp index 7182428f14..bebc23172b 100644 --- a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp +++ b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp @@ -174,7 +174,11 @@ void tst_QSharedMemory::cleanup() #include <private/qsharedmemory_p.h> #include <sys/types.h> #include <sys/ipc.h> +#ifndef QT_POSIX_IPC #include <sys/shm.h> +#else +#include <sys/mman.h> +#endif // QT_POSIX_IPC #include <errno.h> #endif @@ -189,7 +193,10 @@ QString tst_QSharedMemory::helperBinary() int tst_QSharedMemory::remove(const QString &key) { -#ifndef Q_OS_WIN +#ifdef Q_OS_WIN + Q_UNUSED(key); + return 0; +#else // On unix the shared memory might exists from a previously failed test // or segfault, remove it it does if (key.isEmpty()) @@ -202,6 +209,7 @@ int tst_QSharedMemory::remove(const QString &key) return -2; } +#ifndef QT_POSIX_IPC int unix_key = ftok(fileName.toLatin1().constData(), 'Q'); if (-1 == unix_key) { qDebug() << "ftok failed"; @@ -219,11 +227,15 @@ int tst_QSharedMemory::remove(const QString &key) qDebug() << "shmctl failed"; return -5; } - return QFile::remove(fileName); #else - Q_UNUSED(key); - return 0; -#endif + if (shm_unlink(QFile::encodeName(fileName).constData()) == -1) { + qDebug() << "shm_unlink failed"; + return -5; + } +#endif // QT_POSIX_IPC + + return QFile::remove(fileName); +#endif // Q_OS_WIN } /*! diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp index 8195efed99..30deb6ff57 100644 --- a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp +++ b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp @@ -65,7 +65,7 @@ private slots: void processes_data(); void processes(); -#ifndef Q_OS_WIN +#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC) void undo(); #endif void initialValue(); @@ -233,8 +233,8 @@ void tst_QSystemSemaphore::processes() } } -// This test only checks a unix behavior. -#ifndef Q_OS_WIN +// This test only checks a system v unix behavior. +#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC) void tst_QSystemSemaphore::undo() { QSystemSemaphore sem("store", 1, QSystemSemaphore::Create); diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 41a6de214a..ddf387ed8d 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -43,9 +43,10 @@ #include <qlocale.h> #include <qdebug.h> #include <qjsondocument.h> - +#include <quuid.h> #include <limits.h> +#include <float.h> #include <QLinkedList> #include <QRegularExpression> @@ -169,8 +170,9 @@ private slots: void operator_eq_eq_data(); void operator_eq_eq(); - void operator_eq_eq_rhs(); + void compareNumbers_data() const; + void compareNumbers() const; void typeName_data(); void typeName(); @@ -213,7 +215,10 @@ private slots: void toIntFromQString() const; void toIntFromDouble() const; void setValue(); + void fpStringRoundtrip_data() const; + void fpStringRoundtrip() const; + void numericalConvert_data(); void numericalConvert(); void moreCustomTypes(); void movabilityTest(); @@ -985,7 +990,7 @@ void tst_QVariant::toByteArray_data() QTest::newRow( "int" ) << QVariant( -123 ) << QByteArray( "-123" ); QTest::newRow( "uint" ) << QVariant( (uint)123 ) << QByteArray( "123" ); QTest::newRow( "double" ) << QVariant( 123.456 ) << QByteArray( "123.456" ); - QTest::newRow( "float" ) << QVariant( 123.456f ) << QByteArray( "123.456" ); + QTest::newRow( "float" ) << QVariant( 123.456f ) << QByteArray( "123.456001" ); QTest::newRow( "longlong" ) << QVariant( (qlonglong)34 ) << QByteArray( "34" ); QTest::newRow( "ulonglong" ) << QVariant( (qulonglong)34 ) << QByteArray( "34" ); } @@ -1011,7 +1016,7 @@ void tst_QVariant::toString_data() QTest::newRow( "int" ) << QVariant( -123 ) << QString( "-123" ); QTest::newRow( "uint" ) << QVariant( (uint)123 ) << QString( "123" ); QTest::newRow( "double" ) << QVariant( 123.456 ) << QString( "123.456" ); - QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.456" ); + QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.456001" ); QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" ); @@ -1367,12 +1372,12 @@ void tst_QVariant::operator_eq_eq_data() QVariant mUIntQString(QString("42")); QVariant mDouble(42.11); - QVariant mDoubleString(QByteArray("42.11")); - QVariant mDoubleQString(QString("42.11")); + QVariant mDoubleString(QByteArray("42.109999999999999")); + QVariant mDoubleQString(QString("42.109999999999999")); QVariant mFloat(42.11f); - QVariant mFloatString(QByteArray("42.11")); - QVariant mFloatQString(QString("42.11")); + QVariant mFloatString(QByteArray("42.1100006")); + QVariant mFloatQString(QString("42.1100006")); QVariant mLongLong((qlonglong)-42); QVariant mLongLongString(QByteArray("-42")); @@ -1433,6 +1438,13 @@ void tst_QVariant::operator_eq_eq_data() // ### many other combinations missing { + // QUuid can convert to QString, but not the opposite + QUuid uuid(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + QTest::newRow("uuidstring") << QVariant(uuid) << QVariant(uuid.toString()) << true; + QTest::newRow("stringuuid") << QVariant(uuid.toString()) << QVariant(uuid) << true; + } + + { QMap<QString, QVariant> map1; map1.insert( "X", 1 ); @@ -1580,6 +1592,326 @@ void tst_QVariant::operator_eq_eq_rhs() #endif } +void tst_QVariant::compareNumbers_data() const +{ + typedef signed char schar; + QTest::addColumn<QVariant>("v1"); + QTest::addColumn<QVariant>("v2"); + QTest::addColumn<int>("expected"); + + // sanity checking: same types + QTest::newRow("bool1") << QVariant(false) << QVariant(false) << 0; + QTest::newRow("bool2") << QVariant(true) << QVariant(true) << 0; + QTest::newRow("bool3") << QVariant(false) << QVariant(true) << -1; + QTest::newRow("bool4") << QVariant(true) << QVariant(false) << +1; + + QTest::newRow("char1") << qVariantFromValue(char(0)) << qVariantFromValue(char(0)) << 0; + QTest::newRow("char2") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(CHAR_MAX) << 0; + QTest::newRow("char3") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(CHAR_MIN) << 0; + QTest::newRow("char4") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(CHAR_MAX) << -1; + QTest::newRow("char5") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(CHAR_MIN) << +1; + + QTest::newRow("schar1") << qVariantFromValue(schar(0)) << qVariantFromValue(schar(0)) << 0; + QTest::newRow("schar2") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(SCHAR_MAX) << 0; + QTest::newRow("schar3") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(SCHAR_MIN) << 0; + QTest::newRow("schar4") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(SCHAR_MAX) << -1; + QTest::newRow("schar5") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(SCHAR_MIN) << +1; + + QTest::newRow("uchar1") << qVariantFromValue(uchar(0)) << qVariantFromValue(uchar(0)) << 0; + QTest::newRow("uchar2") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(UCHAR_MAX) << 0; + QTest::newRow("uchar3") << qVariantFromValue(uchar(0)) << qVariantFromValue(UCHAR_MAX) << -1; + QTest::newRow("uchar4") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(uchar(0)) << +1; + + QTest::newRow("short1") << qVariantFromValue(short(0)) << qVariantFromValue(short(0)) << 0; + QTest::newRow("short2") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(SHRT_MAX) << 0; + QTest::newRow("short3") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(SHRT_MIN) << 0; + QTest::newRow("short4") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(SHRT_MAX) << -1; + QTest::newRow("short5") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(SHRT_MIN) << +1; + + QTest::newRow("ushort1") << qVariantFromValue(ushort(0)) << qVariantFromValue(ushort(0)) << 0; + QTest::newRow("ushort2") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(USHRT_MAX) << 0; + QTest::newRow("ushort3") << qVariantFromValue(ushort(0)) << qVariantFromValue(USHRT_MAX) << -1; + QTest::newRow("ushort4") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(ushort(0)) << +1; + + QTest::newRow("int1") << qVariantFromValue(int(0)) << qVariantFromValue(int(0)) << 0; + QTest::newRow("int2") << qVariantFromValue(INT_MAX) << qVariantFromValue(INT_MAX) << 0; + QTest::newRow("int3") << qVariantFromValue(INT_MIN) << qVariantFromValue(INT_MIN) << 0; + QTest::newRow("int4") << qVariantFromValue(INT_MIN) << qVariantFromValue(INT_MAX) << -1; + QTest::newRow("int5") << qVariantFromValue(INT_MAX) << qVariantFromValue(INT_MIN) << +1; + + QTest::newRow("uint1") << qVariantFromValue(uint(0)) << qVariantFromValue(uint(0)) << 0; + QTest::newRow("uint2") << qVariantFromValue(UINT_MAX) << qVariantFromValue(UINT_MAX) << 0; + QTest::newRow("uint3") << qVariantFromValue(uint(0)) << qVariantFromValue(UINT_MAX) << -1; + QTest::newRow("uint4") << qVariantFromValue(UINT_MAX) << qVariantFromValue(uint(0)) << +1; + + QTest::newRow("long1") << qVariantFromValue(long(0)) << qVariantFromValue(long(0)) << 0; + QTest::newRow("long2") << qVariantFromValue(LONG_MAX) << qVariantFromValue(LONG_MAX) << 0; + QTest::newRow("long3") << qVariantFromValue(LONG_MIN) << qVariantFromValue(LONG_MIN) << 0; + QTest::newRow("long4") << qVariantFromValue(LONG_MIN) << qVariantFromValue(LONG_MAX) << -1; + QTest::newRow("long5") << qVariantFromValue(LONG_MAX) << qVariantFromValue(LONG_MIN) << +1; + + QTest::newRow("ulong1") << qVariantFromValue(ulong(0)) << qVariantFromValue(ulong(0)) << 0; + QTest::newRow("ulong2") << qVariantFromValue(ULONG_MAX) << qVariantFromValue(ULONG_MAX) << 0; + QTest::newRow("ulong3") << qVariantFromValue(ulong(0)) << qVariantFromValue(ULONG_MAX) << -1; + QTest::newRow("ulong4") << qVariantFromValue(ULONG_MAX) << qVariantFromValue(ulong(0)) << +1; + + QTest::newRow("llong1") << qVariantFromValue(qlonglong(0)) << qVariantFromValue(qlonglong(0)) << 0; + QTest::newRow("llong2") << qVariantFromValue(LLONG_MAX) << qVariantFromValue(LLONG_MAX) << 0; + QTest::newRow("llong3") << qVariantFromValue(LLONG_MIN) << qVariantFromValue(LLONG_MIN) << 0; + QTest::newRow("llong4") << qVariantFromValue(LLONG_MIN) << qVariantFromValue(LLONG_MAX) << -1; + QTest::newRow("llong5") << qVariantFromValue(LLONG_MAX) << qVariantFromValue(LLONG_MIN) << +1; + + QTest::newRow("ullong1") << qVariantFromValue(qulonglong(0)) << qVariantFromValue(qulonglong(0)) << 0; + QTest::newRow("ullong2") << qVariantFromValue(ULLONG_MAX) << qVariantFromValue(ULLONG_MAX) << 0; + QTest::newRow("ullong3") << qVariantFromValue(qulonglong(0)) << qVariantFromValue(ULLONG_MAX) << -1; + QTest::newRow("ullong4") << qVariantFromValue(ULLONG_MAX) << qVariantFromValue(qulonglong(0)) << +1; + + QTest::newRow("float1") << qVariantFromValue(0.f) << qVariantFromValue(0.f) << 0; + QTest::newRow("float2") << qVariantFromValue(-1.f) << qVariantFromValue(0.f) << -1; + QTest::newRow("float3") << qVariantFromValue(0.f) << qVariantFromValue(-1.f) << +1; + QTest::newRow("float4") << qVariantFromValue(-float(qInf())) << qVariantFromValue(0.f) << -1; + QTest::newRow("float5") << qVariantFromValue(0.f) << qVariantFromValue(-float(qInf())) << +1; + + QTest::newRow("double1") << qVariantFromValue(0.) << qVariantFromValue(0.) << 0; + QTest::newRow("double2") << qVariantFromValue(-1.) << qVariantFromValue(0.) << -1; + QTest::newRow("double3") << qVariantFromValue(0.) << qVariantFromValue(-1.) << +1; + QTest::newRow("double4") << qVariantFromValue(-qInf()) << qVariantFromValue(0.) << -1; + QTest::newRow("double5") << qVariantFromValue(0.) << qVariantFromValue(-qInf()) << +1; + + // mixed comparisons + // fp + fp + QTest::newRow("float+double1") << qVariantFromValue(0.f) << qVariantFromValue(0.) << 0; + QTest::newRow("float+double2") << qVariantFromValue(-1.f) << qVariantFromValue(0.) << -1; + QTest::newRow("float+double3") << qVariantFromValue(0.f) << qVariantFromValue(-1.) << +1; + QTest::newRow("float+double4") << qVariantFromValue(-float(qInf())) << qVariantFromValue(0.) << -1; + QTest::newRow("float+double5") << qVariantFromValue(0.f) << qVariantFromValue(-qInf()) << +1; + + // fp + int + QTest::newRow("float+int1") << qVariantFromValue(0.f) << qVariantFromValue(0) << 0; + QTest::newRow("double+int1") << qVariantFromValue(0.) << qVariantFromValue(0) << 0; + QTest::newRow("float+int2") << qVariantFromValue(-1.f) << qVariantFromValue(0) << -1; + QTest::newRow("double+int2") << qVariantFromValue(-1.) << qVariantFromValue(0) << -1; + QTest::newRow("float+int3") << qVariantFromValue(0.f) << qVariantFromValue(-1) << +1; + QTest::newRow("double+int3") << qVariantFromValue(0.) << qVariantFromValue(-1) << +1; + QTest::newRow("float+int4") << qVariantFromValue(1.5f) << qVariantFromValue(1) << +1; + QTest::newRow("double+int4") << qVariantFromValue(1.5) << qVariantFromValue(1) << +1; + + // fp + uint + QTest::newRow("float+uint1") << qVariantFromValue(0.f) << qVariantFromValue(0U) << 0; + QTest::newRow("double+uint1") << qVariantFromValue(0.) << qVariantFromValue(0U) << 0; + QTest::newRow("float+uint2") << qVariantFromValue(-1.f) << qVariantFromValue(0U) << -1; + QTest::newRow("double+uint2") << qVariantFromValue(-1.) << qVariantFromValue(0U) << -1; + QTest::newRow("float+uint3") << qVariantFromValue(0.f) << qVariantFromValue(1U) << -1; + QTest::newRow("double+uint3") << qVariantFromValue(0.) << qVariantFromValue(1U) << -1; + QTest::newRow("float+uint4") << qVariantFromValue(1.5f) << qVariantFromValue(1U) << +1; + QTest::newRow("double+uint4") << qVariantFromValue(1.5) << qVariantFromValue(1U) << +1; + + // lower ranked + int + QTest::newRow("bool+int1") << qVariantFromValue(false) << qVariantFromValue(0) << 0; + QTest::newRow("bool+int2") << qVariantFromValue(false) << qVariantFromValue(1) << -1; + QTest::newRow("bool+int3") << qVariantFromValue(true) << qVariantFromValue(0) << +1; + QTest::newRow("bool+int4") << qVariantFromValue(true) << qVariantFromValue(1) << 0; + QTest::newRow("bool+int5") << qVariantFromValue(true) << qVariantFromValue(2) << -1; + + QTest::newRow("char+int1") << qVariantFromValue(char(0)) << qVariantFromValue(0) << 0; + QTest::newRow("char+int2") << qVariantFromValue(char(0)) << qVariantFromValue(1) << -1; + QTest::newRow("char+int3") << qVariantFromValue(char(1)) << qVariantFromValue(0) << +1; + QTest::newRow("char+int4") << qVariantFromValue(char(1)) << qVariantFromValue(1) << 0; + if (std::numeric_limits<char>::is_signed) { + QTest::newRow("char+int5") << qVariantFromValue(char(-1)) << qVariantFromValue(0) << -1; + QTest::newRow("char+int6") << qVariantFromValue(char(-1)) << qVariantFromValue(-1) << 0; + } + + QTest::newRow("schar+int1") << qVariantFromValue(schar(0)) << qVariantFromValue(0) << 0; + QTest::newRow("schar+int2") << qVariantFromValue(schar(0)) << qVariantFromValue(1) << -1; + QTest::newRow("schar+int3") << qVariantFromValue(schar(1)) << qVariantFromValue(0) << +1; + QTest::newRow("schar+int4") << qVariantFromValue(schar(1)) << qVariantFromValue(1) << 0; + QTest::newRow("schar+int5") << qVariantFromValue(schar(-1)) << qVariantFromValue(0) << -1; + QTest::newRow("schar+int6") << qVariantFromValue(schar(-1)) << qVariantFromValue(-1) << 0; + + QTest::newRow("uchar+int1") << qVariantFromValue(uchar(0)) << qVariantFromValue(0) << 0; + QTest::newRow("uchar+int2") << qVariantFromValue(uchar(0)) << qVariantFromValue(1) << -1; + QTest::newRow("uchar+int3") << qVariantFromValue(uchar(1)) << qVariantFromValue(0) << +1; + QTest::newRow("uchar+int4") << qVariantFromValue(uchar(1)) << qVariantFromValue(1) << 0; + + QTest::newRow("short+int1") << qVariantFromValue(short(0)) << qVariantFromValue(0) << 0; + QTest::newRow("short+int2") << qVariantFromValue(short(0)) << qVariantFromValue(1) << -1; + QTest::newRow("short+int3") << qVariantFromValue(short(1)) << qVariantFromValue(0) << +1; + QTest::newRow("short+int4") << qVariantFromValue(short(1)) << qVariantFromValue(1) << 0; + QTest::newRow("short+int5") << qVariantFromValue(short(-1)) << qVariantFromValue(0) << -1; + QTest::newRow("short+int6") << qVariantFromValue(short(-1)) << qVariantFromValue(-1) << 0; + + QTest::newRow("ushort+int1") << qVariantFromValue(ushort(0)) << qVariantFromValue(0) << 0; + QTest::newRow("ushort+int2") << qVariantFromValue(ushort(0)) << qVariantFromValue(1) << -1; + QTest::newRow("ushort+int3") << qVariantFromValue(ushort(1)) << qVariantFromValue(0) << +1; + QTest::newRow("ushort+int4") << qVariantFromValue(ushort(1)) << qVariantFromValue(1) << 0; + + // lower ranked + uint (without sign change) + QTest::newRow("bool+uint1") << qVariantFromValue(false) << qVariantFromValue(0U) << 0; + QTest::newRow("bool+uint2") << qVariantFromValue(false) << qVariantFromValue(1U) << -1; + QTest::newRow("bool+uint3") << qVariantFromValue(true) << qVariantFromValue(0U) << +1; + QTest::newRow("bool+uint4") << qVariantFromValue(true) << qVariantFromValue(1U) << 0; + QTest::newRow("bool+uint5") << qVariantFromValue(true) << qVariantFromValue(2U) << -1; + + QTest::newRow("char+uint1") << qVariantFromValue(char(0)) << qVariantFromValue(0U) << 0; + QTest::newRow("char+uint2") << qVariantFromValue(char(0)) << qVariantFromValue(1U) << -1; + QTest::newRow("char+uint3") << qVariantFromValue(char(1)) << qVariantFromValue(0U) << +1; + QTest::newRow("char+uint4") << qVariantFromValue(char(1)) << qVariantFromValue(1U) << 0; + + QTest::newRow("schar+uint1") << qVariantFromValue(schar(0)) << qVariantFromValue(0U) << 0; + QTest::newRow("schar+uint2") << qVariantFromValue(schar(0)) << qVariantFromValue(1U) << -1; + QTest::newRow("schar+uint3") << qVariantFromValue(schar(1)) << qVariantFromValue(0U) << +1; + QTest::newRow("schar+uint4") << qVariantFromValue(schar(1)) << qVariantFromValue(1U) << 0; + + QTest::newRow("uchar+uint1") << qVariantFromValue(uchar(0)) << qVariantFromValue(0U) << 0; + QTest::newRow("uchar+uint2") << qVariantFromValue(uchar(0)) << qVariantFromValue(1U) << -1; + QTest::newRow("uchar+uint3") << qVariantFromValue(uchar(1)) << qVariantFromValue(0U) << +1; + QTest::newRow("uchar+uint4") << qVariantFromValue(uchar(1)) << qVariantFromValue(1U) << 0; + + QTest::newRow("short+uint1") << qVariantFromValue(short(0)) << qVariantFromValue(0U) << 0; + QTest::newRow("short+uint2") << qVariantFromValue(short(0)) << qVariantFromValue(1U) << -1; + QTest::newRow("short+uint3") << qVariantFromValue(short(1)) << qVariantFromValue(0U) << +1; + QTest::newRow("short+uint4") << qVariantFromValue(short(1)) << qVariantFromValue(1U) << 0; + + QTest::newRow("ushort+uint1") << qVariantFromValue(ushort(0)) << qVariantFromValue(0U) << 0; + QTest::newRow("ushort+uint2") << qVariantFromValue(ushort(0)) << qVariantFromValue(1U) << -1; + QTest::newRow("ushort+uint3") << qVariantFromValue(ushort(1)) << qVariantFromValue(0U) << +1; + QTest::newRow("ushort+uint4") << qVariantFromValue(ushort(1)) << qVariantFromValue(1U) << 0; + + // int + qlonglong + QTest::newRow("int+qlonglong1") << qVariantFromValue(0) << qVariantFromValue(Q_INT64_C(0)) << 0; + QTest::newRow("int+qlonglong2") << qVariantFromValue(1) << qVariantFromValue(Q_INT64_C(0)) << +1; + QTest::newRow("int+qlonglong3") << qVariantFromValue(0) << qVariantFromValue(Q_INT64_C(1)) << -1; + QTest::newRow("int+qlonglong4") << qVariantFromValue(1) << qVariantFromValue(Q_INT64_C(1)) << 0; + QTest::newRow("int+qlonglong5") << qVariantFromValue(0) << qVariantFromValue(Q_INT64_C(-1)) << +1; + QTest::newRow("int+qlonglong6") << qVariantFromValue(-1) << qVariantFromValue(Q_INT64_C(0)) << -1; + QTest::newRow("int+qlonglong7") << qVariantFromValue(-1) << qVariantFromValue(Q_INT64_C(-1)) << 0; + + // uint + qulonglong + QTest::newRow("uint+qulonglong1") << qVariantFromValue(0U) << qVariantFromValue(Q_UINT64_C(0)) << 0; + QTest::newRow("uint+qulonglong2") << qVariantFromValue(1U) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("uint+qulonglong3") << qVariantFromValue(0U) << qVariantFromValue(Q_UINT64_C(1)) << -1; + QTest::newRow("uint+qulonglong4") << qVariantFromValue(1U) << qVariantFromValue(Q_UINT64_C(1)) << 0; + + // int + uint (without sign change) + QTest::newRow("int+uint1") << qVariantFromValue(0) << qVariantFromValue(0U) << 0; + QTest::newRow("int+uint2") << qVariantFromValue(1) << qVariantFromValue(0U) << +1; + QTest::newRow("int+uint3") << qVariantFromValue(0) << qVariantFromValue(1U) << -1; + QTest::newRow("int+uint4") << qVariantFromValue(1) << qVariantFromValue(1U) << 0; + + // uint + qlonglong + QTest::newRow("uint+qlonglong1") << qVariantFromValue(0U) << qVariantFromValue(Q_INT64_C(0)) << 0; + QTest::newRow("uint+qlonglong2") << qVariantFromValue(1U) << qVariantFromValue(Q_INT64_C(0)) << +1; + QTest::newRow("uint+qlonglong3") << qVariantFromValue(0U) << qVariantFromValue(Q_INT64_C(1)) << -1; + QTest::newRow("uint+qlonglong4") << qVariantFromValue(1U) << qVariantFromValue(Q_INT64_C(1)) << 0; + QTest::newRow("uint+qlonglong5") << qVariantFromValue(0U) << qVariantFromValue(Q_INT64_C(-1)) << +1; + + // boundary conditions + QTest::newRow("charmax+intmax") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(INT_MAX) << -1; + QTest::newRow("charmax+uintmax") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(UINT_MAX) << -1; + QTest::newRow("scharmax+intmax") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(INT_MAX) << -1; + QTest::newRow("scharmax+uintmax") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(UINT_MAX) << -1; + QTest::newRow("ucharmax+intmax") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(INT_MAX) << -1; + QTest::newRow("ucharmax+uintmax") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(UINT_MAX) << -1; + QTest::newRow("shortmax+intmax") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(INT_MAX) << -1; + QTest::newRow("shortmax+uintmax") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(UINT_MAX) << -1; + QTest::newRow("ushortmax+intmax") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(INT_MAX) << -1; + QTest::newRow("ushortmax+uintmax") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(UINT_MAX) << -1; + + QTest::newRow("intmin+qlonglongmin") << qVariantFromValue(INT_MIN) << qVariantFromValue(LLONG_MIN) << +1; + QTest::newRow("intmax+uintmax") << qVariantFromValue(INT_MAX) << qVariantFromValue(UINT_MAX) << -1; + QTest::newRow("intmax+qlonglongmax") << qVariantFromValue(INT_MAX) << qVariantFromValue(LLONG_MAX) << -1; + QTest::newRow("uintmax+qlonglongmax") << qVariantFromValue(UINT_MAX) << qVariantFromValue(LLONG_MAX) << -1; + QTest::newRow("intmax+qulonglongmax") << qVariantFromValue(INT_MAX) << qVariantFromValue(ULLONG_MAX) << -1; + QTest::newRow("qlonglongmax+qulonglongmax") << qVariantFromValue(LLONG_MAX) << qVariantFromValue(ULLONG_MAX) << -1; + QTest::newRow("uintmax+qlonglongmin") << qVariantFromValue(UINT_MAX) << qVariantFromValue(LLONG_MIN) << +1; + + // check for no sign-extension issues + QTest::newRow("ushortmax+intzero") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(0) << +1; + QTest::newRow("ushortmax+qlonglongzero") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(Q_INT64_C(0)) << +1; + QTest::newRow("uintmax+qlonglongzero") << qVariantFromValue(UINT_MAX) << qVariantFromValue(Q_INT64_C(0)) << +1; + + // sign changes + // the tests below check that a signed negative number sign-changes to a non-zero unsigned number and that + // signed -1 sign-changes to unsigned maximum (all bits set, ~0). This works on two's complement machines + // (all that Qt supports), and would also work on one's complement. + if (std::numeric_limits<char>::is_signed) { + QTest::newRow("signchange-char+uint") << qVariantFromValue(char(-1)) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-char+uintmax") << qVariantFromValue(char(-1)) << qVariantFromValue(UINT_MAX) << 0; + QTest::newRow("signchange-charmin+uint") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-char+qulonglong") << qVariantFromValue(char(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("signchange-char+qulonglongmax") << qVariantFromValue(char(-1)) << qVariantFromValue(ULLONG_MAX) << 0; + QTest::newRow("signchange-charmin+qulonglong") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1; + } + QTest::newRow("signchange-schar+uint") << qVariantFromValue(schar(-1)) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-schar+uintmax") << qVariantFromValue(schar(-1)) << qVariantFromValue(UINT_MAX) << 0; + QTest::newRow("signchange-scharmin+uint") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-schar+qulonglong") << qVariantFromValue(schar(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("signchange-schar+qulonglongmax") << qVariantFromValue(schar(-1)) << qVariantFromValue(ULLONG_MAX) << 0; + QTest::newRow("signchange-scharmin+qulonglong") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("signchange-short+uint") << qVariantFromValue(short(-1)) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-short+uintmax") << qVariantFromValue(short(-1)) << qVariantFromValue(UINT_MAX) << 0; + QTest::newRow("signchange-shortmin+uint") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-short+qulonglong") << qVariantFromValue(short(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("signchange-short+qulonglongmax") << qVariantFromValue(short(-1)) << qVariantFromValue(ULLONG_MAX) << 0; + QTest::newRow("signchange-shortmin+qulonglong") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("signchange-int+uint") << qVariantFromValue(-1) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-int+uintmax") << qVariantFromValue(-1) << qVariantFromValue(UINT_MAX) << 0; + QTest::newRow("signchange-intmin+uint") << qVariantFromValue(INT_MIN) << qVariantFromValue(0U) << +1; + QTest::newRow("signchange-int+qulonglong") << qVariantFromValue(-1) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("signchange-int+qulonglongmax") << qVariantFromValue(-1) << qVariantFromValue(ULLONG_MAX) << 0; + QTest::newRow("signchange-intmin+qulonglong") << qVariantFromValue(INT_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1; + // no qlonglong+uint, since that should promote to qlonglong and then the comparison is signed (tested above) + QTest::newRow("signchange-qlonglong+qulonglong") << qVariantFromValue(Q_INT64_C(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1; + QTest::newRow("signchange-qlonglong+qulonglongmax") << qVariantFromValue(Q_INT64_C(-1)) << qVariantFromValue(ULLONG_MAX) << 0; + QTest::newRow("signchange-qlonglongmin+qulonglong") << qVariantFromValue(LLONG_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1; +} + +void tst_QVariant::compareNumbers() const +{ + QFETCH(QVariant, v1); + QFETCH(QVariant, v2); + QFETCH(int, expected); + + if (expected == -1) { + QVERIFY(v1 < v2); + QVERIFY(v1 <= v2); + QVERIFY(!(v1 == v2)); + QVERIFY(!(v1 > v2)); + QVERIFY(!(v1 >= v2)); + + QVERIFY(!(v2 < v1)); + QVERIFY(!(v2 <= v1)); + QVERIFY(!(v2 == v1)); + QVERIFY(v2 >= v1); + QVERIFY(v2 > v1); + } else if (expected == 0) { + QVERIFY(!(v1 < v2)); + QVERIFY(v1 <= v2); + QCOMPARE(v1, v2); + QVERIFY(!(v1 > v2)); + QVERIFY(v1 >= v2); + + QVERIFY(!(v2 < v1)); + QVERIFY(v2 <= v1); + QCOMPARE(v2, v1); + QVERIFY(v2 >= v1); + QVERIFY(!(v2 > v1)); + } else { + QVERIFY(!(v1 < v2)); + QVERIFY(!(v1 <= v2)); + QVERIFY(!(v1 == v2)); + QVERIFY(v1 > v2); + QVERIFY(v1 >= v2); + + QVERIFY(v2 < v1); + QVERIFY(v2 <= v1); + QVERIFY(!(v2 == v1)); + QVERIFY(!(v2 >= v1)); + QVERIFY(!(v2 > v1)); + } +} + void tst_QVariant::typeName_data() { QTest::addColumn<int>("type"); @@ -2945,41 +3277,72 @@ void tst_QVariant::setValue() QVERIFY( v2.isDetached() ); } +void tst_QVariant::fpStringRoundtrip_data() const +{ + QTest::addColumn<QVariant>("number"); + + QTest::newRow("float") << QVariant(1 + FLT_EPSILON); + QTest::newRow("double") << QVariant(1 + DBL_EPSILON); +} + +void tst_QVariant::fpStringRoundtrip() const +{ + QFETCH(QVariant, number); + + QVariant converted = number; + QVERIFY(converted.convert(QVariant::String)); + QVERIFY(converted.convert(number.type())); + QCOMPARE(converted, number); + + converted = number; + QVERIFY(converted.convert(QVariant::ByteArray)); + QVERIFY(converted.convert(number.type())); + QCOMPARE(converted, number); +} + +void tst_QVariant::numericalConvert_data() +{ + QTest::addColumn<QVariant>("v"); + QTest::addColumn<bool>("isInteger"); + QTest::newRow("float") << QVariant(float(5.3)) << false; + QTest::newRow("double") << QVariant(double(5.3)) << false; + QTest::newRow("qreal") << QVariant(qreal(5.3)) << false; + QTest::newRow("int") << QVariant(int(5)) << true; + QTest::newRow("uint") << QVariant(uint(5)) << true; + QTest::newRow("short") << QVariant(short(5)) << true; + QTest::newRow("longlong") << QVariant(quint64(5)) << true; + QTest::newRow("long") << QVariant::fromValue(long(5)) << true; + QTest::newRow("stringint") << QVariant(QString::fromLatin1("5")) << true; + QTest::newRow("string") << QVariant(QString::fromLatin1("5.30000019")) << false; +} + void tst_QVariant::numericalConvert() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) QSKIP("Known to fail due to a GCC bug on at least Ubuntu 10.04 32-bit - check QTBUG-8959"); #endif - QVariant vfloat(float(5.3)); - QVariant vdouble(double(5.3)); - QVariant vreal(qreal(5.3)); - QVariant vint(int(5)); - QVariant vuint(uint(5)); - QVariant vshort(short(5)); - QVariant vlonglong(quint64(5)); - QVariant vlong = QVariant::fromValue(long(5)); - QVariant vstringint(QString::fromLatin1("5")); - QVariant vstring(QString::fromLatin1("5.3")); - - QVector<QVariant *> vect; - vect << &vfloat << &vdouble << &vreal << &vint << &vuint << &vshort<< &vlonglong << &vlong << &vstringint << &vstring; - - for(int i = 0; i < vect.size(); i++) { - double num = 5.3; - if (i >= 3 && i <= 8) - num = 5; - QVariant *v = vect.at(i); - QCOMPARE(v->toFloat() , float(num)); - QCOMPARE(float(v->toReal()) , float(num)); - QCOMPARE(float(v->toDouble()) , float(num)); - if (i != 9) { - QCOMPARE(v->toInt() , int(num)); - QCOMPARE(v->toUInt() , uint(num)); - QCOMPARE(v->toULongLong() , quint64(num)); - QCOMPARE(v->value<ulong>() , ulong(num)); - QCOMPARE(v->value<ushort>() , ushort(num)); - } - QCOMPARE(v->toString() , QString::number(num)); + QFETCH(QVariant, v); + QFETCH(bool, isInteger); + double num = isInteger ? 5 : 5.3; + + QCOMPARE(v.toFloat() , float(num)); + QCOMPARE(float(v.toReal()) , float(num)); + QCOMPARE(float(v.toDouble()) , float(num)); + if (isInteger) { + QCOMPARE(v.toInt() , int(num)); + QCOMPARE(v.toUInt() , uint(num)); + QCOMPARE(v.toULongLong() , quint64(num)); + QCOMPARE(v.value<ulong>() , ulong(num)); + QCOMPARE(v.value<ushort>() , ushort(num)); + } + switch (v.userType()) + { + case QVariant::Double: + QCOMPARE(v.toString() , QString::number(num, 'g', DBL_MANT_DIG * log10(2.) + 2)); + break; + case QMetaType::Float: + QCOMPARE(v.toString() , QString::number(float(num), 'g', FLT_MANT_DIG * log10(2.) + 2)); + break; } } @@ -3214,8 +3577,8 @@ void tst_QVariant::moreCustomTypes() QCOMPARE(MyNotMovable::count, 0); { - PLAY_WITH_VARIANT(12.12, false, "12.12", 12.12, true); - PLAY_WITH_VARIANT(12.12f, false, "12.12", 12.12f, true); + PLAY_WITH_VARIANT(12.12, false, "12.119999999999999", 12.12, true); + PLAY_WITH_VARIANT(12.12f, false, "12.1199999", 12.12f, true); PLAY_WITH_VARIANT('a', false, "a", 'a', true); PLAY_WITH_VARIANT((unsigned char)('a'), false, "a", 'a', true); PLAY_WITH_VARIANT( quint8(12), false, "\xc", 12, true); @@ -4044,10 +4407,13 @@ void tst_QVariant::iterateContainerElements() QCOMPARE(varMap.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ QCOMPARE(varHash.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ QCOMPARE(actual, expected); \ + const QAssociativeIterable::const_iterator it = mappingIter.find(key); \ + QVERIFY(it != mappingIter.end()); \ + QCOMPARE(it.value().value<MAPPED_TYPE>(), expected); \ } \ QCOMPARE(numSeen, (int)std::distance(mapping.begin(), mapping.end())); \ QCOMPARE(containerIter, containerEnd); \ - \ + QVERIFY(mappingIter.find(10) == mappingIter.end()); \ } TEST_ASSOCIATIVE_ITERATION(QHash, int, bool) diff --git a/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp b/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp index 820039b6a9..7592a0cee1 100644 --- a/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp +++ b/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp @@ -205,12 +205,16 @@ void tst_QState::transitions() QVERIFY(s1.transitions().isEmpty()); QAbstractTransition *t1 = s1.addTransition(this, SIGNAL(destroyed()), &s2); + QAbstractTransition *t1_1 = s1.addTransition(this, &tst_QState::destroyed, &s2); QVERIFY(t1 != 0); - QCOMPARE(s1.transitions().count(), 1); + QVERIFY(t1_1 != 0); + QCOMPARE(s1.transitions().count(), 2); QCOMPARE(s1.transitions().first(), t1); + QCOMPARE(s1.transitions().last(), t1_1); QVERIFY(s2.transitions().isEmpty()); s1.removeTransition(t1); + s1.removeTransition(t1_1); QVERIFY(s1.transitions().isEmpty()); s1.addTransition(t1); diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp index 425a07b3a7..605a1525e3 100644 --- a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp +++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp @@ -94,13 +94,9 @@ # define QATOMIC_TEST_NOT_SUPPORTED #endif -#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) -# pragma GCC diagnostic ignored "-Wtype-limits" -# pragma GCC diagnostic ignored "-Wsign-compare" -#endif -#if defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) -# pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" -#endif +QT_WARNING_DISABLE_GCC("-Wtype-limits") +QT_WARNING_DISABLE_GCC("-Wsign-compare") +QT_WARNING_DISABLE_CLANG("-Wtautological-constant-out-of-range-compare") typedef signed char schar; diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 9c2c8bf12a..1f1cf1db0c 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -92,6 +92,7 @@ private slots: void priorityStart(); void waitForDone(); void clear(); + void cancel(); void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); void stressTest(); @@ -958,6 +959,56 @@ void tst_QThreadPool::clear() QCOMPARE(count.load(), threadPool.maxThreadCount()); } +void tst_QThreadPool::cancel() +{ + QSemaphore sem(0); + class BlockingRunnable : public QRunnable + { + public: + QSemaphore & sem; + int & dtorCounter; + int & runCounter; + int dummy; + BlockingRunnable(QSemaphore & s, int & c, int & r) : sem(s), dtorCounter(c), runCounter(r){} + ~BlockingRunnable(){dtorCounter++;} + void run() + { + runCounter++; + sem.acquire(); + count.ref(); + } + }; + typedef BlockingRunnable* BlockingRunnablePtr; + + QThreadPool threadPool; + threadPool.setMaxThreadCount(3); + int runs = 2 * threadPool.maxThreadCount(); + BlockingRunnablePtr* runnables = new BlockingRunnablePtr[runs]; + count.store(0); + int dtorCounter = 0; + int runCounter = 0; + for (int i = 0; i < runs; i++) { + runnables[i] = new BlockingRunnable(sem, dtorCounter, runCounter); + runnables[i]->setAutoDelete(i != 0 && i != (runs-1)); //one which will run and one which will not + threadPool.cancel(runnables[i]); //verify NOOP for jobs not in the queue + threadPool.start(runnables[i]); + } + for (int i = 0; i < runs; i++) { + threadPool.cancel(runnables[i]); + } + runnables[0]->dummy = 0; //valgrind will catch this if cancel() is crazy enough to delete currently running jobs + runnables[runs-1]->dummy = 0; + QCOMPARE(dtorCounter, runs-threadPool.maxThreadCount()-1); + sem.release(threadPool.maxThreadCount()); + threadPool.waitForDone(); + QCOMPARE(runCounter, threadPool.maxThreadCount()); + QCOMPARE(count.load(), threadPool.maxThreadCount()); + QCOMPARE(dtorCounter, runs-2); + delete runnables[0]; //if the pool deletes them then we'll get double-free crash + delete runnables[runs-1]; + delete[] runnables; +} + void tst_QThreadPool::destroyingWaitsForTasksToFinish() { QTime total, pass; diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index 1dfe01663f..78d3e9e2b8 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -3129,7 +3129,7 @@ void tst_Collections::qtimerList() QFAIL("QList preallocates too much memory"); } -#define QVERIFY_TYPE(Type) QVERIFY(sizeof(Type)) +#define QVERIFY_TYPE(Type) QVERIFY(sizeof(Type) > 0) template <typename Container> void testContainerTypedefs(Container container) diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 5730c4df35..a7c08fddb3 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -789,7 +789,7 @@ void tst_QArrayData::alignment() + minAlignment - Q_ALIGNOF(QArrayData))); // Data is aligned - QCOMPARE(quintptr(data->data()) % alignment, quintptr(0u)); + QCOMPARE(quintptr(quintptr(data->data()) % alignment), quintptr(0u)); // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 18739cb4e1..d010ff807d 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -2000,6 +2000,9 @@ void tst_QByteArray::toUpperLower_data() QTest::addColumn<QByteArray>("lower"); QTest::newRow("empty") << QByteArray() << QByteArray() << QByteArray(); + QTest::newRow("literal") << QByteArrayLiteral("Hello World") + << QByteArrayLiteral("HELLO WORLD") + << QByteArrayLiteral("hello world"); QTest::newRow("ascii") << QByteArray("Hello World, this is a STRING") << QByteArray("HELLO WORLD, THIS IS A STRING") << QByteArray("hello world, this is a string"); @@ -2014,8 +2017,34 @@ void tst_QByteArray::toUpperLower() QFETCH(QByteArray, input); QFETCH(QByteArray, upper); QFETCH(QByteArray, lower); + QCOMPARE(lower.toLower(), lower); + QCOMPARE(upper.toUpper(), upper); QCOMPARE(input.toUpper(), upper); QCOMPARE(input.toLower(), lower); + + QByteArray copy = input; + QCOMPARE(qMove(copy).toUpper(), upper); + copy = input; + copy.detach(); + QCOMPARE(qMove(copy).toUpper(), upper); + + copy = input; + QCOMPARE(qMove(copy).toLower(), lower); + copy = input; + copy.detach(); + QCOMPARE(qMove(copy).toLower(), lower); + + copy = lower; + QCOMPARE(qMove(copy).toLower(), lower); + copy = lower; + copy.detach(); + QCOMPARE(qMove(copy).toLower(), lower); + + copy = upper; + QCOMPARE(qMove(copy).toUpper(), upper); + copy = upper; + copy.detach(); + QCOMPARE(qMove(copy).toUpper(), upper); } void tst_QByteArray::macTypes() diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp index a4350ea2fe..55c911a5fc 100644 --- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp +++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp @@ -47,6 +47,8 @@ public slots: void init(); void cleanup(); private slots: + void operators_data(); + void operators(); void toUpper(); void toLower(); void toTitle(); @@ -99,6 +101,33 @@ void tst_QChar::cleanup() #endif } +void tst_QChar::operators_data() +{ + QTest::addColumn<QChar>("lhs"); + QTest::addColumn<QChar>("rhs"); + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) + QTest::newRow(qPrintable(QString().sprintf("'\\%d' (op) '\\%d'", i, j))) + << QChar(ushort(i)) << QChar(ushort(j)); + } +} + +void tst_QChar::operators() +{ + QFETCH(QChar, lhs); + QFETCH(QChar, rhs); + +#define CHECK(op) QCOMPARE((lhs op rhs), (lhs.unicode() op rhs.unicode())) + CHECK(==); + CHECK(!=); + CHECK(< ); + CHECK(> ); + CHECK(<=); + CHECK(>=); +#undef CHECK +} + void tst_QChar::toUpper() { QVERIFY(QChar('a').toUpper() == 'A'); diff --git a/tests/auto/corelib/tools/qdatetime/qdatetime.pro b/tests/auto/corelib/tools/qdatetime/qdatetime.pro index 0a89fe7645..25d11443e4 100644 --- a/tests/auto/corelib/tools/qdatetime/qdatetime.pro +++ b/tests/auto/corelib/tools/qdatetime/qdatetime.pro @@ -11,3 +11,8 @@ win32-msvc|win32-msvc9x { QMAKE_CXXFLAGS_RELEASE -= -O1 } DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +mac { + OBJECTIVE_SOURCES += tst_qdatetime_mac.mm + LIBS += -framework Foundation +} diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index ae812bef0e..e992c41bc1 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -145,6 +145,8 @@ private slots: void invalid() const; + void macTypes(); + private: enum { LocalTimeIsUtc = 0, LocalTimeAheadOfUtc = 1, LocalTimeBehindUtc = -1} localTimeType; bool europeanTimeZone; @@ -2989,5 +2991,15 @@ void tst_QDateTime::invalid() const QCOMPARE(tzDate.timeSpec(), Qt::TimeZone); } +void tst_QDateTime::macTypes() +{ +#ifndef Q_OS_MAC + QSKIP("This is a Apple-only test"); +#else + extern void tst_QDateTime_macTypes(); // in qdatetime_mac.mm + tst_QDateTime_macTypes(); +#endif +} + QTEST_APPLESS_MAIN(tst_QDateTime) #include "tst_qdatetime.moc" diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm b/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm new file mode 100644 index 0000000000..d03ae3faeb --- /dev/null +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Petroules Corporation. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QDateTime> +#include <QtTest/QtTest> + +#include <CoreFoundation/CoreFoundation.h> +#include <Foundation/Foundation.h> + +void tst_QDateTime_macTypes() +{ + // QDateTime <-> CFDate + { + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const CFDateRef cfDate = qtDateTime.toCFDate(); + QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTime); + CFRelease(cfDate); + } + { + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const CFDateRef cfDate = qtDateTime.toCFDate(); + QDateTime qtDateTimeCopy(qtDateTime); + qtDateTime.setTime_t(10000); // modify + QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTimeCopy); + } + // QDateTime <-> NSDate + { + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const NSDate *nsDate = qtDateTime.toNSDate(); + QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTime); + [autoreleasepool release]; + } + { + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); + const NSDate *nsDate = qtDateTime.toNSDate(); + QDateTime qtDateTimeCopy(qtDateTime); + qtDateTime.setTime_t(10000); // modify + QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTimeCopy); + [autoreleasepool release]; + } +} diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp index d1152419c0..c1d6184072 100644 --- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp @@ -51,6 +51,7 @@ private slots: void operators(); void properties(); void metaTypes(); + void propertyOrderIsNotImportant(); void bezierSpline_data(); void bezierSpline(); void tcbSpline_data(); @@ -552,6 +553,25 @@ void tst_QEasingCurve::metaTypes() QVERIFY(qMetaTypeId<QEasingCurve>() == QMetaType::QEasingCurve); } +/* + Test to ensure that regardless of what order properties are set, they should produce the same + behavior. + */ +void tst_QEasingCurve::propertyOrderIsNotImportant() +{ + + QEasingCurve c1; + c1.setPeriod(1); + c1.setType(QEasingCurve::OutSine); + QVERIFY(c1.valueForProgress(0.75) > 0.9); + + QEasingCurve c2; + c2.setType(QEasingCurve::OutSine); + c2.setPeriod(1); + + QCOMPARE(c1.valueForProgress(0.75), c2.valueForProgress(0.75)); +} + void tst_QEasingCurve::bezierSpline_data() { QTest::addColumn<QString>("definition"); diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index a1fc50fb38..39aaee102b 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -57,8 +57,6 @@ private slots: void operator_eq(); // copied from tst_QMap void rehash_isnt_quadratic(); void dont_need_default_constructor(); - void qhash(); - void fp_qhash_of_zero_is_zero(); void qmultihash_specific(); void compare(); @@ -70,9 +68,6 @@ private slots: void const_shared_null(); void twoArguments_qHash(); void initializerList(); - - void qthash_data(); - void qthash(); void eraseValidIteratorOnSharedHash(); }; @@ -1009,83 +1004,6 @@ void tst_QHash::dont_need_default_constructor() } } -void tst_QHash::qhash() -{ - { - QBitArray a1; - QBitArray a2; - QVERIFY(qHash(a1) == 0); - - a1.resize(1); - a1.setBit(0, true); - - a2.resize(1); - a2.setBit(0, false); - - uint h1 = qHash(a1); - uint h2 = qHash(a2); - - QVERIFY(h1 != h2); - - a2.setBit(0, true); - QVERIFY(h1 == qHash(a2)); - - a1.fill(true, 8); - a1.resize(7); - - h1 = qHash(a1); - - a2.fill(true, 7); - h2 = qHash(a2); - - QVERIFY(h1 == h2); - - a2.setBit(0, false); - uint h3 = qHash(a2); - QVERIFY(h2 != h3); - - a2.setBit(0, true); - QVERIFY(h2 == qHash(a2)); - - a2.setBit(6, false); - uint h4 = qHash(a2); - QVERIFY(h2 != h4); - - a2.setBit(6, true); - QVERIFY(h2 == qHash(a2)); - - QVERIFY(h3 != h4); - } - - { - QPair<int, int> p12(1, 2); - QPair<int, int> p21(2, 1); - - QVERIFY(qHash(p12) == qHash(p12)); - QVERIFY(qHash(p21) == qHash(p21)); - QVERIFY(qHash(p12) != qHash(p21)); - - QPair<int, int> pA(0x12345678, 0x12345678); - QPair<int, int> pB(0x12345675, 0x12345675); - - QVERIFY(qHash(pA) != qHash(pB)); - } -} - -void tst_QHash::fp_qhash_of_zero_is_zero() -{ - QCOMPARE(qHash(-0.0f), 0U); - QCOMPARE(qHash( 0.0f), 0U); - - QCOMPARE(qHash(-0.0 ), 0U); - QCOMPARE(qHash( 0.0 ), 0U); - -#ifndef Q_OS_DARWIN - QCOMPARE(qHash(-0.0L), 0U); - QCOMPARE(qHash( 0.0L), 0U); -#endif -} - void tst_QHash::qmultihash_specific() { QMultiHash<int, int> hash1; @@ -1384,25 +1302,6 @@ void tst_QHash::initializerList() #endif } -void tst_QHash::qthash_data() -{ - QTest::addColumn<QString>("key"); - QTest::addColumn<uint>("hash"); - - QTest::newRow("null") << QString() << 0u; - QTest::newRow("empty") << QStringLiteral("") << 0u; - QTest::newRow("abcdef") << QStringLiteral("abcdef") << 108567222u; - QTest::newRow("tqbfjotld") << QStringLiteral("The quick brown fox jumps over the lazy dog") << 140865879u; - QTest::newRow("42") << QStringLiteral("42") << 882u; -} - -void tst_QHash::qthash() -{ - QFETCH(QString, key); - const uint result = qt_hash(key); - QTEST(result, "hash"); -} - void tst_QHash::eraseValidIteratorOnSharedHash() { QHash<int, int> a, b; diff --git a/tests/auto/corelib/tools/qhashfunctions/.gitignore b/tests/auto/corelib/tools/qhashfunctions/.gitignore new file mode 100644 index 0000000000..ca8886e200 --- /dev/null +++ b/tests/auto/corelib/tools/qhashfunctions/.gitignore @@ -0,0 +1 @@ +tst_qhashfunctions diff --git a/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro b/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro new file mode 100644 index 0000000000..21426a4f55 --- /dev/null +++ b/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro @@ -0,0 +1,5 @@ +CONFIG += testcase parallel_test +TARGET = tst_qhashfunctions +QT = core testlib +SOURCES = $$PWD/tst_qhashfunctions.cpp +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp new file mode 100644 index 0000000000..38d39d247c --- /dev/null +++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <qhash.h> +#include <qtypetraits.h> + +#include <iterator> +#include <sstream> +#include <algorithm> + +class tst_QHashFunctions : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void qhash(); + void fp_qhash_of_zero_is_zero(); + void qthash_data(); + void qthash(); + void range(); + void rangeCommutative(); +}; + +void tst_QHashFunctions::qhash() +{ + { + QBitArray a1; + QBitArray a2; + QVERIFY(qHash(a1) == 0); + + a1.resize(1); + a1.setBit(0, true); + + a2.resize(1); + a2.setBit(0, false); + + uint h1 = qHash(a1); + uint h2 = qHash(a2); + + QVERIFY(h1 != h2); + + a2.setBit(0, true); + QVERIFY(h1 == qHash(a2)); + + a1.fill(true, 8); + a1.resize(7); + + h1 = qHash(a1); + + a2.fill(true, 7); + h2 = qHash(a2); + + QVERIFY(h1 == h2); + + a2.setBit(0, false); + uint h3 = qHash(a2); + QVERIFY(h2 != h3); + + a2.setBit(0, true); + QVERIFY(h2 == qHash(a2)); + + a2.setBit(6, false); + uint h4 = qHash(a2); + QVERIFY(h2 != h4); + + a2.setBit(6, true); + QVERIFY(h2 == qHash(a2)); + + QVERIFY(h3 != h4); + } + + { + QPair<int, int> p12(1, 2); + QPair<int, int> p21(2, 1); + + QVERIFY(qHash(p12) == qHash(p12)); + QVERIFY(qHash(p21) == qHash(p21)); + QVERIFY(qHash(p12) != qHash(p21)); + + QPair<int, int> pA(0x12345678, 0x12345678); + QPair<int, int> pB(0x12345675, 0x12345675); + + QVERIFY(qHash(pA) != qHash(pB)); + } +} + +void tst_QHashFunctions::fp_qhash_of_zero_is_zero() +{ + QCOMPARE(qHash(-0.0f), 0U); + QCOMPARE(qHash( 0.0f), 0U); + + QCOMPARE(qHash(-0.0 ), 0U); + QCOMPARE(qHash( 0.0 ), 0U); + +#ifndef Q_OS_DARWIN + QCOMPARE(qHash(-0.0L), 0U); + QCOMPARE(qHash( 0.0L), 0U); +#endif +} + +void tst_QHashFunctions::qthash_data() +{ + QTest::addColumn<QString>("key"); + QTest::addColumn<uint>("hash"); + + QTest::newRow("null") << QString() << 0u; + QTest::newRow("empty") << QStringLiteral("") << 0u; + QTest::newRow("abcdef") << QStringLiteral("abcdef") << 108567222u; + QTest::newRow("tqbfjotld") << QStringLiteral("The quick brown fox jumps over the lazy dog") << 140865879u; + QTest::newRow("42") << QStringLiteral("42") << 882u; +} + +void tst_QHashFunctions::qthash() +{ + QFETCH(QString, key); + const uint result = qt_hash(key); + QTEST(result, "hash"); +} + +namespace SomeNamespace { + struct Hashable { int i; }; + inline uint qHash(Hashable h, uint seed = 0) + { return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); } +} + +void tst_QHashFunctions::range() +{ + static const int ints[] = {0, 1, 2, 3, 4, 5}; + static const size_t numInts = sizeof ints / sizeof *ints; + + // empty range just gives the seed: + QCOMPARE(qHashRange(ints, ints, 0xdeadbeefU), 0xdeadbeefU); + // verify that order matters: + QVERIFY(qHashRange(ints, ints + numInts) != + qHashRange(std::reverse_iterator<const int*>(ints + numInts), std::reverse_iterator<const int*>(ints))); + + { + // verify that the input iterator category suffices: + std::stringstream sstream; + Q_STATIC_ASSERT((QtPrivate::is_same<std::input_iterator_tag, std::istream_iterator<int>::iterator_category>::value)); + std::copy(ints, ints + numInts, std::ostream_iterator<int>(sstream, " ")); + sstream.seekg(0); + std::istream_iterator<int> it(sstream), end; + QCOMPARE(qHashRange(ints, ints + numInts), qHashRange(it, end)); + } + + SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}}; + static const size_t numHashables = sizeof hashables / sizeof *hashables; + // compile check: is qHash() found using ADL? + (void)qHashRange(hashables, hashables + numHashables); +} + +void tst_QHashFunctions::rangeCommutative() +{ + int ints[] = {0, 1, 2, 3, 4, 5}; + static const size_t numInts = sizeof ints / sizeof *ints; + + // empty range just gives the seed: + QCOMPARE(qHashRangeCommutative(ints, ints, 0xdeadbeefU), 0xdeadbeefU); + // verify that order doesn't matter: + QCOMPARE(qHashRangeCommutative(ints, ints + numInts), + qHashRangeCommutative(std::reverse_iterator<int*>(ints + numInts), std::reverse_iterator<int*>(ints))); + + { + // verify that the input iterator category suffices: + std::stringstream sstream; + std::copy(ints, ints + numInts, std::ostream_iterator<int>(sstream, " ")); + sstream.seekg(0); + std::istream_iterator<int> it(sstream), end; + QCOMPARE(qHashRangeCommutative(ints, ints + numInts), qHashRangeCommutative(it, end)); + } + + SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}}; + static const size_t numHashables = sizeof hashables / sizeof *hashables; + // compile check: is qHash() found using ADL? + (void)qHashRangeCommutative(hashables, hashables + numHashables); +} + +QTEST_APPLESS_MAIN(tst_QHashFunctions) +#include "tst_qhashfunctions.moc" diff --git a/tests/auto/corelib/tools/qline/qline.pro b/tests/auto/corelib/tools/qline/qline.pro index acdba32db1..56f852ac52 100644 --- a/tests/auto/corelib/tools/qline/qline.pro +++ b/tests/auto/corelib/tools/qline/qline.pro @@ -2,5 +2,5 @@ CONFIG += testcase parallel_test TARGET = tst_qline QT = core testlib SOURCES = tst_qline.cpp -unix:!mac:!vxworks:LIBS+=-lm +unix:!mac:!vxworks:!haiku:LIBS+=-lm DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index db22f99cb8..1b6fe2aefe 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -237,6 +237,95 @@ void consistencyCheck(const QRegularExpressionMatchIterator &iterator) } +template<typename Result> +static void prepareResultForNoMatchType(Result *r, const Result &orig) +{ + Q_UNUSED(r); + Q_UNUSED(orig); +} + +static void prepareResultForNoMatchType(Match *m, const Match &orig) +{ + m->isValid = orig.isValid; +} + +template<typename QREMatch, typename QREMatchFunc, typename Subject, typename Result> +static void testMatchImpl(const QRegularExpression ®exp, + QREMatchFunc matchingMethod, + const Subject &subject, + int offset, + QRegularExpression::MatchType matchType, + QRegularExpression::MatchOptions matchOptions, + const Result &result) +{ + { + const QREMatch m = (regexp.*matchingMethod)(subject, offset, matchType, matchOptions); + consistencyCheck(m); + QVERIFY(m == result); + QCOMPARE(m.regularExpression(), regexp); + QCOMPARE(m.matchType(), matchType); + QCOMPARE(m.matchOptions(), matchOptions); + } + { + // ignore the expected results provided by the match object -- + // we'll never get any result when testing the NoMatch type. + // Just check the validity of the match here. + Result realMatch; + prepareResultForNoMatchType(&realMatch, result); + + const QREMatch m = (regexp.*matchingMethod)(subject, offset, QRegularExpression::NoMatch, matchOptions); + consistencyCheck(m); + QVERIFY(m == realMatch); + QCOMPARE(m.regularExpression(), regexp); + QCOMPARE(m.matchType(), QRegularExpression::NoMatch); + QCOMPARE(m.matchOptions(), matchOptions); + } +} + +template<typename QREMatch, typename QREMatchFuncForString, typename QREMatchFuncForStringRef, typename Result> +static void testMatch(const QRegularExpression ®exp, + QREMatchFuncForString matchingMethodForString, + QREMatchFuncForStringRef matchingMethodForStringRef, + const QString &subject, + int offset, + QRegularExpression::MatchType matchType, + QRegularExpression::MatchOptions matchOptions, + const Result &result) +{ + if (forceOptimize) + regexp.optimize(); + + // test with QString as subject type + testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result); + + // test with QStringRef as subject type + testMatchImpl<QREMatch>(regexp, + matchingMethodForStringRef, + QStringRef(&subject, 0, subject.length()), + offset, + matchType, + matchOptions, + result); + + // offset <= 0 tested above; now also test stringrefs not spanning over + // the entire subject. Note that the offset can be negative, hence the above + // tests can't be merged into this one + for (int i = 1; i <= offset; ++i) { + testMatchImpl<QREMatch>(regexp, + matchingMethodForStringRef, + QStringRef(&subject, i, subject.length() - i), + offset - i, + matchType, + matchOptions, + result); + } +} + +typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; +typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; +typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; +typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const; + void tst_QRegularExpression::provideRegularExpressions() { QTest::addColumn<QString>("pattern"); @@ -526,6 +615,7 @@ void tst_QRegularExpression::normalMatch_data() QTest::addColumn<Match>("match"); Match m; + int offset = 0; m.clear(); m.isValid = true; m.hasMatch = true; @@ -577,20 +667,28 @@ void tst_QRegularExpression::normalMatch_data() m.clear(); m.isValid = true; m.hasMatch = true; m.captured << "c123def" << "c12" << "3" << "def"; - QTest::newRow("match06") << QRegularExpression("(\\w*)(\\d+)(\\w*)") - << "abc123def" - << 2 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 2; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("match06-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("(\\w*)(\\d+)(\\w*)") + << QStringLiteral("abc123def").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; m.hasMatch = true; m.captured << QString(""); - QTest::newRow("match07") << QRegularExpression("\\w*") - << "abc123def" - << 9 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 9; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("match07-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("\\w*") + << QStringLiteral("abc123def").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; m.hasMatch = true; @@ -648,19 +746,27 @@ void tst_QRegularExpression::normalMatch_data() m.clear(); m.isValid = true; - QTest::newRow("nomatch02") << QRegularExpression("(\\w+) (\\w+)") - << "a string" - << 1 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 1; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("nomatch02-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("(\\w+) (\\w+)") + << QStringLiteral("a string").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; - QTest::newRow("nomatch03") << QRegularExpression("\\w+") - << "abc123def" - << 9 - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 9; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("nomatch03-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("\\w+") + << QStringLiteral("abc123def").mid(offset - i) + << i + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } // *** @@ -728,32 +834,14 @@ void tst_QRegularExpression::normalMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(Match, match); - if (forceOptimize) - regexp.optimize(); - - { - QRegularExpressionMatch m = regexp.match(subject, offset, QRegularExpression::NormalMatch, matchOptions); - consistencyCheck(m); - QVERIFY(m == match); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), QRegularExpression::NormalMatch); - QCOMPARE(m.matchOptions(), matchOptions); - } - { - // ignore the expected results provided by the match object -- - // we'll never get any result when testing the NoMatch type. - // Just check the validity of the match here. - Match realMatch; - realMatch.clear(); - realMatch.isValid = match.isValid; - - QRegularExpressionMatch m = regexp.match(subject, offset, QRegularExpression::NoMatch, matchOptions); - consistencyCheck(m); - QVERIFY(m == realMatch); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), QRegularExpression::NoMatch); - QCOMPARE(m.matchOptions(), matchOptions); - } + testMatch<QRegularExpressionMatch>(regexp, + static_cast<QREMatchStringPMF>(&QRegularExpression::match), + static_cast<QREMatchStringRefPMF>(&QRegularExpression::match), + subject, + offset, + QRegularExpression::NormalMatch, + matchOptions, + match); } void tst_QRegularExpression::partialMatch_data() @@ -766,6 +854,7 @@ void tst_QRegularExpression::partialMatch_data() QTest::addColumn<Match>("match"); Match m; + int offset = 0; m.clear(); m.isValid = true; m.hasPartialMatch = true; @@ -840,12 +929,16 @@ void tst_QRegularExpression::partialMatch_data() m.clear(); m.isValid = true; m.hasPartialMatch = true; m.captured << "def"; - QTest::newRow("softmatch08") << QRegularExpression("abc\\w+X|defY") - << "abcdef" - << 1 - << QRegularExpression::PartialPreferCompleteMatch - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 1; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("softmatch08-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("abc\\w+X|defY") + << QStringLiteral("abcdef").mid(offset - i) + << i + << QRegularExpression::PartialPreferCompleteMatch + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } // *** @@ -922,12 +1015,16 @@ void tst_QRegularExpression::partialMatch_data() m.clear(); m.isValid = true; m.hasPartialMatch = true; m.captured << "def"; - QTest::newRow("hardmatch08") << QRegularExpression("abc\\w+X|defY") - << "abcdef" - << 1 - << QRegularExpression::PartialPreferFirstMatch - << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) - << m; + offset = 1; + for (int i = 0; i <= offset; ++i) { + QTest::newRow(QStringLiteral("hardmatch08-offset%1").arg(i).toUtf8().constData()) + << QRegularExpression("abc\\w+X|defY") + << QStringLiteral("abcdef").mid(offset - i) + << i + << QRegularExpression::PartialPreferFirstMatch + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + } m.clear(); m.isValid = true; m.hasPartialMatch = true; @@ -1009,32 +1106,14 @@ void tst_QRegularExpression::partialMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(Match, match); - if (forceOptimize) - regexp.optimize(); - - { - QRegularExpressionMatch m = regexp.match(subject, offset, matchType, matchOptions); - consistencyCheck(m); - QVERIFY(m == match); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), matchType); - QCOMPARE(m.matchOptions(), matchOptions); - } - { - // ignore the expected results provided by the match object -- - // we'll never get any result when testing the NoMatch type. - // Just check the validity of the match here. - Match realMatch; - realMatch.clear(); - realMatch.isValid = match.isValid; - - QRegularExpressionMatch m = regexp.match(subject, offset, QRegularExpression::NoMatch, matchOptions); - consistencyCheck(m); - QVERIFY(m == realMatch); - QCOMPARE(m.regularExpression(), regexp); - QCOMPARE(m.matchType(), QRegularExpression::NoMatch); - QCOMPARE(m.matchOptions(), matchOptions); - } + testMatch<QRegularExpressionMatch>(regexp, + static_cast<QREMatchStringPMF>(&QRegularExpression::match), + static_cast<QREMatchStringRefPMF>(&QRegularExpression::match), + subject, + offset, + matchType, + matchOptions, + match); } void tst_QRegularExpression::globalMatch_data() @@ -1304,31 +1383,14 @@ void tst_QRegularExpression::globalMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(QList<Match>, matchList); - if (forceOptimize) - regexp.optimize(); - - { - QRegularExpressionMatchIterator iterator = regexp.globalMatch(subject, offset, matchType, matchOptions); - consistencyCheck(iterator); - QVERIFY(iterator == matchList); - QCOMPARE(iterator.regularExpression(), regexp); - QCOMPARE(iterator.matchType(), matchType); - QCOMPARE(iterator.matchOptions(), matchOptions); - } - { - // ignore the expected results provided by the match object -- - // we'll never get any result when testing the NoMatch type. - // Just check the validity of the match here. - QList<Match> realMatchList; - - QRegularExpressionMatchIterator iterator = regexp.globalMatch(subject, offset, QRegularExpression::NoMatch, matchOptions); - consistencyCheck(iterator); - QVERIFY(iterator == realMatchList); - QCOMPARE(iterator.regularExpression(), regexp); - QCOMPARE(iterator.matchType(), QRegularExpression::NoMatch); - QCOMPARE(iterator.matchOptions(), matchOptions); - } - + testMatch<QRegularExpressionMatchIterator>(regexp, + static_cast<QREGlobalMatchStringPMF>(&QRegularExpression::globalMatch), + static_cast<QREGlobalMatchStringRefPMF>(&QRegularExpression::globalMatch), + subject, + offset, + matchType, + matchOptions, + matchList); } void tst_QRegularExpression::serialize_data() diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index d892125c87..33f1b25519 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -294,16 +294,16 @@ void tst_QRingBuffer::readLine() char stringBuf[102]; stringBuf[101] = 0; // non-crash terminator QVERIFY(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2) == ba1.size()); - QVERIFY(QByteArray(stringBuf, strlen(stringBuf)) == ba1); + QVERIFY(QByteArray(stringBuf, int(strlen(stringBuf))) == ba1); // check first empty string reading - stringBuf[0] = 0xFF; - QCOMPARE(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2), ba2.size()); + stringBuf[0] = char(0xFF); + QCOMPARE(ringBuffer.readLine(stringBuf, int(sizeof(stringBuf)) - 2), ba2.size()); QVERIFY(stringBuf[0] == ba2[0]); - QVERIFY(ringBuffer.readLine(stringBuf, sizeof(stringBuf) - 2) == (ba3.size() + ba4.size() + QVERIFY(ringBuffer.readLine(stringBuf, int(sizeof(stringBuf)) - 2) == (ba3.size() + ba4.size() + ba2.size())); - QVERIFY(QByteArray(stringBuf, strlen(stringBuf)) == (ba3 + ba4 + ba2)); + QVERIFY(QByteArray(stringBuf, int(strlen(stringBuf))) == (ba3 + ba4 + ba2)); QVERIFY(ringBuffer.size() == 0); } diff --git a/tests/auto/corelib/tools/qset/tst_qset.cpp b/tests/auto/corelib/tools/qset/tst_qset.cpp index f04eefad51..30f7e3741d 100644 --- a/tests/auto/corelib/tools/qset/tst_qset.cpp +++ b/tests/auto/corelib/tools/qset/tst_qset.cpp @@ -72,6 +72,7 @@ private slots: void javaMutableIterator(); void makeSureTheComfortFunctionsCompile(); void initializerList(); + void qhash(); }; struct IdentityTracker { @@ -137,6 +138,16 @@ void tst_QSet::operator_eq() QVERIFY(a != b); QVERIFY(!(a == b)); } + + { + QSet<int> s1, s2; + s1.reserve(100); + s2.reserve(4); + QVERIFY(s1 == s2); + s1 << 100 << 200 << 300 << 400; + s2 << 400 << 300 << 200 << 100; + QVERIFY(s1 == s2); + } } void tst_QSet::swap() @@ -958,6 +969,67 @@ void tst_QSet::initializerList() #endif } +QT_BEGIN_NAMESPACE +extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; // from qhash.cpp +QT_END_NAMESPACE + +class QtQHashSeedSaver { + int oldSeed, newSeed; +public: + explicit QtQHashSeedSaver(int seed) + : oldSeed(qt_qhash_seed.fetchAndStoreRelaxed(seed)), + newSeed(seed) + {} + ~QtQHashSeedSaver() + { + // only restore when no-one else changed the seed in the meantime: + qt_qhash_seed.testAndSetRelaxed(newSeed, oldSeed); + } +}; + +void tst_QSet::qhash() +{ + // + // check that sets containing the same elements hash to the same value + // + { + // create some deterministic initial state: + const QtQHashSeedSaver seed1(0); + + QSet<int> s1; + s1.reserve(4); + s1 << 400 << 300 << 200 << 100; + + // also change the seed: + const QtQHashSeedSaver seed2(0x10101010); + + QSet<int> s2; + s2.reserve(100); // provoke different bucket counts + s2 << 100 << 200 << 300 << 400; // and insert elements in different order, too + + QVERIFY(s1.capacity() != s2.capacity()); + QCOMPARE(s1, s2); + QVERIFY(!std::equal(s1.cbegin(), s1.cend(), s2.cbegin())); // verify that the order _is_ different + QCOMPARE(qHash(s1), qHash(s2)); + } + + // + // check that sets of sets work: + // + { +#ifdef Q_COMPILER_INITIALIZER_LISTS + QSet<QSet<int> > intSetSet = { { 0, 1, 2 }, { 0, 1 }, { 1, 2 } }; +#else + QSet<QSet<int> > intSetSet; + QSet<int> intSet01, intSet12; + intSet01 << 0 << 1; + intSet12 << 1 << 2; + intSetSet << intSet01 << intSet12 << (intSet01|intSet12); +#endif + QCOMPARE(intSetSet.size(), 3); + } +} + QTEST_APPLESS_MAIN(tst_QSet) #include "tst_qset.moc" diff --git a/tests/auto/corelib/tools/qstring/qstring.pro b/tests/auto/corelib/tools/qstring/qstring.pro index 971e2fb782..1eda27e1ff 100644 --- a/tests/auto/corelib/tools/qstring/qstring.pro +++ b/tests/auto/corelib/tools/qstring/qstring.pro @@ -4,6 +4,7 @@ QT = core testlib SOURCES = tst_qstring.cpp DEFINES += QT_NO_CAST_TO_ASCII contains(QT_CONFIG,icu):DEFINES += QT_USE_ICU +contains(QT_CONFIG,c++11): CONFIG += c++11 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 mac { diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index ea40c64c89..356724916b 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -59,6 +59,7 @@ #include <locale.h> #include <qhash.h> +#include <string> #define CREATE_REF(string) \ const QString padded = QString::fromLatin1(" %1 ").arg(string); \ @@ -155,6 +156,7 @@ private slots: void lastIndexOfInvalidRegex(); void indexOf_data(); void indexOf(); + void indexOfInvalidRegex(); void indexOf2_data(); void indexOf2(); void indexOf3_data(); @@ -262,6 +264,7 @@ private slots: void assignQLatin1String(); void isRightToLeft_data(); void isRightToLeft(); + void unicodeStrings(); }; template <class T> const T &verifyZeroTermination(const T &t) { return t; } @@ -325,75 +328,6 @@ QString verifyZeroTermination(const QString &str) typedef QList<int> IntList; -// This next bit is needed for the NAN and INF in string -> number conversion tests -#include <float.h> -#include <limits.h> -#include <math.h> -#if defined (Q_OS_WIN) -# include <windows.h> -// mingw defines NAN and INFINITY to 0/0 and x/0 -# if defined(Q_CC_GNU) -# undef NAN -# undef INFINITY -# else -# define isnan(d) _isnan(d) -# endif -#endif -#if defined (Q_OS_MAC) && !defined isnan -#define isnan(d) __isnand(d) -#endif -#if defined (Q_OS_SOLARIS) -# include <ieeefp.h> -#endif -#if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) -# define INFINITY DBL_INFINITY -# define NAN DBL_QNAN -#endif -#if defined(Q_OS_IRIX) && defined(Q_CC_GNU) -# include <ieeefp.h> -# define isnan(d) isnand(d) -#endif - -enum { - LittleEndian, - BigEndian -#ifdef Q_BYTE_ORDER -# if Q_BYTE_ORDER == Q_BIG_ENDIAN - , ByteOrder = BigEndian -# elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN - , ByteOrder = LittleEndian -# else -# error "undefined byte order" -# endif -}; -#else -}; -static const unsigned int one = 1; -static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); -#endif -#if !defined(INFINITY) -static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0,0 }; -static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; -static inline double inf() -{ - if (ByteOrder == BigEndian) - return *reinterpret_cast<const double *>(be_inf_bytes); - return *reinterpret_cast<const double *>(le_inf_bytes); -} -# define INFINITY (::inf()) -#endif -#if !defined(NAN) -static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0,0 }; -static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; -static inline double nan() -{ - if (ByteOrder == BigEndian) - return *reinterpret_cast<const double *>(be_nan_bytes); - return *reinterpret_cast<const double *>(le_nan_bytes); -} -# define NAN (::nan()) -#endif - tst_QString::tst_QString() { QTextCodec::setCodecForLocale(QTextCodec::codecForName("ISO 8859-1")); @@ -812,10 +746,8 @@ void tst_QString::acc_01() } } -#ifdef Q_CC_GNU -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-security" -#endif +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wformat-security") void tst_QString::isNull() { @@ -827,9 +759,7 @@ void tst_QString::isNull() QVERIFY(!a.isNull()); } -#ifdef Q_CC_GNU -# pragma GCC diagnostic pop -#endif +QT_WARNING_POP void tst_QString::isEmpty() { @@ -1182,6 +1112,18 @@ void tst_QString::indexOf() QRegularExpression re(QRegularExpression::escape(needle), options); QCOMPARE( haystack.indexOf(re, startpos), resultpos ); + QCOMPARE(haystack.indexOf(re, startpos, Q_NULLPTR), resultpos); + + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QCOMPARE(haystack.indexOf(re, startpos, &match), resultpos); + QCOMPARE(match.hasMatch(), resultpos != -1); + if (resultpos > -1 && needleIsLatin) { + if (bcs) + QVERIFY(match.captured() == needle); + else + QVERIFY(match.captured().toLower() == needle.toLower()); + } } if (cs == Qt::CaseSensitive) { @@ -1290,6 +1232,20 @@ void tst_QString::indexOf2() } } +void tst_QString::indexOfInvalidRegex() +{ + QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\")), -1); + QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, Q_NULLPTR), -1); + + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, &match), -1); + QVERIFY(!match.hasMatch()); +} + void tst_QString::lastIndexOf_data() { QTest::addColumn<QString>("haystack" ); @@ -1379,6 +1335,17 @@ void tst_QString::lastIndexOf() QRegularExpression re(QRegularExpression::escape(needle), options); QCOMPARE(haystack.lastIndexOf(re, from), expected); + QCOMPARE(haystack.lastIndexOf(re, from, Q_NULLPTR), expected); + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QCOMPARE(haystack.lastIndexOf(re, from, &match), expected); + QCOMPARE(match.hasMatch(), expected > -1); + if (expected > -1) { + if (caseSensitive) + QCOMPARE(match.captured(), needle); + else + QCOMPARE(match.captured().toLower(), needle.toLower()); + } } } @@ -1403,7 +1370,15 @@ void tst_QString::lastIndexOf() void tst_QString::lastIndexOfInvalidRegex() { QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object"); - QCOMPARE(QString("").lastIndexOf(QRegularExpression("invalid regex\\"), 0), -1); + QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), 0), -1); + QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, Q_NULLPTR), -1); + + QRegularExpressionMatch match; + QVERIFY(!match.hasMatch()); + QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object"); + QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, &match), -1); + QVERIFY(!match.hasMatch()); } void tst_QString::count() @@ -1838,6 +1813,7 @@ void tst_QString::toUpper() { QCOMPARE( QString().toUpper(), QString() ); QCOMPARE( QString("").toUpper(), QString("") ); + QCOMPARE( QStringLiteral("text").toUpper(), QString("TEXT") ); QCOMPARE( QString("text").toUpper(), QString("TEXT") ); QCOMPARE( QString("Text").toUpper(), QString("TEXT") ); QCOMPARE( QString("tExt").toUpper(), QString("TEXT") ); @@ -1898,6 +1874,7 @@ void tst_QString::toLower() QCOMPARE( QString().toLower(), QString() ); QCOMPARE( QString("").toLower(), QString("") ); QCOMPARE( QString("text").toLower(), QString("text") ); + QCOMPARE( QStringLiteral("Text").toLower(), QString("text") ); QCOMPARE( QString("Text").toLower(), QString("text") ); QCOMPARE( QString("tExt").toLower(), QString("text") ); QCOMPARE( QString("teXt").toLower(), QString("text") ); @@ -2019,6 +1996,13 @@ void tst_QString::trimmed() QCOMPARE(a,(QString)" "); a=" a "; QCOMPARE(a.trimmed(),(QString)"a"); + + a="Text"; + QCOMPARE(qMove(a).trimmed(),(QString)"Text"); + a=" "; + QCOMPARE(qMove(a).trimmed(),(QString)""); + a=" a "; + QCOMPARE(qMove(a).trimmed(),(QString)"a"); } void tst_QString::simplified_data() @@ -2063,9 +2047,12 @@ void tst_QString::simplified() QVERIFY2(result.isEmpty() && !result.isNull(), qPrintable("'" + full + "' did not yield empty: " + result)); } else { QCOMPARE(result, simple); - if (full == simple) - QVERIFY(result.isSharedWith(full)); } + + // force a detach + if (!full.isEmpty()) + full[0] = full[0]; + QCOMPARE(qMove(full).simplified(), simple); } void tst_QString::insert() @@ -4454,6 +4441,8 @@ void tst_QString::section() QCOMPARE( wholeString.section( QRegExp(sep), start, end, QString::SectionFlag(flags) ), sectionString ); QCOMPARE( wholeString.section( QRegularExpression(sep), start, end, QString::SectionFlag(flags) ), sectionString ); } else { + if (sep.size() == 1) + QCOMPARE( wholeString.section( sep[0], start, end, QString::SectionFlag(flags) ), sectionString ); QCOMPARE( wholeString.section( sep, start, end, QString::SectionFlag(flags) ), sectionString ); QCOMPARE( wholeString.section( QRegExp(QRegExp::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString ); QCOMPARE( wholeString.section( QRegularExpression(QRegularExpression::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString ); @@ -5235,6 +5224,27 @@ void tst_QString::fromUtf16_char16() #endif } +void tst_QString::unicodeStrings() +{ +#ifdef Q_COMPILER_UNICODE_STRINGS + QString s1, s2; + static const std::u16string u16str1(u"Hello Unicode World"); + static const std::u32string u32str1(U"Hello Unicode World"); + s1 = QString::fromStdU16String(u16str1); + s2 = QString::fromStdU32String(u32str1); + QCOMPARE(s1, QString("Hello Unicode World")); + QCOMPARE(s1, s2); + + QCOMPARE(s2.toStdU16String(), u16str1); + QCOMPARE(s1.toStdU32String(), u32str1); + + s1 = QString::fromStdU32String(std::u32string(U"\u221212\U000020AC\U00010000")); + QCOMPARE(s1, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200")); +#else + QSKIP("Compiler does not support C++11 unicode strings"); +#endif +} + void tst_QString::latin1String() { QString s("Hello"); @@ -5257,7 +5267,7 @@ void tst_QString::nanAndInf() #define CHECK_DOUBLE(str, expected_ok, expected_inf) \ d = QString(str).toDouble(&ok); \ QVERIFY(ok == expected_ok); \ - QVERIFY((d == INFINITY) == expected_inf); + QVERIFY(qIsInf(d) == expected_inf); CHECK_DOUBLE("inf", true, true) CHECK_DOUBLE("INF", true, true) @@ -5285,17 +5295,15 @@ void tst_QString::nanAndInf() #define CHECK_NAN(str, expected_ok, expected_nan) \ d = QString(str).toDouble(&ok); \ QVERIFY(ok == expected_ok); \ - QVERIFY((bool)isnan(d) == expected_nan); \ + QVERIFY(qIsNaN(d) == expected_nan); CHECK_NAN("nan", true, true) CHECK_NAN("NAN", true, true) CHECK_NAN("nan ", true, true) CHECK_NAN("\t NAN", true, true) CHECK_NAN("\t NAN ", true, true) -#ifndef QT_QLOCALE_USES_FCVT //In case we use glibc this tests will fail CHECK_NAN("-nan", false, false) CHECK_NAN("+NAN", false, false) -#endif CHECK_NAN("NaN", true, true) CHECK_NAN("nAn", true, true) CHECK_NAN("NANe-10", false, false) @@ -5305,7 +5313,7 @@ void tst_QString::nanAndInf() d = QString("-INF").toDouble(&ok); QVERIFY(ok); - QVERIFY(d == -INFINITY); + QVERIFY(d == -qInf()); QString("INF").toLong(&ok); QVERIFY(!ok); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 9a79d48472..c9e8a5f657 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -575,6 +575,18 @@ void tst_QVector::append() const QCOMPARE(v.last(), SimpleValue<T>::at(0)); } #endif + { + QVector<int> v; + v << 1 << 2 << 3; + QVector<int> x; + x << 4 << 5 << 6; + v.append(x); + + QVector<int> combined; + combined << 1 << 2 << 3 << 4 << 5 << 6; + + QCOMPARE(v, combined); + } } void tst_QVector::appendInt() const diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index ce37ccb18b..9024a1a1bb 100644 --- a/tests/auto/corelib/tools/tools.pro +++ b/tests/auto/corelib/tools/tools.pro @@ -23,6 +23,7 @@ SUBDIRS=\ qfreelist \ qhash \ qhash_strictiterators \ + qhashfunctions \ qline \ qlinkedlist \ qlist \ diff --git a/tests/auto/dbus/qdbusinterface/myobject.h b/tests/auto/dbus/qdbusinterface/myobject.h index 9b337b2a28..cb350d043c 100644 --- a/tests/auto/dbus/qdbusinterface/myobject.h +++ b/tests/auto/dbus/qdbusinterface/myobject.h @@ -38,7 +38,7 @@ #include <QtDBus/QtDBus> -class MyObject: public QObject +class MyObject: public QObject, protected QDBusContext { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.MyObject") @@ -123,15 +123,12 @@ public: Q_INVOKABLE void ping_invokable(QDBusMessage msg) { - QDBusConnection sender = QDBusConnection::sender(); - if (!sender.isConnected()) - exit(1); - + Q_ASSERT(QDBusContext::calledFromDBus()); ++callCount; callArgs = msg.arguments(); msg.setDelayedReply(true); - if (!sender.send(msg.createReply(callArgs))) + if (!QDBusContext::connection().send(msg.createReply(callArgs))) exit(1); } @@ -139,15 +136,12 @@ public slots: void ping(QDBusMessage msg) { - QDBusConnection sender = QDBusConnection::sender(); - if (!sender.isConnected()) - exit(1); - + Q_ASSERT(QDBusContext::calledFromDBus()); ++callCount; callArgs = msg.arguments(); msg.setDelayedReply(true); - if (!sender.send(msg.createReply(callArgs))) + if (!QDBusContext::connection().send(msg.createReply(callArgs))) exit(1); } }; diff --git a/tests/auto/dbus/qdbusmetatype/tst_qdbusmetatype.cpp b/tests/auto/dbus/qdbusmetatype/tst_qdbusmetatype.cpp index fc20b47768..f80a969384 100644 --- a/tests/auto/dbus/qdbusmetatype/tst_qdbusmetatype.cpp +++ b/tests/auto/dbus/qdbusmetatype/tst_qdbusmetatype.cpp @@ -69,6 +69,19 @@ struct Struct4 // (ssa(ss)sayasx) QStringList m6; qlonglong m7; }; +struct Struct5 // a{sa{sv}} - non-standard outer struct is used as a local +{ // container, see marshalling operator below. + QVariantMap m1; + QVariantMap m2; + QVariantMap m3; +}; +struct Struct6 // av - non-standard outer struct is used as a local container, +{ // see marshalling operator below. + QVariant v1; + QVariant v2; + QVariant v3; +}; + struct Invalid0 { }; // empty struct Invalid1 { }; // s @@ -84,6 +97,8 @@ Q_DECLARE_METATYPE(Struct2) Q_DECLARE_METATYPE(Struct3) Q_DECLARE_METATYPE(Struct4) Q_DECLARE_METATYPE(StringPair) +Q_DECLARE_METATYPE(Struct5) +Q_DECLARE_METATYPE(Struct6) Q_DECLARE_METATYPE(Invalid0) Q_DECLARE_METATYPE(Invalid1) @@ -141,6 +156,34 @@ QDBusArgument &operator<<(QDBusArgument &arg, const Struct4 &s) return arg; } +QDBusArgument &operator<<(QDBusArgument &arg, const Struct5 &s) +{ + arg.beginMap(qMetaTypeId<QString>(), qMetaTypeId<QVariantMap>()); + + arg.beginMapEntry(); + arg << QStringLiteral("map1") << s.m1; + arg.endMapEntry(); + + arg.beginMapEntry(); + arg << QStringLiteral("map2") << s.m2; + arg.endMapEntry(); + + arg.beginMapEntry(); + arg << QStringLiteral("map3") << s.m3; + arg.endMapEntry(); + + arg.endMap(); + return arg; +} + +QDBusArgument &operator<<(QDBusArgument &arg, const Struct6 &s) +{ + arg.beginArray(qMetaTypeId<QDBusVariant>()); + arg << QDBusVariant(s.v1) << QDBusVariant(s.v2) << QDBusVariant(s.v3); + arg.endArray(); + return arg; +} + QDBusArgument &operator<<(QDBusArgument &arg, const Invalid0 &) { return arg; @@ -194,6 +237,10 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, Struct3 &) { return arg; } const QDBusArgument &operator>>(const QDBusArgument &arg, Struct4 &) { return arg; } +const QDBusArgument &operator>>(const QDBusArgument &arg, Struct5 &) +{ return arg; } +const QDBusArgument &operator>>(const QDBusArgument &arg, Struct6 &) +{ return arg; } const QDBusArgument &operator>>(const QDBusArgument &arg, StringPair &) { return arg; } const QDBusArgument &operator>>(const QDBusArgument &arg, Invalid0 &) @@ -220,6 +267,8 @@ void tst_QDBusMetaType::initTestCase() qDBusRegisterMetaType<Struct2>(); qDBusRegisterMetaType<Struct3>(); qDBusRegisterMetaType<Struct4>(); + qDBusRegisterMetaType<Struct5>(); + qDBusRegisterMetaType<Struct6>(); qDBusRegisterMetaType<StringPair>(); qDBusRegisterMetaType<QList<Struct1> >(); @@ -297,6 +346,10 @@ void tst_QDBusMetaType::dynamicTypes_data() QTest::newRow("Struct4") << QVariant::Type(qMetaTypeId<Struct4>()) << "(ssa(ss)sayasx)"; QTest::newRow("QList<Struct4>") << QVariant::Type(qMetaTypeId<QList<Struct4> >()) << "a(ssa(ss)sayasx)"; + QTest::newRow("Struct5") << QVariant::Type(qMetaTypeId<Struct5>()) << "a{sa{sv}}"; + + QTest::newRow("Struct6") << QVariant::Type(qMetaTypeId<Struct6>()) << "av"; + QTest::newRow("QMap<int,QString>") << QVariant::Type(intStringMap) << "a{is}"; QTest::newRow("QMap<QString,QString>") << QVariant::Type(stringStringMap) << "a{ss}"; QTest::newRow("QMap<QString,Struct1>") << QVariant::Type(stringStruct1Map) << "a{s(s)}"; diff --git a/tests/auto/gui/image/qicon/qicon.pro b/tests/auto/gui/image/qicon/qicon.pro index f48fe90dd8..6ff20ec8fa 100644 --- a/tests/auto/gui/image/qicon/qicon.pro +++ b/tests/auto/gui/image/qicon/qicon.pro @@ -7,4 +7,4 @@ qtHaveModule(widgets): QT += widgets SOURCES += tst_qicon.cpp RESOURCES = tst_qicon.qrc -TESTDATA += icons/* *.png *.svg *.svgz +TESTDATA += icons/* second_icons/* *.png *.svg *.svgz diff --git a/tests/auto/gui/image/qicon/icons/testtheme/32x32/actions/appointment-new.png b/tests/auto/gui/image/qicon/second_icons/testtheme/32x32/actions/appointment-new.png Binary files differindex 85daef3b0b..85daef3b0b 100644 --- a/tests/auto/gui/image/qicon/icons/testtheme/32x32/actions/appointment-new.png +++ b/tests/auto/gui/image/qicon/second_icons/testtheme/32x32/actions/appointment-new.png diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp index 550dd5bc33..add6da9efb 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.cpp +++ b/tests/auto/gui/image/qicon/tst_qicon.cpp @@ -559,10 +559,12 @@ void tst_QIcon::task184901_badCache() void tst_QIcon::fromTheme() { - QString searchPath = QLatin1String(":/icons"); - QIcon::setThemeSearchPaths(QStringList() << searchPath); - QVERIFY(QIcon::themeSearchPaths().size() == 1); - QCOMPARE(searchPath, QIcon::themeSearchPaths()[0]); + QString firstSearchPath = QLatin1String(":/icons"); + QString secondSearchPath = QLatin1String(":/second_icons"); + QIcon::setThemeSearchPaths(QStringList() << firstSearchPath << secondSearchPath); + QVERIFY(QIcon::themeSearchPaths().size() == 2); + QCOMPARE(firstSearchPath, QIcon::themeSearchPaths()[0]); + QCOMPARE(secondSearchPath, QIcon::themeSearchPaths()[1]); QString themeName("testtheme"); QIcon::setThemeName(themeName); @@ -576,6 +578,14 @@ void tst_QIcon::fromTheme() QVERIFY(appointmentIcon.availableSizes().contains(QSize(32, 32))); QVERIFY(appointmentIcon.availableSizes().contains(QSize(22, 22))); + // Test fallback to less specific icon + QIcon specificAppointmentIcon = QIcon::fromTheme("appointment-new-specific"); + QVERIFY(!QIcon::hasThemeIcon("appointment-new-specific")); + QVERIFY(QIcon::hasThemeIcon("appointment-new")); + QCOMPARE(specificAppointmentIcon.name(), QString::fromLatin1("appointment-new")); + QCOMPARE(specificAppointmentIcon.availableSizes(), appointmentIcon.availableSizes()); + QCOMPARE(specificAppointmentIcon.pixmap(32).cacheKey(), appointmentIcon.pixmap(32).cacheKey()); + // Test icon from parent theme QIcon abIcon = QIcon::fromTheme("address-book-new"); QVERIFY(!abIcon.isNull()); diff --git a/tests/auto/gui/image/qicon/tst_qicon.qrc b/tests/auto/gui/image/qicon/tst_qicon.qrc index dc11a87ddd..1505ca925b 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.qrc +++ b/tests/auto/gui/image/qicon/tst_qicon.qrc @@ -5,7 +5,7 @@ <file>rect.png</file> <file>./icons/testtheme/16x16/actions/appointment-new.png</file> <file>./icons/testtheme/22x22/actions/appointment-new.png</file> -<file>./icons/testtheme/32x32/actions/appointment-new.png</file> +<file>./second_icons/testtheme/32x32/actions/appointment-new.png</file> <file>./icons/testtheme/index.theme</file> <file>./icons/testtheme/scalable/actions/svg-only.svg</file> <file>./icons/themeparent/16x16/actions/address-book-new.png</file> diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index ed1d915670..9feec3f6c7 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -776,6 +776,13 @@ void tst_QImage::convertToFormat_data() << int(QImage::Format_ARGB32) << 0xff00ff00; QTest::newRow("blue rgb30 -> argb32") << int(QImage::Format_RGB30) << 0xff0000ff << int(QImage::Format_ARGB32) << 0xff0000ff; + + QTest::newRow("white gray8 -> argb pm") << int(QImage::Format_Grayscale8) << 0xfffffeffu + << int(QImage::Format_ARGB32_Premultiplied) << 0xfffefefeu; + QTest::newRow("gray gray8 -> argb pm") << int(QImage::Format_Grayscale8) << 0xff565557u + << int(QImage::Format_ARGB32_Premultiplied) << 0xff555555u; + QTest::newRow("black gray8 -> argb pm") << int(QImage::Format_Grayscale8) << 0xff000100u + << int(QImage::Format_ARGB32_Premultiplied) << 0xff000000u; } @@ -1005,6 +1012,10 @@ void tst_QImage::rotate_data() << QImage::Format_RGBX8888 << d; QTest::newRow(qPrintable(title.arg("Format_RGBA8888_Premultiplied"))) << QImage::Format_RGBA8888_Premultiplied << d; + QTest::newRow(qPrintable(title.arg("Format_Alpha8"))) + << QImage::Format_Alpha8 << d; + QTest::newRow(qPrintable(title.arg("Format_Grayscale8"))) + << QImage::Format_Grayscale8 << d; } } @@ -2093,16 +2104,20 @@ void tst_QImage::fillPixel_data() QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << 0x0u << 0x00000000u; QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << 0x0u << 0x00000000u; QTest::newRow("RGBA8888pm, transparent") << QImage::Format_RGBA8888_Premultiplied << 0x0u << 0x00000000u; + QTest::newRow("Alpha8, transparent") << QImage::Format_Alpha8 << 0x0u << 0x00000000u; QTest::newRow("RGB16, red") << QImage::Format_RGB16 << (uint)qConvertRgb32To16(0xffff0000) << 0xffff0000u; QTest::newRow("RGB32, red") << QImage::Format_RGB32 << 0xffff0000u << 0xffff0000u; QTest::newRow("ARGB32, red") << QImage::Format_ARGB32 << 0xffff0000u << 0xffff0000u; QTest::newRow("RGBA8888, red") << QImage::Format_RGBA8888 << 0xff0000ffu << 0xffff0000u; + QTest::newRow("Grayscale8, grey") << QImage::Format_Grayscale8 << 0xff808080u << 0xff808080u; + QTest::newRow("RGB32, semi-red") << QImage::Format_RGB32 << 0x80ff0000u << 0xffff0000u; QTest::newRow("ARGB32, semi-red") << QImage::Format_ARGB32 << 0x80ff0000u << 0x80ff0000u; QTest::newRow("ARGB32pm, semi-red") << QImage::Format_ARGB32 << 0x80800000u << 0x80800000u; QTest::newRow("RGBA8888pm, semi-red") << QImage::Format_RGBA8888_Premultiplied << 0x80000080u << 0x80800000u; + QTest::newRow("Alpha8, semi-red") << QImage::Format_Alpha8 << 0x80000080u << 0x80000000u; } void tst_QImage::fillPixel() diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index f1c1012371..f6b8fbcab9 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -487,13 +487,13 @@ void tst_QImageReader::imageFormat_data() QTest::addColumn<QImage::Format>("imageFormat"); QTest::newRow("pbm") << QString("image.pbm") << QByteArray("pbm") << QImage::Format_Mono; - QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm") << QImage::Format_Indexed8; + QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm") << QImage::Format_Grayscale8; QTest::newRow("ppm-1") << QString("image.ppm") << QByteArray("ppm") << QImage::Format_RGB32; QTest::newRow("ppm-2") << QString("teapot.ppm") << QByteArray("ppm") << QImage::Format_RGB32; QTest::newRow("ppm-3") << QString("runners.ppm") << QByteArray("ppm") << QImage::Format_RGB32; QTest::newRow("ppm-4") << QString("test.ppm") << QByteArray("ppm") << QImage::Format_RGB32; - QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg") << QImage::Format_Indexed8; + QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg") << QImage::Format_Grayscale8; QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg") << QImage::Format_RGB32; QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg") << QImage::Format_RGB32; diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 6a7bbc3119..a327932a3c 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -281,7 +281,7 @@ void tst_QPixmap::fromImage() image.fill(0x7f7f7f7f); const QPixmap pixmap = QPixmap::fromImage(image); -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 if (pixmap.handle()->classId() == QPlatformPixmap::X11Class && !pixmap.x11PictureHandle()) QSKIP("Requires XRender support"); #endif @@ -510,7 +510,7 @@ void tst_QPixmap::fill() else pm = QPixmap(400, 400); -#if defined(Q_WS_X11) +#if defined(Q_DEAD_CODE_FROM_QT4_X11) if (!bitmap && pm.handle()->classId() == QPlatformPixmap::X11Class && !pm.x11PictureHandle()) QSKIP("Requires XRender support"); #endif @@ -540,7 +540,7 @@ void tst_QPixmap::fill() void tst_QPixmap::fill_transparent() { QPixmap pixmap(10, 10); -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 if (pixmap.handle()->classId() == QPlatformPixmap::X11Class && !pixmap.x11PictureHandle()) QSKIP("Requires XRender support"); #endif diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 310fd58b7f..b14d2cf288 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -812,6 +812,33 @@ void tst_QGuiApplication::quitOnLastWindowClosed() QCOMPARE(spy.count(), 1); QVERIFY(spy2.count() > 15); // Should be around 20 if closing did not cause the quit } + { + int argc = 0; + QGuiApplication app(argc, 0); + app.setQuitOnLastWindowClosed(false); + + QTimer timer; + timer.setInterval(2000); + timer.setSingleShot(true); + QObject::connect(&timer, SIGNAL(timeout()), &app, SLOT(quit())); + + QSignalSpy spy(&app, SIGNAL(lastWindowClosed())); + QSignalSpy spy2(&timer, SIGNAL(timeout())); + + QPointer<QWindow> mainWindow = new QWindow; + + mainWindow->show(); + + QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should not quit the application + timer.start(); + + app.exec(); + + QCOMPARE(spy2.count(), 1); // quit timer fired + QCOMPARE(spy.count(), 1); // lastWindowClosed emitted + + app.setQuitOnLastWindowClosed(true); // restore underlying static to default value + } } static Qt::ScreenOrientation testOrientationToSend = Qt::PrimaryOrientation; diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 61ba99c7de..41a53ddd55 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -63,6 +63,7 @@ private slots: void positioning_data(); void positioning(); void positioningDuringMinimized(); + void platformSurface(); void isExposed(); void isActive(); void testInputEvents(); @@ -161,10 +162,21 @@ public: { m_received[event->type()]++; m_order << event->type(); - if (event->type() == QEvent::Expose) + switch (event->type()) { + case QEvent::Expose: m_exposeRegion = static_cast<QExposeEvent *>(event)->region(); - else if (event->type() == QEvent::Move) + break; + + case QEvent::PlatformSurface: + m_surfaceventType = static_cast<QPlatformSurfaceEvent *>(event)->surfaceEventType(); + break; + + case QEvent::Move: m_framePositionsOnMove << framePosition(); + break; + default: + break; + } return QWindow::event(event); } @@ -184,11 +196,17 @@ public: return m_exposeRegion; } + QPlatformSurfaceEvent::SurfaceEventType surfaceEventType() const + { + return m_surfaceventType; + } + QVector<QPoint> m_framePositionsOnMove; private: QHash<QEvent::Type, int> m_received; QVector<QEvent::Type> m_order; QRegion m_exposeRegion; + QPlatformSurfaceEvent::SurfaceEventType m_surfaceventType; }; void tst_QWindow::eventOrderOnShow() @@ -355,6 +373,63 @@ void tst_QWindow::positioningDuringMinimized() QTRY_COMPARE(window.geometry(), newGeometry); } +class PlatformWindowFilter : public QObject +{ + Q_OBJECT +public: + PlatformWindowFilter(QObject *parent = 0) + : QObject(parent) + , m_window(Q_NULLPTR) + , m_alwaysExisted(true) + {} + + void setWindow(Window *window) { m_window = window; } + + bool eventFilter(QObject *o, QEvent *e) + { + // Check that the platform surface events are delivered synchronously. + // If they are, the native platform surface should always exist when we + // receive a QPlatformSurfaceEvent + if (e->type() == QEvent::PlatformSurface && o == m_window) { + m_alwaysExisted &= (m_window->handle() != Q_NULLPTR); + } + return false; + } + + bool surfaceExisted() const { return m_alwaysExisted; } + +private: + Window *m_window; + bool m_alwaysExisted; +}; + +void tst_QWindow::platformSurface() +{ + QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); + + Window window; + PlatformWindowFilter filter; + filter.setWindow(&window); + window.installEventFilter(&filter); + + window.setGeometry(geometry); + QCOMPARE(window.geometry(), geometry); + window.create(); + + QTRY_VERIFY(window.received(QEvent::PlatformSurface) == 1); + QTRY_VERIFY(window.surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated); + QTRY_VERIFY(window.handle() != Q_NULLPTR); + + window.destroy(); + QTRY_VERIFY(window.received(QEvent::PlatformSurface) == 2); + QTRY_VERIFY(window.surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed); + QTRY_VERIFY(window.handle() == Q_NULLPTR); + + // Check for synchronous delivery of platform surface events and that the platform + // surface always existed upon event delivery + QTRY_VERIFY(filter.surfaceExisted()); +} + void tst_QWindow::isExposed() { QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index cdbc242640..c4cad91006 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -54,6 +54,9 @@ private slots: void normalize_data(); void normalize(); + void inverted_data(); + void inverted(); + void compare(); void add_data(); @@ -80,6 +83,9 @@ private slots: void fromAxisAndAngle_data(); void fromAxisAndAngle(); + void fromRotationMatrix_data(); + void fromRotationMatrix(); + void slerp_data(); void slerp(); @@ -291,6 +297,32 @@ void tst_QQuaternion::normalize() QCOMPARE(v.length(), 1.0f); } +void tst_QQuaternion::inverted_data() +{ + // Use the same test data as the length test. + length_data(); +} +void tst_QQuaternion::inverted() +{ + QFETCH(float, x); + QFETCH(float, y); + QFETCH(float, z); + QFETCH(float, w); + QFETCH(float, len); + + QQuaternion v(w, x, y, z); + QQuaternion u = v.inverted(); + if (v.isNull()) { + QVERIFY(u.isNull()); + } else { + len *= len; + QCOMPARE(-u.x() * len, v.x()); + QCOMPARE(-u.y() * len, v.y()); + QCOMPARE(-u.z() * len, v.z()); + QCOMPARE(u.scalar() * len, v.scalar()); + } +} + // Test the comparison operators for quaternions. void tst_QQuaternion::compare() { @@ -696,6 +728,25 @@ void tst_QQuaternion::fromAxisAndAngle() QVERIFY(qFuzzyCompare(answer.scalar(), result.scalar())); } +// Test quaternion convertion to and from rotation matrix. +void tst_QQuaternion::fromRotationMatrix_data() +{ + fromAxisAndAngle_data(); +} +void tst_QQuaternion::fromRotationMatrix() +{ + QFETCH(float, x1); + QFETCH(float, y1); + QFETCH(float, z1); + QFETCH(float, angle); + + QQuaternion result = QQuaternion::fromAxisAndAngle(QVector3D(x1, y1, z1), angle); + QMatrix3x3 rot3x3 = result.toRotationMatrix(); + QQuaternion answer = QQuaternion::fromRotationMatrix(rot3x3); + + QVERIFY(qFuzzyCompare(answer, result) || qFuzzyCompare(-answer, result)); +} + // Test spherical interpolation of quaternions. void tst_QQuaternion::slerp_data() { diff --git a/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp b/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp index 2d4b6d16b0..2b3fbff000 100644 --- a/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp +++ b/tests/auto/gui/math3d/qvectornd/tst_qvectornd.cpp @@ -36,6 +36,7 @@ #include <QtGui/qvector2d.h> #include <QtGui/qvector3d.h> #include <QtGui/qvector4d.h> +#include <QtGui/qmatrix4x4.h> class tst_QVectorND : public QObject { @@ -113,6 +114,13 @@ private slots: void divide4_data(); void divide4(); + void divideFactor2_data(); + void divideFactor2(); + void divideFactor3_data(); + void divideFactor3(); + void divideFactor4_data(); + void divideFactor4(); + void negate2_data(); void negate2(); void negate3_data(); @@ -142,6 +150,11 @@ private slots: void dotProduct4_data(); void dotProduct4(); + void project_data(); + void project(); + void unproject_data(); + void unproject(); + void properties(); void metaTypes(); }; @@ -1623,16 +1636,154 @@ void tst_QVectorND::multiplyFactor4() QCOMPARE(v3.w(), v1.w() * factor); } -// Test vector division by a factor for 2D vectors. +// Test component-wise vector division for 2D vectors. void tst_QVectorND::divide2_data() { // Use the same test data as the multiply test. - multiplyFactor2_data(); + multiply2_data(); } void tst_QVectorND::divide2() { QFETCH(float, x1); QFETCH(float, y1); + QFETCH(float, x2); + QFETCH(float, y2); + QFETCH(float, x3); + QFETCH(float, y3); + + QVector2D v1(x1, y1); + QVector2D v2(x2, y2); + QVector2D v3(x3, y3); + + if (v2.x() != 0.0f && v2.y() != 0.0f) { + QVERIFY((v3 / v2) == v1); + + QVector2D v4(v3); + v4 /= v2; + QVERIFY(v4 == v1); + + QCOMPARE(v4.x(), v3.x() / v2.x()); + QCOMPARE(v4.y(), v3.y() / v2.y()); + } + if (v1.x() != 0.0f && v1.y() != 0.0f) { + QVERIFY((v3 / v1) == v2); + + QVector2D v4(v3); + v4 /= v1; + QVERIFY(v4 == v2); + + QCOMPARE(v4.x(), v3.x() / v1.x()); + QCOMPARE(v4.y(), v3.y() / v1.y()); + } +} + +// Test component-wise vector division for 3D vectors. +void tst_QVectorND::divide3_data() +{ + // Use the same test data as the multiply test. + multiply3_data(); +} +void tst_QVectorND::divide3() +{ + QFETCH(float, x1); + QFETCH(float, y1); + QFETCH(float, z1); + QFETCH(float, x2); + QFETCH(float, y2); + QFETCH(float, z2); + QFETCH(float, x3); + QFETCH(float, y3); + QFETCH(float, z3); + + QVector3D v1(x1, y1, z1); + QVector3D v2(x2, y2, z2); + QVector3D v3(x3, y3, z3); + + if (v2.x() != 0.0f && v2.y() != 0.0f && v2.z() != 0.0f) { + QVERIFY((v3 / v2) == v1); + + QVector3D v4(v3); + v4 /= v2; + QVERIFY(v4 == v1); + + QCOMPARE(v4.x(), v3.x() / v2.x()); + QCOMPARE(v4.y(), v3.y() / v2.y()); + QCOMPARE(v4.z(), v3.z() / v2.z()); + } + if (v1.x() != 0.0f && v1.y() != 0.0f && v1.z() != 0.0f) { + QVERIFY((v3 / v1) == v2); + + QVector3D v4(v3); + v4 /= v1; + QVERIFY(v4 == v2); + + QCOMPARE(v4.x(), v3.x() / v1.x()); + QCOMPARE(v4.y(), v3.y() / v1.y()); + QCOMPARE(v4.z(), v3.z() / v1.z()); + } +} + +// Test component-wise vector division for 4D vectors. +void tst_QVectorND::divide4_data() +{ + // Use the same test data as the multiply test. + multiply4_data(); +} +void tst_QVectorND::divide4() +{ + QFETCH(float, x1); + QFETCH(float, y1); + QFETCH(float, z1); + QFETCH(float, w1); + QFETCH(float, x2); + QFETCH(float, y2); + QFETCH(float, z2); + QFETCH(float, w2); + QFETCH(float, x3); + QFETCH(float, y3); + QFETCH(float, z3); + QFETCH(float, w3); + + QVector4D v1(x1, y1, z1, w1); + QVector4D v2(x2, y2, z2, w2); + QVector4D v3(x3, y3, z3, w3); + + if (v2.x() != 0.0f && v2.y() != 0.0f && v2.z() != 0.0f && v2.w() != 0.0f) { + QVERIFY((v3 / v2) == v1); + + QVector4D v4(v3); + v4 /= v2; + QVERIFY(v4 == v1); + + QCOMPARE(v4.x(), v3.x() / v2.x()); + QCOMPARE(v4.y(), v3.y() / v2.y()); + QCOMPARE(v4.z(), v3.z() / v2.z()); + QCOMPARE(v4.w(), v3.w() / v2.w()); + } + if (v1.x() != 0.0f && v1.y() != 0.0f && v1.z() != 0.0f && v1.w() != 0.0f) { + QVERIFY((v3 / v1) == v2); + + QVector4D v4(v3); + v4 /= v1; + QVERIFY(v4 == v2); + + QCOMPARE(v4.x(), v3.x() / v1.x()); + QCOMPARE(v4.y(), v3.y() / v1.y()); + QCOMPARE(v4.z(), v3.z() / v1.z()); + QCOMPARE(v4.w(), v3.w() / v1.w()); + } +} + +// Test vector division by a factor for 2D vectors. +void tst_QVectorND::divideFactor2_data() +{ + // Use the same test data as the multiplyFactor test. + multiplyFactor2_data(); +} +void tst_QVectorND::divideFactor2() +{ + QFETCH(float, x1); + QFETCH(float, y1); QFETCH(float, factor); QFETCH(float, x2); QFETCH(float, y2); @@ -1654,12 +1805,12 @@ void tst_QVectorND::divide2() } // Test vector division by a factor for 3D vectors. -void tst_QVectorND::divide3_data() +void tst_QVectorND::divideFactor3_data() { - // Use the same test data as the multiply test. + // Use the same test data as the multiplyFactor test. multiplyFactor3_data(); } -void tst_QVectorND::divide3() +void tst_QVectorND::divideFactor3() { QFETCH(float, x1); QFETCH(float, y1); @@ -1687,12 +1838,12 @@ void tst_QVectorND::divide3() } // Test vector division by a factor for 4D vectors. -void tst_QVectorND::divide4_data() +void tst_QVectorND::divideFactor4_data() { - // Use the same test data as the multiply test. + // Use the same test data as the multiplyFactor test. multiplyFactor4_data(); } -void tst_QVectorND::divide4() +void tst_QVectorND::divideFactor4() { QFETCH(float, x1); QFETCH(float, y1); @@ -2291,6 +2442,158 @@ void tst_QVectorND::dotProduct4() QCOMPARE(QVector4D::dotProduct(v1, v2), d); } +void tst_QVectorND::project_data() +{ + QTest::addColumn<QVector3D>("point"); + QTest::addColumn<QRect>("viewport"); + QTest::addColumn<QMatrix4x4>("projection"); + QTest::addColumn<QMatrix4x4>("view"); + QTest::addColumn<QVector2D>("result"); + + QMatrix4x4 projection; + projection.ortho(-1.0f, 1.0f, -1.0f, 1.0f, 0.1f, 1000.0f); + + QMatrix4x4 view; + // Located at (0, 0, 10), looking at origin, y is up + view.lookAt(QVector3D(0.0f, 0.0f, 10.0f), QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 1.0f, 0.0f)); + + QMatrix4x4 nullMatrix(0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f); + + QTest::newRow("center") + << QVector3D(0.0f, 0.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector2D(400.0f, 300.0f); + + QTest::newRow("topLeft") + << QVector3D(-1.0f, 1.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector2D(0.0f, 600.0f); + + QTest::newRow("topRight") + << QVector3D(1.0f, 1.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector2D(800.0f, 600.0f); + + QTest::newRow("bottomLeft") + << QVector3D(-1.0f, -1.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector2D(0.0f, 0.0f); + + QTest::newRow("bottomRight") + << QVector3D(1.0f, -1.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector2D(800.0f, 0.0f); + + QTest::newRow("nullMatrix") + << QVector3D(0.0f, 0.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << nullMatrix + << nullMatrix + << QVector2D(400.0f, 300.0f); +} + +void tst_QVectorND::project() +{ + QFETCH(QVector3D, point); + QFETCH(QRect, viewport); + QFETCH(QMatrix4x4, projection); + QFETCH(QMatrix4x4, view); + QFETCH(QVector2D, result); + + QVector3D project = point.project(view, projection, viewport); + + QCOMPARE(project.toVector2D(), result); +} + +void tst_QVectorND::unproject_data() +{ + QTest::addColumn<QVector3D>("point"); + QTest::addColumn<QRect>("viewport"); + QTest::addColumn<QMatrix4x4>("projection"); + QTest::addColumn<QMatrix4x4>("view"); + QTest::addColumn<QVector3D>("result"); + + QMatrix4x4 projection; + projection.ortho(-1.0f, 1.0f, -1.0f, 1.0f, 0.1f, 1000.0f); + + QMatrix4x4 view; + // Located at (0, 0, 10), looking at origin, y is up + view.lookAt(QVector3D(0.0f, 0.0f, 10.0f), QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 1.0f, 0.0f)); + + QMatrix4x4 nullMatrix(0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f); + + QTest::newRow("center") + << QVector3D(400.0f, 300.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector3D(0.0f, 0.0f, 9.9f); + + QTest::newRow("topLeft") + << QVector3D(0.0f, 600.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector3D(-1.0f, 1.0f, 9.9f); + + QTest::newRow("topRight") + << QVector3D(800.0f, 600.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector3D(1.0f, 1.0f, 9.9f); + + QTest::newRow("bottomLeft") + << QVector3D(0.0f, 0.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector3D(-1.0, -1.0f, 9.9f); + + QTest::newRow("bottomRight") + << QVector3D(800.0f, 0.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << projection + << view + << QVector3D(1.0f, -1.0f, 9.9f); + + QTest::newRow("nullMatrix") + << QVector3D(400.0f, 300.0f, 0.0f) + << QRect(0.0f, 0.0f, 800.0f, 600.0f) + << nullMatrix + << nullMatrix + << QVector3D(0.0f, 0.0f, -1.0f); + +} + +void tst_QVectorND::unproject() +{ + QFETCH(QVector3D, point); + QFETCH(QRect, viewport); + QFETCH(QMatrix4x4, projection); + QFETCH(QMatrix4x4, view); + QFETCH(QVector3D, result); + + QVector3D unproject = point.unproject(view, projection, viewport); + QVERIFY(qFuzzyCompare(unproject, result)); +} + class tst_QVectorNDProperties : public QObject { Q_OBJECT diff --git a/tests/auto/gui/painting/qbrush/qbrush.pro b/tests/auto/gui/painting/qbrush/qbrush.pro index 526de12815..0cb11398dc 100644 --- a/tests/auto/gui/painting/qbrush/qbrush.pro +++ b/tests/auto/gui/painting/qbrush/qbrush.pro @@ -1,5 +1,5 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qbrush -QT += testlib +QT += testlib gui-private SOURCES += tst_qbrush.cpp diff --git a/tests/auto/gui/painting/qbrush/tst_qbrush.cpp b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp index d252a0e87c..5ffba431ff 100644 --- a/tests/auto/gui/painting/qbrush/tst_qbrush.cpp +++ b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp @@ -37,6 +37,7 @@ #include "qbrush.h" #include <QPainter> #include <QBitmap> +#include <private/qpixmap_raster_p.h> #include <qdebug.h> @@ -69,6 +70,9 @@ private slots: void nullBrush(); void isOpaque(); void debug(); + + void textureBrushStream(); + void textureBrushComparison(); }; @@ -407,5 +411,59 @@ void tst_QBrush::debug() qDebug() << pixmap_brush; // don't crash } +void tst_QBrush::textureBrushStream() +{ + QPixmap pixmap_source(10, 10); + QImage image_source(10, 10, QImage::Format_RGB32); + + fill(&pixmap_source); + fill(&image_source); + + QBrush pixmap_brush; + pixmap_brush.setTexture(pixmap_source); + QBrush image_brush; + image_brush.setTextureImage(image_source); + + QByteArray data1; + QByteArray data2; + { + QDataStream stream1(&data1, QIODevice::WriteOnly); + QDataStream stream2(&data2, QIODevice::WriteOnly); + stream1 << pixmap_brush; + stream2 << image_brush; + } + + QBrush loadedBrush1; + QBrush loadedBrush2; + { + QDataStream stream1(&data1, QIODevice::ReadOnly); + QDataStream stream2(&data2, QIODevice::ReadOnly); + stream1 >> loadedBrush1; + stream2 >> loadedBrush2; + } + + QCOMPARE(loadedBrush1.style(), Qt::TexturePattern); + QCOMPARE(loadedBrush2.style(), Qt::TexturePattern); + QCOMPARE(loadedBrush1.texture(), pixmap_source); + QCOMPARE(loadedBrush2.textureImage(), image_source); +} + +void tst_QBrush::textureBrushComparison() +{ + QImage image1(10, 10, QImage::Format_RGB32); + QRasterPlatformPixmap* ppixmap = new QRasterPlatformPixmap(QPlatformPixmap::PixmapType); + ppixmap->fromImage(image1, Qt::NoFormatConversion); + QPixmap pixmap(ppixmap); + QImage image2(image1); + + QBrush pixmapBrush, imageBrush1, imageBrush2; + pixmapBrush.setTexture(pixmap); + imageBrush1.setTextureImage(image1); + imageBrush2.setTextureImage(image2); + + QVERIFY(imageBrush1 == imageBrush2); + QVERIFY(pixmapBrush == imageBrush1); +} + QTEST_MAIN(tst_QBrush) #include "tst_qbrush.moc" diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 405f84d527..3b3334ba1f 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -102,7 +102,7 @@ private slots: void achromaticHslHue(); -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 void setallowX11ColorNames(); #endif }; @@ -1373,7 +1373,7 @@ void tst_QColor::achromaticHslHue() QCOMPARE(hsl.hslHue(), -1); } -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 void tst_QColor::setallowX11ColorNames() { #if defined(Q_OS_IRIX) diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 8a0705630d..9ca8e78fff 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -501,7 +501,7 @@ void tst_QPainter::drawPixmap_comp() destPm.fill(c1); srcPm.fill(c2); -#if defined(Q_WS_X11) +#if defined(Q_DEAD_CODE_FROM_QT4_X11) if (!destPm.x11PictureHandle()) QSKIP("Requires XRender support"); #endif @@ -3443,7 +3443,8 @@ void tst_QPainter::drawImage_data() for (int srcFormat = QImage::Format_Mono; srcFormat < QImage::NImageFormats; ++srcFormat) { for (int dstFormat = QImage::Format_Mono; dstFormat < QImage::NImageFormats; ++dstFormat) { - if (dstFormat == QImage::Format_Indexed8) + // Indexed8 can't be painted to, and Alpha8 can't hold a color. + if (dstFormat == QImage::Format_Indexed8 || dstFormat == QImage::Format_Alpha8) continue; for (int odd_x = 0; odd_x <= 1; ++odd_x) { for (int odd_width = 0; odd_width <= 1; ++odd_width) { diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp index a03bf2ba4e..6bfec61363 100644 --- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp @@ -37,9 +37,7 @@ #include <qfile.h> #include <qpainterpath.h> #include <qpen.h> - -#define _USE_MATH_DEFINES -#include <math.h> +#include <qmath.h> class tst_QPainterPath : public QObject { diff --git a/tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp b/tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp index f55260c572..3bccfb75f7 100644 --- a/tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp +++ b/tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp @@ -36,9 +36,7 @@ #include <qfile.h> #include <QPainterPathStroker> - -#define _USE_MATH_DEFINES -#include <math.h> +#include <qmath.h> class tst_QPainterPathStroker : public QObject { diff --git a/tests/auto/gui/painting/qpathclipper/qpathclipper.pro b/tests/auto/gui/painting/qpathclipper/qpathclipper.pro index 18f7ccef2f..b90bca8df3 100644 --- a/tests/auto/gui/painting/qpathclipper/qpathclipper.pro +++ b/tests/auto/gui/painting/qpathclipper/qpathclipper.pro @@ -8,4 +8,4 @@ QT += gui-private testlib requires(contains(QT_CONFIG,private_tests)) -unix:!mac:LIBS+=-lm +unix:!mac:!haiku:LIBS+=-lm diff --git a/tests/auto/gui/painting/qpolygon/qpolygon.pro b/tests/auto/gui/painting/qpolygon/qpolygon.pro index f3e75d7e9e..4783e4b5d4 100644 --- a/tests/auto/gui/painting/qpolygon/qpolygon.pro +++ b/tests/auto/gui/painting/qpolygon/qpolygon.pro @@ -4,6 +4,6 @@ TARGET = tst_qpolygon QT += testlib SOURCES += tst_qpolygon.cpp -unix:!mac:LIBS+=-lm +unix:!mac:!haiku:LIBS+=-lm diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp index 091265285f..95028a29fd 100644 --- a/tests/auto/gui/painting/qregion/tst_qregion.cpp +++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp @@ -38,7 +38,7 @@ #include <qbitmap.h> #include <qpainter.h> #include <qpolygon.h> -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 #include <private/qt_x11_p.h> #endif @@ -82,7 +82,7 @@ private slots: void isEmpty_data(); void isEmpty(); -#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL) +#if defined(Q_DEAD_CODE_FROM_QT4_X11) && defined(QT_BUILD_INTERNAL) void clipRectangles(); #endif @@ -848,7 +848,7 @@ void tst_QRegion::isEmpty() QVERIFY(region.rects().isEmpty()); } -#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL) +#if defined(Q_DEAD_CODE_FROM_QT4_X11) && defined(QT_BUILD_INTERNAL) void tst_QRegion::clipRectangles() { QRegion region(30, 30, 30, 30); diff --git a/tests/auto/gui/painting/qtransform/qtransform.pro b/tests/auto/gui/painting/qtransform/qtransform.pro index 1b5c2a4f25..d59c040fb8 100644 --- a/tests/auto/gui/painting/qtransform/qtransform.pro +++ b/tests/auto/gui/painting/qtransform/qtransform.pro @@ -4,4 +4,4 @@ TARGET = tst_qtransform SOURCES += tst_qtransform.cpp QT += testlib -unix:!mac:LIBS+=-lm +unix:!mac:!haiku:LIBS+=-lm diff --git a/tests/auto/gui/painting/qwmatrix/qwmatrix.pro b/tests/auto/gui/painting/qwmatrix/qwmatrix.pro index e0e260555a..b3bec3d4ff 100644 --- a/tests/auto/gui/painting/qwmatrix/qwmatrix.pro +++ b/tests/auto/gui/painting/qwmatrix/qwmatrix.pro @@ -4,4 +4,4 @@ TARGET = tst_qwmatrix SOURCES += tst_qwmatrix.cpp QT += testlib -unix:!mac:LIBS+=-lm +unix:!mac:!haiku:LIBS+=-lm diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index 89ad66c1e8..a8834563a1 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -98,6 +98,8 @@ private slots: void textureblitterPartTargetRectTransform(); void defaultSurfaceFormat(); + void imageFormatPainting(); + #ifdef USE_GLX void glxContextWrap(); #endif @@ -718,6 +720,68 @@ void tst_QOpenGL::fboHandleNulledAfterContextDestroyed() QCOMPARE(fbo->handle(), 0U); } +void tst_QOpenGL::imageFormatPainting() +{ + QScopedPointer<QSurface> surface(createSurface(QSurface::Window)); + + QOpenGLContext ctx; + QVERIFY(ctx.create()); + + QVERIFY(ctx.makeCurrent(surface.data())); + + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + QSKIP("QOpenGLFramebufferObject not supported on this platform"); + + QOpenGLFramebufferObjectFormat fboFormat; + fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + + const QSize size(128, 128); + QOpenGLFramebufferObject fbo(size, fboFormat); + + if (fbo.attachment() != QOpenGLFramebufferObject::CombinedDepthStencil) + QSKIP("FBOs missing combined depth~stencil support"); + + QVERIFY(fbo.bind()); + + QImage alpha(128, 128, QImage::Format_Alpha8); + alpha.fill(127); + + QPainter fboPainter; + QOpenGLPaintDevice device(fbo.width(), fbo.height()); + + QVERIFY(fboPainter.begin(&device)); + fboPainter.fillRect(0, 0, 128, 128, qRgb(255, 0, 255)); + fboPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + fboPainter.drawImage(0, 0, alpha); + fboPainter.end(); + + QImage fb = fbo.toImage(); + QCOMPARE(fb.pixel(0, 0), qRgba(127, 0, 127, 127)); + + QImage grayscale(128, 128, QImage::Format_Grayscale8); + grayscale.fill(128); + + QVERIFY(fboPainter.begin(&device)); + fboPainter.setCompositionMode(QPainter::CompositionMode_Plus); + fboPainter.drawImage(0, 0, grayscale); + fboPainter.end(); + + fb = fbo.toImage(); + QCOMPARE(fb.pixel(0, 0), qRgb(255, 128, 255)); + + QImage argb(128, 128, QImage::Format_ARGB32); + argb.fill(qRgba(255, 255, 255, 128)); + + QVERIFY(fboPainter.begin(&device)); + fboPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); + fboPainter.drawImage(0, 0, argb); + fboPainter.end(); + + fb = fbo.toImage(); + QCOMPARE(fb.pixel(0, 0), qRgb(255, 192, 255)); + +} + void tst_QOpenGL::openGLPaintDevice_data() { QTest::addColumn<int>("surfaceClass"); diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index f60a229c08..380aaa87f9 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -591,10 +591,6 @@ void tst_QFont::serialize_data() QTest::newRow("letterSpacing") << font << QDataStream::Qt_4_5; font = basicFont; - font.setRawMode(true); - QTest::newRow("rawMode") << font << QDataStream::Qt_1_0; - - font = basicFont; font.setKerning(false); QTest::newRow("kerning") << font << QDataStream::Qt_4_0; diff --git a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp index 969c8f9ce7..8cb32dabd1 100644 --- a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp @@ -948,7 +948,7 @@ void tst_QRawFont::rawFontFromInvalidData() QVERIFY(!font.isValid()); - invalidData.fill(255, 1024); + invalidData.fill(char(255), 1024); font.loadFromData(invalidData, 10, QFont::PreferDefaultHinting); QVERIFY(!font.isValid()); diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 4cab2b8a51..139cafa1fa 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -78,6 +78,8 @@ private slots: void find2(); void findWithRegExp_data(); void findWithRegExp(); + void findWithRegularExpression_data(); + void findWithRegularExpression(); void findMultiple(); void basicIsModifiedChecks(); void moreIsModified(); @@ -188,6 +190,7 @@ private slots: private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); + void buildRegExpData(); QTextDocument *doc; QTextCursor cursor; @@ -344,21 +347,7 @@ void tst_QTextDocument::find() void tst_QTextDocument::findWithRegExp_data() { - QTest::addColumn<QString>("haystack"); - QTest::addColumn<QString>("needle"); - QTest::addColumn<int>("flags"); - QTest::addColumn<int>("from"); - QTest::addColumn<int>("anchor"); - QTest::addColumn<int>("position"); - - // match integers 0 to 99 - QTest::newRow("1") << "23" << "^\\d\\d?$" << int(QTextDocument::FindCaseSensitively) << 0 << 0 << 2; - // match ampersands but not & - QTest::newRow("2") << "His & hers & theirs" << "&(?!amp;)"<< int(QTextDocument::FindCaseSensitively) << 0 << 15 << 16; - //backward search - QTest::newRow("3") << QString::fromLatin1("HelloBlahWorld Blah Hah") - << "h" << int(QTextDocument::FindBackward) << 18 << 8 << 9; - + buildRegExpData(); } void tst_QTextDocument::findWithRegExp() @@ -385,6 +374,34 @@ void tst_QTextDocument::findWithRegExp() } } +void tst_QTextDocument::findWithRegularExpression_data() +{ + buildRegExpData(); +} + +void tst_QTextDocument::findWithRegularExpression() +{ + QFETCH(QString, haystack); + QFETCH(QString, needle); + QFETCH(int, flags); + QFETCH(int, from); + QFETCH(int, anchor); + QFETCH(int, position); + + cursor.insertText(haystack); + //search using a regular expression + QRegularExpression expr(needle); + QTextDocument::FindFlags flg(flags); + cursor = doc->find(expr, from, flg); + + if (anchor != -1) { + QCOMPARE(cursor.anchor(), anchor); + QCOMPARE(cursor.position(), position); + } else { + QVERIFY(cursor.isNull()); + } +} + void tst_QTextDocument::find2() { doc->setPlainText("aaa"); @@ -2594,6 +2611,24 @@ void tst_QTextDocument::backgroundImage_checkExpectedHtml(const QTextDocument &d QCOMPARE(doc.toHtml(), expectedHtml); } +void tst_QTextDocument::buildRegExpData() +{ + QTest::addColumn<QString>("haystack"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<int>("flags"); + QTest::addColumn<int>("from"); + QTest::addColumn<int>("anchor"); + QTest::addColumn<int>("position"); + + // match integers 0 to 99 + QTest::newRow("1") << "23" << "^\\d\\d?$" << int(QTextDocument::FindCaseSensitively) << 0 << 0 << 2; + // match ampersands but not & + QTest::newRow("2") << "His & hers & theirs" << "&(?!amp;)"<< int(QTextDocument::FindCaseSensitively) << 0 << 15 << 16; + //backward search + QTest::newRow("3") << QString::fromLatin1("HelloBlahWorld Blah Hah") + << "h" << int(QTextDocument::FindBackward) << 18 << 8 << 9; +} + void tst_QTextDocument::backgroundImage_toHtml() { CREATE_DOC_AND_CURSOR(); diff --git a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp index e95de3df45..51e993a7d6 100644 --- a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp +++ b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp @@ -67,6 +67,7 @@ private slots: void clippedTableCell(); void floatingTablePageBreak(); void imageAtRightAlignedTab(); + void blockVisibility(); private: QTextDocument *doc; @@ -312,5 +313,46 @@ void tst_QTextDocumentLayout::imageAtRightAlignedTab() QCOMPARE(doc->idealWidth(), 300.0); } +void tst_QTextDocumentLayout::blockVisibility() +{ + QTextCursor cursor(doc); + for (int i = 0; i < 10; ++i) { + if (!doc->isEmpty()) + cursor.insertBlock(); + cursor.insertText(QString::number(i)); + } + + qreal margin = doc->documentMargin(); + QSizeF emptySize(2 * margin, 2 * margin); + QSizeF halfSize = doc->size(); + halfSize.rheight() -= 2 * margin; + halfSize.rheight() /= 2; + halfSize.rheight() += 2 * margin; + + for (int i = 0; i < 10; i += 2) { + QTextBlock block = doc->findBlockByNumber(i); + block.setVisible(false); + doc->markContentsDirty(block.position(), block.length()); + } + + QCOMPARE(doc->size(), halfSize); + + for (int i = 1; i < 10; i += 2) { + QTextBlock block = doc->findBlockByNumber(i); + block.setVisible(false); + doc->markContentsDirty(block.position(), block.length()); + } + + QCOMPARE(doc->size(), emptySize); + + for (int i = 0; i < 10; i += 2) { + QTextBlock block = doc->findBlockByNumber(i); + block.setVisible(true); + doc->markContentsDirty(block.position(), block.length()); + } + + QCOMPARE(doc->size(), halfSize); +} + QTEST_MAIN(tst_QTextDocumentLayout) #include "tst_qtextdocumentlayout.moc" diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 3ccedf6248..7afffff00b 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -315,6 +315,7 @@ private Q_SLOTS: void ioPostToHttpFromMiddleOfQBufferFiveBytes(); void ioPostToHttpNoBufferFlag(); void ioPostToHttpUploadProgress(); + void emitAllUploadProgressSignals(); void ioPostToHttpEmptyUploadProgress(); void lastModifiedHeaderForFile(); @@ -4979,6 +4980,59 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() server.close(); } +void tst_QNetworkReply::emitAllUploadProgressSignals() +{ + QFile sourceFile(testDataDir + "/image1.jpg"); + QVERIFY(sourceFile.open(QIODevice::ReadOnly)); + + // emulate a minimal http server + QTcpServer server; + server.listen(QHostAddress(QHostAddress::LocalHost), 0); + connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); + QNetworkRequest normalRequest(url); + normalRequest.setRawHeader("Content-Type", "application/octet-stream"); + + QNetworkRequest catchAllSignalsRequest(normalRequest); + catchAllSignalsRequest.setAttribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute, true); + + QList<QNetworkRequest> requests; + requests << normalRequest << catchAllSignalsRequest; + + QList<int> signalCount; + + foreach (const QNetworkRequest &request, requests) { + + sourceFile.seek(0); + QNetworkReplyPtr reply(manager.post(request, &sourceFile)); + QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); + + // get the request started and the incoming socket connected + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + QTcpSocket *incomingSocket = server.nextPendingConnection(); + QVERIFY(incomingSocket); + QTestEventLoop::instance().enterLoop(10); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + incomingSocket->write("HTTP/1.0 200 OK\r\n"); + incomingSocket->write("Content-Length: 0\r\n"); + incomingSocket->write("\r\n"); + QTestEventLoop::instance().enterLoop(10); + // not timeouted -> finished() was emitted + QVERIFY(!QTestEventLoop::instance().timeout()); + + incomingSocket->close(); + signalCount.append(spy.count()); + reply->deleteLater(); + } + server.close(); + + // verify that the normal request emitted less signals than the one emitting all signals + QVERIFY2(signalCount.at(0) < signalCount.at(1), "no upload signal was suppressed"); +} + void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() { QByteArray ba; diff --git a/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp b/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp index 30a01cb6f4..4d719e2710 100644 --- a/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp +++ b/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp @@ -55,6 +55,8 @@ private slots: void octetString(); void objectIdentifier_data(); void objectIdentifier(); + void string_data(); + void string(); }; void tst_QAsn1Element::emptyConstructor() @@ -265,5 +267,58 @@ void tst_QAsn1Element::objectIdentifier() QCOMPARE(elem.toObjectName(), name); } +void tst_QAsn1Element::string_data() +{ + QTest::addColumn<QAsn1Element>("element"); + QTest::addColumn<QString>("value"); + + QTest::newRow("printablestring") + << QAsn1Element(QAsn1Element::PrintableStringType, QByteArray("Hello World")) + << QStringLiteral("Hello World"); + QTest::newRow("teletextstring") + << QAsn1Element(QAsn1Element::TeletexStringType, QByteArray("Hello World")) + << QStringLiteral("Hello World"); + QTest::newRow("utf8string") + << QAsn1Element(QAsn1Element::Utf8StringType, QByteArray("Hello World")) + << QStringLiteral("Hello World"); + QTest::newRow("rfc822name") + << QAsn1Element(QAsn1Element::Rfc822NameType, QByteArray("Hello World")) + << QStringLiteral("Hello World"); + QTest::newRow("dnsname") + << QAsn1Element(QAsn1Element::DnsNameType, QByteArray("Hello World")) + << QStringLiteral("Hello World"); + QTest::newRow("uri") + << QAsn1Element(QAsn1Element::UniformResourceIdentifierType, QByteArray("Hello World")) + << QStringLiteral("Hello World"); + + // Embedded NULs are not allowed and should be rejected + QTest::newRow("evil_printablestring") + << QAsn1Element(QAsn1Element::PrintableStringType, QByteArray("Hello\0World", 11)) + << QString(); + QTest::newRow("evil_teletextstring") + << QAsn1Element(QAsn1Element::TeletexStringType, QByteArray("Hello\0World", 11)) + << QString(); + QTest::newRow("evil_utf8string") + << QAsn1Element(QAsn1Element::Utf8StringType, QByteArray("Hello\0World", 11)) + << QString(); + QTest::newRow("evil_rfc822name") + << QAsn1Element(QAsn1Element::Rfc822NameType, QByteArray("Hello\0World", 11)) + << QString(); + QTest::newRow("evil_dnsname") + << QAsn1Element(QAsn1Element::DnsNameType, QByteArray("Hello\0World", 11)) + << QString(); + QTest::newRow("evil_uri") + << QAsn1Element(QAsn1Element::UniformResourceIdentifierType, QByteArray("Hello\0World", 11)) + << QString(); +} + +void tst_QAsn1Element::string() +{ + QFETCH(QAsn1Element, element); + QFETCH(QString, value); + + QCOMPARE(element.toString(), value); +} + QTEST_MAIN(tst_QAsn1Element) #include "tst_qasn1element.moc" diff --git a/tests/auto/network/ssl/qsslellipticcurve/.gitignore b/tests/auto/network/ssl/qsslellipticcurve/.gitignore new file mode 100644 index 0000000000..27f97e770a --- /dev/null +++ b/tests/auto/network/ssl/qsslellipticcurve/.gitignore @@ -0,0 +1 @@ +tst_qsslellipticcurves diff --git a/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro b/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro new file mode 100644 index 0000000000..d9a771a080 --- /dev/null +++ b/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +CONFIG += parallel_test + +SOURCES += tst_qsslellipticcurve.cpp +!wince*:win32:LIBS += -lws2_32 +QT = core network testlib + +TARGET = tst_qsslellipticcurve diff --git a/tests/auto/network/ssl/qsslellipticcurve/tst_qsslellipticcurve.cpp b/tests/auto/network/ssl/qsslellipticcurve/tst_qsslellipticcurve.cpp new file mode 100644 index 0000000000..67d87530ec --- /dev/null +++ b/tests/auto/network/ssl/qsslellipticcurve/tst_qsslellipticcurve.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Governikus GmbH & Co. KG. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QSslEllipticCurve> +#include <QSslSocket> + +class tst_QSslEllipticCurve : public QObject +{ + Q_OBJECT + +#ifndef QT_NO_SSL +private Q_SLOTS: + void constExpr(); + void construction(); + void fromShortName_data(); + void fromShortName(); + void fromLongName_data(); + void fromLongName(); +#endif +}; + +#ifndef QT_NO_SSL + +void tst_QSslEllipticCurve::constExpr() +{ +#ifdef Q_COMPILER_CONSTEXPR + // check that default ctor and op ==/!= are constexpr: + char array1[QSslEllipticCurve() == QSslEllipticCurve() ? 1 : -1]; + char array2[QSslEllipticCurve() != QSslEllipticCurve() ? -1 : 1]; + Q_UNUSED(array1); + Q_UNUSED(array2); +#else + QSKIP("This test requires C++11 generalized constant expression support enabled in the compiler."); +#endif +} + +void tst_QSslEllipticCurve::construction() +{ + QSslEllipticCurve curve; + QCOMPARE(curve.isValid(), false); + QCOMPARE(curve.shortName(), QString()); + QCOMPARE(curve.longName(), QString()); + QCOMPARE(curve.isTlsNamedCurve(), false); +} + +void tst_QSslEllipticCurve::fromShortName_data() +{ + QTest::addColumn<QString>("shortName"); + QTest::addColumn<QSslEllipticCurve>("curve"); + QTest::addColumn<bool>("valid"); + + QTest::newRow("QString()") << QString() << QSslEllipticCurve() << false; + QTest::newRow("\"\"") << QString("") << QSslEllipticCurve() << false; + QTest::newRow("does-not-exist") << QStringLiteral("does-not-exist") << QSslEllipticCurve() << false; + Q_FOREACH (QSslEllipticCurve ec, QSslSocket::supportedEllipticCurves()) { + const QString sN = ec.shortName(); + QTest::newRow(qPrintable("supported EC \"" + sN + '"')) << sN << ec << true; + // At least in the OpenSSL impl, the short name is case-sensitive. That feels odd. + //const QString SN = sN.toUpper(); + //QTest::newRow(qPrintable("supported EC \"" + SN + '"')) << SN << ec << true; + //const QString sn = sN.toLower(); + //QTest::newRow(qPrintable("supported EC \"" + sn + '"')) << sn << ec << true; + } +} + +void tst_QSslEllipticCurve::fromShortName() +{ + QFETCH(QString, shortName); + QFETCH(QSslEllipticCurve, curve); + QFETCH(bool, valid); + + const QSslEllipticCurve result = QSslEllipticCurve::fromShortName(shortName); + QCOMPARE(result, curve); + QCOMPARE(result.isValid(), valid); + QCOMPARE(result.shortName(), curve.shortName()); + QCOMPARE(result.shortName(), valid ? shortName : QString()); +} + +void tst_QSslEllipticCurve::fromLongName_data() +{ + QTest::addColumn<QString>("longName"); + QTest::addColumn<QSslEllipticCurve>("curve"); + QTest::addColumn<bool>("valid"); + + QTest::newRow("QString()") << QString() << QSslEllipticCurve() << false; + QTest::newRow("\"\"") << QString("") << QSslEllipticCurve() << false; + QTest::newRow("does-not-exist") << QStringLiteral("does-not-exist") << QSslEllipticCurve() << false; + Q_FOREACH (QSslEllipticCurve ec, QSslSocket::supportedEllipticCurves()) { + const QString lN = ec.longName(); + QTest::newRow(qPrintable("supported EC \"" + lN + '"')) << lN << ec << true; + } +} + +void tst_QSslEllipticCurve::fromLongName() +{ + QFETCH(QString, longName); + QFETCH(QSslEllipticCurve, curve); + QFETCH(bool, valid); + + const QSslEllipticCurve result = QSslEllipticCurve::fromLongName(longName); + QCOMPARE(result, curve); + QCOMPARE(result.isValid(), valid); + QCOMPARE(result.longName(), curve.longName()); + QCOMPARE(result.longName(), valid ? longName : QString()); +} + +#endif // QT_NO_SSL + +QTEST_MAIN(tst_QSslEllipticCurve) +#include "tst_qsslellipticcurve.moc" diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1.der Binary files differnew file mode 100644 index 0000000000..96bd7e5802 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1.der diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1.pem new file mode 100644 index 0000000000..9719604a5b --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MGgCAQEEHO64tAcs1VO7jI5uxJWVZ4Vl2Ich+pv8ctBzuaigBwYFK4EEACGhPAM6 +AATCe752GB/gfLn631dS6JYBBL+YcYeSakOWm/LnAuzyvtNlMDXWxmGpJScDcqYT +okUBHW8YZbhj2A== +-----END EC PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-256-prime256v1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-256-prime256v1.der Binary files differnew file mode 100644 index 0000000000..410ad8e950 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-256-prime256v1.der diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-256-prime256v1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-256-prime256v1.pem new file mode 100644 index 0000000000..6a8af58066 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-256-prime256v1.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPgxX3TR74wCm/Ivz0uEtk0cumCVxmKbd5Vf0p+fV84toAoGCCqGSM49 +AwEHoUQDQgAEVtbEzyqqHhBSH7Dsx8YVaC0YcvhvBA06fcva1vHZV4hJj7GL6yaO +qjSIot2QW79M4ZoVFCu9GmOW+w+mjwMqNQ== +-----END EC PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-384-secp384r1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-384-secp384r1.der Binary files differnew file mode 100644 index 0000000000..f9663cbf43 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-384-secp384r1.der diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-384-secp384r1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-384-secp384r1.pem new file mode 100644 index 0000000000..53be8dfb52 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-384-secp384r1.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDDRnUOmMxV2R44q5RoM4ldm9A+5T4Xxzp6hWdRWOdhkIozo5GtNnYX8 +ZI5P3zTywD+gBwYFK4EEACKhZANiAAS/u72YC+dGs8D8bH+zRnneVMNPfGKeQrdt +avEiVfKO7nmGdPu7KK9HDQPiKbWc4Yxtn4n7tsKMKo4adnThakcjZxuCIVjmdHIP +9Wy7ZWeOaHi32MLHWQqh0z2elC92SmM= +-----END EC PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pub-224-secp224r1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pub-224-secp224r1.der Binary files differnew file mode 100644 index 0000000000..006a99437b --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pub-224-secp224r1.der diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pub-224-secp224r1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pub-224-secp224r1.pem new file mode 100644 index 0000000000..901d69d424 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pub-224-secp224r1.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +ME4wEAYHKoZIzj0CAQYFK4EEACEDOgAEwnu+dhgf4Hy5+t9XUuiWAQS/mHGHkmpD +lpvy5wLs8r7TZTA11sZhqSUnA3KmE6JFAR1vGGW4Y9g= +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pub-256-prime256v1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pub-256-prime256v1.der Binary files differnew file mode 100644 index 0000000000..82d3d462d9 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pub-256-prime256v1.der diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pub-256-prime256v1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pub-256-prime256v1.pem new file mode 100644 index 0000000000..76ec2d4b0a --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pub-256-prime256v1.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVtbEzyqqHhBSH7Dsx8YVaC0Ycvhv +BA06fcva1vHZV4hJj7GL6yaOqjSIot2QW79M4ZoVFCu9GmOW+w+mjwMqNQ== +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pub-384-secp384r1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pub-384-secp384r1.der Binary files differnew file mode 100644 index 0000000000..aee76614f2 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pub-384-secp384r1.der diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pub-384-secp384r1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pub-384-secp384r1.pem new file mode 100644 index 0000000000..ec69ee21a6 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/ec-pub-384-secp384r1.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEv7u9mAvnRrPA/Gx/s0Z53lTDT3xinkK3 +bWrxIlXyju55hnT7uyivRw0D4im1nOGMbZ+J+7bCjCqOGnZ04WpHI2cbgiFY5nRy +D/Vsu2Vnjmh4t9jCx1kKodM9npQvdkpj +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh index c9f2406cad..279e71e561 100755 --- a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh +++ b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh @@ -72,3 +72,25 @@ do echo -e "\ngenerating DSA public key to DER file ..." openssl dsa -in dsa-pri-$size.pem -pubout -out dsa-pub-$size.der -outform DER done + +#--- EC ---------------------------------------------------------------------------- +# Note: EC will be generated with pre-defined curves. You can check supported curves +# with openssl ecparam -list_curves. +# If OpenSSL 1.0.2 is available brainpool should be added! +# brainpoolP256r1 brainpoolP384r1 brainpoolP512r1 +for curve in secp224r1 prime256v1 secp384r1 +do + size=`tr -cd 0-9 <<< $curve` + size=${size::-1} # remove last number of curve name as we need bit size only + echo -e "\ngenerating EC private key to PEM file ..." + openssl ecparam -name $curve -genkey -noout -out ec-pri-$size-$curve.pem + + echo -e "\ngenerating EC private key to DER file ..." + openssl ec -in ec-pri-$size-$curve.pem -out ec-pri-$size-$curve.der -outform DER + + echo -e "\ngenerating EC public key to PEM file ..." + openssl ec -in ec-pri-$size-$curve.pem -pubout -out ec-pub-$size-$curve.pem + + echo -e "\ngenerating EC public key to DER file ..." + openssl ec -in ec-pri-$size-$curve.pem -pubout -out ec-pub-$size-$curve.der -outform DER +done diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index 8083662d40..ddd8cb64aa 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -105,12 +105,13 @@ void tst_QSslKey::initTestCase() QDir dir(testDataDir + "/keys"); QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable); - QRegExp rx(QLatin1String("^(rsa|dsa)-(pub|pri)-(\\d+)\\.(pem|der)$")); + QRegExp rx(QLatin1String("^(rsa|dsa|ec)-(pub|pri)-(\\d+)-?\\w*\\.(pem|der)$")); foreach (QFileInfo fileInfo, fileInfoList) { if (rx.indexIn(fileInfo.fileName()) >= 0) keyInfoList << KeyInfo( fileInfo, - rx.cap(1) == QLatin1String("rsa") ? QSsl::Rsa : QSsl::Dsa, + rx.cap(1) == QLatin1String("rsa") ? QSsl::Rsa : + (rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa : QSsl::Ec), rx.cap(2) == QLatin1String("pub") ? QSsl::PublicKey : QSsl::PrivateKey, rx.cap(3).toInt(), rx.cap(4) == QLatin1String("pem") ? QSsl::Pem : QSsl::Der); @@ -279,7 +280,8 @@ void tst_QSslKey::toEncryptedPemOrDer_data() foreach (KeyInfo keyInfo, keyInfoList) { foreach (QString password, passwords) { QString testName = QString("%1-%2-%3-%4-%5").arg(keyInfo.fileInfo.fileName()) - .arg(keyInfo.algorithm == QSsl::Rsa ? "RSA" : "DSA") + .arg(keyInfo.algorithm == QSsl::Rsa ? "RSA" : + (keyInfo.algorithm == QSsl::Dsa ? "DSA" : "EC")) .arg(keyInfo.type == QSsl::PrivateKey ? "PrivateKey" : "PublicKey") .arg(keyInfo.format == QSsl::Pem ? "PEM" : "DER") .arg(password); diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.crt b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.crt new file mode 100644 index 0000000000..cf5893e98d --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIJAJBdFtmKuuELMA0GCSqGSIb3DQEBCwUAMC8xGjAYBgNV +BAoMEUJvZ3VzIENvcnBvcmF0aW9uMREwDwYDVQQDDAhCb2d1cyBDQTAgFw0xNTAx +MzAxNzM0NDdaGA8yMTE1MDEwNjE3MzQ0N1owLzEaMBgGA1UECgwRQm9ndXMgQ29y +cG9yYXRpb24xETAPBgNVBAMMCEJvZ3VzIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnXt/X69lmfvWampP88f20yNs1VZroG9VjdR4GaJM6pbWu5Wn +SYBfS81osnHC7dTW2FvKZUGnz7KX+ImkbE2qUvj6yTeFu6ILj3o+8ws7A4iOTkiH +84CHb6T/HxWO5fW6mS5v+tvPDp3rQ7JpPVYvoh7dSv8X1+JCdDmkepRveN6Pzo47 +9VFVC0oscc5I4Y0wPwnaXZ4X26vmRfbhqtoKL57lz1lJ0R6bvLC9mf4DGFPx7WXQ +eOtlKX2dtuKj+Cl3vyHff6gHNMKM0bq3KfsT+vDO6eIs/ayqVRdd0XBIMj+bZYd9 +7QI/+3XTNR3TwTisrjo71XZtHdA1DkcMaSGoJwIDAQABo1AwTjAdBgNVHQ4EFgQU +xVZK4BIjBgmluCLIespCbne4BIUwHwYDVR0jBBgwFoAUxVZK4BIjBgmluCLIespC +bne4BIUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAgZn6odHr2y1G +1OStblBdsXNxmsW7WzhLUYFUhSzBw9KS/O7uG2HAFLwJNM4sQHeuc0JjxqXG5n7s +mGbmWpUYt8+KJDRnUssmKwwg2u6Rqp+0I9leCk9KTtYpXX7d9wprSsgwjQKhTEeQ +fNImbNR6Br7GDO7Om2MnOALvZmp0KJgUFIH0J630LJTrsrTvwfX7wKhYb1wgud5N +SXdGjBuJxKK3Y0VBMsbqwI0y+wHIYE+qLzlFWNRHmKaYeGtg0T8CVK6XWUrLcjcr +rQINqW3rb1OlWF7YZ5dg7vXoZrza6YSQLWha6/FQMCaKtJHxIE1NBw0ZXK6txnkI +f4HXoPvSGg== +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.key b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.key new file mode 100644 index 0000000000..1c2db7932e --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAnXt/X69lmfvWampP88f20yNs1VZroG9VjdR4GaJM6pbWu5Wn +SYBfS81osnHC7dTW2FvKZUGnz7KX+ImkbE2qUvj6yTeFu6ILj3o+8ws7A4iOTkiH +84CHb6T/HxWO5fW6mS5v+tvPDp3rQ7JpPVYvoh7dSv8X1+JCdDmkepRveN6Pzo47 +9VFVC0oscc5I4Y0wPwnaXZ4X26vmRfbhqtoKL57lz1lJ0R6bvLC9mf4DGFPx7WXQ +eOtlKX2dtuKj+Cl3vyHff6gHNMKM0bq3KfsT+vDO6eIs/ayqVRdd0XBIMj+bZYd9 +7QI/+3XTNR3TwTisrjo71XZtHdA1DkcMaSGoJwIDAQABAoIBAGKkKmJq4L8UyXca +ZD4UcHxL4i221e9GDVarURbtXDRMivAwivo1GHvIi93J+Ak0meYniJzoBQ7JlPsu +a/kSpK8YGS3UQ0YF+CvErI1b6XkLHefW8qEJTswVk1+LB1jvFBRCzA1bhVRogiaD +J/wtceSgZIhHRE4LAQj/2hCVzUTtV6Zr0GIJGjB7hdF9MHGlTwkPrkjvERlK/PTc +dVjyNbinYGJNA2i701u/atplH2eSBUresMhHu3AZUUXZKfFQ2m07FDBNAtsoYNnO +d17EXDaoQRDVWSP83GN4b/hpmngvHl1fuFBZ1ms375FNPQo/K33QBaUsLsqiIS/v +k3LBkeECgYEAyqv5dkgte9c2mxT5zUQySr1fDms4nwZTth8477jRnOZND1M9VoIv +1EjBfxq3y7gJVd34VWYeCxNBYwK8C45SDXtlU9X2hLeKWU6yfdegyxv950P5AahT +J80YtYSez+mTLPOC42GeTg7l01NXlTHmPpraIkdNniHc8bqyAEK9w+kCgYEAxuuO +Ln84GkAm1gr6gyFkOMVwVEfszKjRGIqp4BnSwM9bFgWvhyj4jpr+bpe4gQKQQE5q +E/GoxYOtdZ3yYupd2Ki0irGhhm3u0ywgmbomurOw46AInONWcHTU6kZY/dd8wfvW +8YcmFq/LNupwFOEw18mKaQXygMnUYci+uOSw0Y8CgYEAkcX0XjE4FdUL/6usqQme +KsfesR5J0YfZeism5rXGftXfI2C5w5lMEaJrGqL7A9pRTKOlVLdocIrfAvoaiy1I +s03H6e8Bqx/gsK+8DmujybNOgqMPXTPW68/HL/g9ykm0hCZ6RFYYaQiqIb/WRQdp +FiqHLxSeLVkp8+xWz30xxNECgYAA7P23Z64qKRxFKL3ruE8QGJMiQUdv2GVIuPR7 +b4NUlGJ3IsWjWmR1vXDrsNcR+qITOoox15ESgj9facHEBhUzue1FK/h1eLOA1ha8 +wGoHumhbVtZTbJdtZI3NHVCytbsF6Bci/p8FwgGvGr40yquAhZaYUIfFY6sSXW3N +zHqqLwKBgQCUGrePDhjjUZZNQya0TQZ95HL8OQB2e9bx8RwypYdC3pAZ6uDfl+Ne +IZoA8EoDHVbsxDXmLTGil/kyvmYBnzvkVz/yMyFm/7I0zXEOr8bTgqE5wJ8BMGSp +yil5jDoN28KL6D+HsDsWUEOvvHieDYP3cxfpZWiQuWIZ6gfDDVjIwQ== +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-client.crt b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.crt new file mode 100644 index 0000000000..c9d43ce662 --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIBADANBgkqhkiG9w0BAQsFADAvMRowGAYDVQQKDBFCb2d1 +cyBDb3Jwb3JhdGlvbjERMA8GA1UEAwwIQm9ndXMgQ0EwIBcNMTUwMTMwMTczNTI0 +WhgPMjExNTAxMDYxNzM1MjRaMDMxGjAYBgNVBAoMEUJvZ3VzIENvcnBvcmF0aW9u +MRUwEwYDVQQDDAxCb2d1cyBDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDa28y3b2qcrFTjr3GIgjx78qlbRZomBt/A//ZW5qx00+QXT30bu8F0 +jCfHaBTDSnabP86856C/kL1d6oRtc7jmaxNoj39uRh3NcV3VmFEiLI9XmJ0gOIBN +vMQ0voi4gvRBzjFMnVOFML8FePV4OUX1QUZK4eAvZCsDhaJv1cCEERsfcttv7X31 +CT3+a3geZsb0cMDqicq/uaX2IONhqoNYwGlmgF+bWICIxJmEnaK3e/LnKKpvvfTt +n2M0Fx0W4150HSZxQ9Iz6fQQ8oLNn3qNL5i9377XKpck2uxC39yt5WXK2d5m8xBF +5+qwMMqlEW4LoE/dTU9mJ1lZLwV7m7QJAgMBAAGjIDAeMAkGA1UdEwQCMAAwEQYJ +YIZIAYb4QgEBBAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQBBeGwXbU/WRLkfxDoI +Js2nPqzpfEXAcrJhurHKlm/wMIHnHHhTM69O7yTl/VUdKIXPzC1bGkAiSBQo+51B +SJkyWo3vt47g8rqAnUs4oM+bPD2t1YkJVeGLu+Nfw5SHlc+HdojdAcpKtnCbqtrd +vnV4QyB70nxKXC3jmWVBu/jeim0RzUacO+lF9vRPqwnlDINopx8ZpEjaXxABtaQA +cVUosFGEPRjOYAbw9j4fK7J7EXh/124j81OfawkfaMMDt2EedmSdlhPy+Io7VaBo +ho+39cX/oO3Ek+C9v+4aGF7rgp3VyKOGtC5rIy+YiwjcI09pRVPuqEqXC6C4nQcS +SjjF +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-client.key b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.key new file mode 100644 index 0000000000..f676af73d4 --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA2tvMt29qnKxU469xiII8e/KpW0WaJgbfwP/2VuasdNPkF099 +G7vBdIwnx2gUw0p2mz/OvOegv5C9XeqEbXO45msTaI9/bkYdzXFd1ZhRIiyPV5id +IDiATbzENL6IuIL0Qc4xTJ1ThTC/BXj1eDlF9UFGSuHgL2QrA4Wib9XAhBEbH3Lb +b+199Qk9/mt4HmbG9HDA6onKv7ml9iDjYaqDWMBpZoBfm1iAiMSZhJ2it3vy5yiq +b7307Z9jNBcdFuNedB0mcUPSM+n0EPKCzZ96jS+Yvd++1yqXJNrsQt/creVlytne +ZvMQRefqsDDKpRFuC6BP3U1PZidZWS8Fe5u0CQIDAQABAoIBAQDOzZlA0CgWiYTh +bLvEOQQ8Pw0msLs7KY2vCm7UqL3W2w4RtMvMM/tWTMWd2EyeSLOQeZe5ysmLmpJF +tz+RSSMzn4REbiwEoH6yzWfUWEx6FU8Rf6UheCJM0o04Jb59U0jJEbRl59eu6GPo +IOcaxkvDtv1b7tnvDiDTACiAsqNqZhs54QlqwpadSYe4QgK9KH0WxqBzLpXr8eEq +ZV1uuuNpaf+mitVaJhXHyVt7Od1yPfohbTYaXjko3xt3BcStt4tzRZkGQk2kjMWd +d53wqcFlc+zxSW9/ogLr+TCDttTEa1oV+JLpXLkV5J0/saf/LYw96r6f98XhLrd1 +5otsbQ+dAoGBAP0nCzd6otnuUsLX+dz0ed61zDzyTVBXLxuOOvDpuPItVUKPI8yZ +mwveIm97/4u50HGSWUgLR5v+ABfMVG/DqkEP50dDbIhQ2uBhkR5xVgSlZSiZ7S03 +1AErADaeViphKjfAuHraGgC6SRv8HBZadbYW+ZQRVTF6IRJmstiLNJIDAoGBAN1S +AYtYhH0tJSQxyL+sdeuPGhY5RDdlSeLRAStpoGjmaOC4Rc8uDsts2xuInkCcTW2y +nogoR5YxFvcly3vGL5kOzLuscLbueqkz/rbTlZPruqL7fMyPI7Y3YgGER5XNwPpE ++DlW1fu2aE42WUU49mkUNaT2WBtOLnbZKShAWKoDAoGAOGZfeF/JMnaHV8OYdmK9 +WCH2u8lb8j9KToBUn2HjA4mYCjkrx6SdR3qY/2+H0pB2YScy3vssXBOt3591XGUi +ZFZvt4/M+V3SNdVm6HplqKlUrUQF9GIQyKXU6VZDajO1nTBBqZU339ug+Cwl8dD7 +krLxrcxix6AnCBt7UwVIlBMCgYEAydQADogxgknKJiC0Vn86pg9BFeUxXWckIxDA +hUt0+lSsbcn993qkCUUC5zAGSRuAzLnoMnixF7k6nTW9Q+mu/GBvufH+dAQ0ndsJ +vMZlEJkXAYxf+dfLFF+bI5DzCxywkEqXJwsWZs6ofjK35BWXOKoyZXY1UOlSHBXb +n5ZWhOsCgYBRLqEjUehkZfqjZj8VClyPQ/6bAgtfjMRqpgsLgvqG9gBraDs4DXJr +K8Ac3+vCP8rqVwIUC0iu/5MFX75WJ7Go7wbAg7m91P9tmzSiLEm5H1toXJpla6nv +oLZW+jN9O1BaVow8f2qIEJMjHnDbuZnMPQlMGUD+g2tNgczfxT3MOA== +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-server.crt b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.crt new file mode 100644 index 0000000000..7e59f6128d --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQsFADAvMRowGAYDVQQKDBFCb2d1 +cyBDb3Jwb3JhdGlvbjERMA8GA1UEAwwIQm9ndXMgQ0EwIBcNMTUwMTMxMTc0MjI3 +WhgPMjExNTAxMDcxNzQyMjdaMDMxGjAYBgNVBAoMEUJvZ3VzIENvcnBvcmF0aW9u +MRUwEwYDVQQDDAxCb2d1cyBTZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCv899JQxy/mpaQzscopmoKOkgbmwGwty1KiTpT09MU1+gtMHCfhmVp +nAiNIlQlDa+5mjhvyy1fSf+mgdjnvT5pdUAro633gfCv318EViwYsvA7/0ZumFqU +UyPWw4/2of/ZfJv2ewzMLoYEDKiLcXxInBsMlt5Lr7IBS8SNitDU+TAM7HLEIkMz +c0JpxY09H707tO8G3e93yfB5l8H+JdeEdPe+7PDfnsZZuMmaImiNYRByPTTuGvrN +I9I+OxcE4ZOMMNb3mzAoEFnyfHiCO2ehHl58y0a49ayAKJdP/FV3n2LtL/Zc5Ilq +b3VJgaShevrfIiItURjOAjDA9B95hYuZAgMBAAGjIDAeMAkGA1UdEwQCMAAwEQYJ +YIZIAYb4QgEBBAQDAgZAMA0GCSqGSIb3DQEBCwUAA4IBAQBhTqwD3HxamZGopq0K +r8KUdtliiPwo4GBFp0zg6VdSxo01WfpwFGOaeKNmV0JadtJ1DhcsdIUv2OvrxiWQ +1n0IGHULeazQnst1q1t/Vlup3IggKTGCLi8yd3acY8tr2wj9lGjWhsR+BcrCUTEB +BCpIsQiFA8+PTf/8SHuzMokDBP+j02fWCqwR749H4NDQgqrFsgzxLDA69XgvkNM3 ++HOsOR/QxeYIp54mqPnsNVhzV0JbpQpF4j9R5kMI/bsPmWH6W0GbSSyA07o8iVw7 +eqPbwHnIlHXzafvaGmF0QituAzU0nPgMc9OMxuoqacBSmSvmSdMmh///vr7O2KHO +7s+g +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-server.key b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.key new file mode 100644 index 0000000000..bda8dae678 --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAr/PfSUMcv5qWkM7HKKZqCjpIG5sBsLctSok6U9PTFNfoLTBw +n4ZlaZwIjSJUJQ2vuZo4b8stX0n/poHY570+aXVAK6Ot94Hwr99fBFYsGLLwO/9G +bphalFMj1sOP9qH/2Xyb9nsMzC6GBAyoi3F8SJwbDJbeS6+yAUvEjYrQ1PkwDOxy +xCJDM3NCacWNPR+9O7TvBt3vd8nweZfB/iXXhHT3vuzw357GWbjJmiJojWEQcj00 +7hr6zSPSPjsXBOGTjDDW95swKBBZ8nx4gjtnoR5efMtGuPWsgCiXT/xVd59i7S/2 +XOSJam91SYGkoXr63yIiLVEYzgIwwPQfeYWLmQIDAQABAoIBAHVRJJLjpZp3h2a8 +CHypIND69TM60hCywgcNoo9cEES4hL0ErEMhSCL3f5giyHoAOyeElZasoO8FFuk9 +cJNrUd7c59FxDECYKhQJ2n+4uSQqwxUt6xc4jESTfrTmpemrMD0h4ZehifHmH0M5 +8XMwUs7TDxIA0e0jE4vbqg05/m3RMHoeJ4W5K4dMxkJbjmyjjCr8aT8WP/KSTABS +YQPql0rs6WL5Q2s1I/i3I4qIS4CKk8Ym7O5/Wk1fxbCh2ABL2PhW8PZDzvsFYo2T +cwX0cc0EILBc3tOG11Iua6mK8y9Zz1BpUT02ZvGaPf9R6vI0Shk1yWbZ0NYLx0MH +Zu8HIYECgYEA5awzjNcnDYQY9f6C/0TNj54Z8I7UFmGJX7XhPVVMceNieUiLvrsH +Zmf4Q51PLM1iz0S2qGA/c7lngHDXwFe++MANIK7KNwL2LtPF/83mYgBUxBKJaNHD +4B/6CCitjSwAfMNBnE70zg0F9chqy+9p+fTEwUFW6Y4y9U5jO4kw5HECgYEAxB8+ +YYMUGeIt9TnMKrC2YK/o8jo+5ZEOpEIPwleeAIUMujVVonu3TX2nKos2MgaZg/F0 +OpvDlcQZqb4Em73ctf3ZgBYEs9tt2qdB5qGlg4Hs2wyfgKUPQGLX2RseUQCYsOWT +cPPKvYDTZ6yhW6gGBd5ufl5tnG93CsIpcNV1DakCgYEAwByZhi6V4Q1k36eDpcjE +dWRW6ExghVQS17dIb8hAyGbeAPs4wVKqbvN6y/vytVQbWapta0wO51rng51gKuh6 +upHSqUrrpLZafHLyBPYSxljmjpe+zqnfwUKeH2L/QL3UroeZAwlcZlqoaJ27D1j0 ++XrPdaOU8onagCyQfsVT21ECgYAafW3blezdIiO6/7eH/J5lqNz5+swMDe/AV/vw +8AyzXUU+0X1jmPpFSTePE4aaczHBFJfyYp+kVvxwZO4Say6olkUOe+resEDCS90m +3aaRgLcRTz8sDR9mPvOQq40Iu9/j5N5pX0R/HCtx0WtqCePmXwjloLOFcbjOhzM5 +vls1IQKBgEF8DEk8T4ycjwBXC3U7Duj9jPL815417BAHdGstLP1yNcI05ubN2T56 +ITbf625YS7OdtYfrf1/jBnUVXsJspsQqkOUB97M224CVWI+vJiv8jPX+KCnR7/Zh +A/7OrtZ6FCzLyBeu/2p1NHAttqSUqu9t6wCeeBcelnAUcrjfLmlw +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index a355cfeb17..c3b7cb1250 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Governikus GmbH & Co. KG. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -31,7 +32,7 @@ ** ****************************************************************************/ - +#include <QtCore/qglobal.h> #include <QtCore/qthread.h> #include <QtNetwork/qhostaddress.h> #include <QtNetwork/qhostinfo.h> @@ -41,27 +42,42 @@ #include <QtNetwork/qsslkey.h> #include <QtNetwork/qsslsocket.h> #include <QtNetwork/qtcpserver.h> +#include <QtNetwork/qsslpresharedkeyauthenticator.h> #include <QtTest/QtTest> #include <QNetworkProxy> #include <QAuthenticator> #include "private/qhostinfo_p.h" +#include "private/qiodevice_p.h" // for QIODEVICE_BUFFERSIZE + +#include "../../../network-settings.h" + #ifndef QT_NO_SSL +#ifndef QT_NO_OPENSSL #include "private/qsslsocket_openssl_p.h" #include "private/qsslsocket_openssl_symbols_p.h" -#include "private/qsslconfiguration_p.h" #endif +#include "private/qsslsocket_p.h" +#include "private/qsslconfiguration_p.h" -#include "../../../network-settings.h" - -#ifndef QT_NO_SSL Q_DECLARE_METATYPE(QSslSocket::SslMode) typedef QList<QSslError::SslError> SslErrorList; Q_DECLARE_METATYPE(SslErrorList) Q_DECLARE_METATYPE(QSslError) +Q_DECLARE_METATYPE(QSslKey) Q_DECLARE_METATYPE(QSsl::SslProtocol) +Q_DECLARE_METATYPE(QSslSocket::PeerVerifyMode); +typedef QSharedPointer<QSslSocket> QSslSocketPtr; + +// Non-OpenSSL backends are not able to report a specific error code +// for self-signed certificate for certificates. +#ifndef QT_NO_OPENSSL +#define FLUKE_CERTIFICATE_ERROR QSslError::SelfSignedCertificate +#else +#define FLUKE_CERTIFICATE_ERROR QSslError::CertificateUntrusted #endif +#endif // QT_NO_SSL #if defined Q_OS_HPUX && defined Q_CC_GNU // This error is delivered every time we try to use the fluke CA @@ -69,9 +85,14 @@ Q_DECLARE_METATYPE(QSsl::SslProtocol) #define QSSLSOCKET_CERTUNTRUSTED_WORKAROUND #endif -#ifndef QT_NO_SSL -typedef QSharedPointer<QSslSocket> QSslSocketPtr; -#endif +// Use this cipher to force PSK key sharing. +// Also, it's a cipher w/o auth, to check that we emit the signals warning +// about the identity of the peer. +static const QString PSK_CIPHER_WITHOUT_AUTH = QStringLiteral("PSK-AES256-CBC-SHA"); +static const quint16 PSK_SERVER_PORT = 4433; +static const QByteArray PSK_CLIENT_PRESHAREDKEY = QByteArrayLiteral("\x1a\x2b\x3c\x4d\x5e\x6f"); +static const QByteArray PSK_SERVER_IDENTITY_HINT = QByteArrayLiteral("QtTestServerHint"); +static const QByteArray PSK_CLIENT_IDENTITY = QByteArrayLiteral("Client_identity"); class tst_QSslSocket : public QObject { @@ -96,6 +117,19 @@ public: #ifndef QT_NO_SSL QSslSocketPtr newSocket(); + +#ifndef QT_NO_OPENSSL + enum PskConnectTestType { + PskConnectDoNotHandlePsk, + PskConnectEmptyCredentials, + PskConnectWrongCredentials, + PskConnectWrongIdentity, + PskConnectWrongPreSharedKey, + PskConnectRightCredentialsPeerVerifyFailure, + PskConnectRightCredentialsVerifyPeer, + PskConnectRightCredentialsDoNotVerifyPeer, + }; +#endif #endif public slots: @@ -168,7 +202,6 @@ private slots: void waitForMinusOne(); void verifyMode(); void verifyDepth(); - void peerVerifyError(); void disconnectFromHostWhenConnecting(); void disconnectFromHostWhenConnected(); void resetProxy(); @@ -190,8 +223,15 @@ private slots: void qtbug18498_peek2(); void dhServer(); void ecdhServer(); + void verifyClientCertificate_data(); + void verifyClientCertificate(); void setEmptyDefaultConfiguration(); // this test should be last +#ifndef QT_NO_OPENSSL + void simplePskConnect_data(); + void simplePskConnect(); +#endif + static void exitLoop() { // Safe exit - if we aren't in an event loop, don't @@ -224,6 +264,12 @@ private: static int loopLevel; }; +#ifndef QT_NO_SSL +#ifndef QT_NO_OPENSSL +Q_DECLARE_METATYPE(tst_QSslSocket::PskConnectTestType) +#endif +#endif + int tst_QSslSocket::loopLevel = 0; tst_QSslSocket::tst_QSslSocket() @@ -233,6 +279,11 @@ tst_QSslSocket::tst_QSslSocket() qRegisterMetaType<QSslError>("QSslError"); qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState"); qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); + +#ifndef QT_NO_OPENSSL + qRegisterMetaType<QSslPreSharedKeyAuthenticator *>(); + qRegisterMetaType<tst_QSslSocket::PskConnectTestType>(); +#endif #endif } @@ -546,37 +597,53 @@ void tst_QSslSocket::sslErrors_data() { QTest::addColumn<QString>("host"); QTest::addColumn<int>("port"); - QTest::addColumn<SslErrorList>("expected"); - QTest::newRow(qPrintable(QtNetworkSettings::serverLocalName())) - << QtNetworkSettings::serverLocalName() - << 993 - << (SslErrorList() << QSslError::HostNameMismatch - << QSslError::SelfSignedCertificate); + QString name = QtNetworkSettings::serverLocalName(); + QTest::newRow(qPrintable(name)) << name << 993; + + name = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); + QTest::newRow(qPrintable(name)) << name << 443; } void tst_QSslSocket::sslErrors() { QFETCH(QString, host); QFETCH(int, port); - QFETCH(SslErrorList, expected); QSslSocketPtr socket = newSocket(); + QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList<QSslError>))); + QSignalSpy peerVerifyErrorSpy(socket.data(), SIGNAL(peerVerifyError(QSslError))); + socket->connectToHostEncrypted(host, port); if (!socket->waitForConnected()) - QEXPECT_FAIL("imap.trolltech.com", "server not open to internet", Continue); - socket->waitForEncrypted(5000); + QSKIP("Skipping flaky test - See QTBUG-29941"); + socket->waitForEncrypted(10000); - SslErrorList output; - foreach (QSslError error, socket->sslErrors()) { - output << error.error(); - } + // check the SSL errors contain HostNameMismatch and an error due to + // the certificate being self-signed + SslErrorList sslErrors; + foreach (const QSslError &err, socket->sslErrors()) + sslErrors << err.error(); + qSort(sslErrors); + QVERIFY(sslErrors.contains(QSslError::HostNameMismatch)); + QVERIFY(sslErrors.contains(FLUKE_CERTIFICATE_ERROR)); -#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND - if (output.count() && output.last() == QSslError::CertificateUntrusted) - output.takeLast(); -#endif - QCOMPARE(output, expected); + // check the same errors were emitted by sslErrors + QVERIFY(!sslErrorsSpy.isEmpty()); + SslErrorList emittedErrors; + foreach (const QSslError &err, qvariant_cast<QList<QSslError> >(sslErrorsSpy.first().first())) + emittedErrors << err.error(); + qSort(emittedErrors); + QCOMPARE(sslErrors, emittedErrors); + + // check the same errors were emitted by peerVerifyError + QVERIFY(!peerVerifyErrorSpy.isEmpty()); + SslErrorList peerErrors; + const QList<QVariantList> &peerVerifyList = peerVerifyErrorSpy; + foreach (const QVariantList &args, peerVerifyList) + peerErrors << qvariant_cast<QSslError>(args.first()).error(); + qSort(peerErrors); + QCOMPARE(sslErrors, peerErrors); } void tst_QSslSocket::addCaCertificate() @@ -929,7 +996,7 @@ void tst_QSslSocket::protocol() socket->abort(); } #endif -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) { // qt-test-server allows SSLV2. socket->setProtocol(QSsl::SslV2); @@ -996,12 +1063,17 @@ public: const QString &certFile = SRCDIR "certs/fluke.cert", const QString &interFile = QString()) : socket(0), + ignoreSslErrors(true), + peerVerifyMode(QSslSocket::AutoVerifyPeer), protocol(QSsl::TlsV1_0), m_keyFile(keyFile), m_certFile(certFile), m_interFile(interFile) { } QSslSocket *socket; + QString addCaCertificates; + bool ignoreSslErrors; + QSslSocket::PeerVerifyMode peerVerifyMode; QSsl::SslProtocol protocol; QString m_keyFile; QString m_certFile; @@ -1012,8 +1084,10 @@ protected: void incomingConnection(qintptr socketDescriptor) { socket = new QSslSocket(this); + socket->setPeerVerifyMode(peerVerifyMode); socket->setProtocol(protocol); - connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); + if (ignoreSslErrors) + connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); QFile file(m_keyFile); QVERIFY(file.open(QIODevice::ReadOnly)); @@ -1021,6 +1095,14 @@ protected: QVERIFY(!key.isNull()); socket->setPrivateKey(key); + // Add CA certificates to verify client certificate + if (!addCaCertificates.isEmpty()) { + QList<QSslCertificate> caCert = QSslCertificate::fromPath(addCaCertificates); + QVERIFY(!caCert.isEmpty()); + QVERIFY(!caCert.first().isNull()); + socket->addCaCertificates(caCert); + } + // If we have a cert issued directly from the CA if (m_interFile.isEmpty()) { QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile); @@ -1066,7 +1148,7 @@ void tst_QSslSocket::protocolServerSide_data() QTest::addColumn<QSsl::SslProtocol>("clientProtocol"); QTest::addColumn<bool>("works"); -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 #endif QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true; @@ -1075,7 +1157,7 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true; QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true; -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false; QTest::newRow("ssl2-tls1.0") << QSsl::SslV2 << QSsl::TlsV1_0 << false; QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false; @@ -1083,33 +1165,33 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2 #endif -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false; #endif QTest::newRow("ssl3-tls1.0") << QSsl::SslV3 << QSsl::TlsV1_0 << false; QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true; QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << false; -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a // numerical IP, so OpenSSL will send a SSL 2 handshake #else QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << true; #endif -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("tls1.0-ssl2") << QSsl::TlsV1_0 << QSsl::SslV2 << false; #endif QTest::newRow("tls1.0-ssl3") << QSsl::TlsV1_0 << QSsl::SslV3 << false; QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1_0 << QSsl::TlsV1SslV3 << true; QTest::newRow("tls1.0-secure") << QSsl::TlsV1_0 << QSsl::SecureProtocols << true; -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a // numerical IP, so OpenSSL will send a SSL 2 handshake #else QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << true; #endif -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false; #endif QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true; @@ -1117,7 +1199,7 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true; QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true; -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false; #endif QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << false; @@ -1125,7 +1207,7 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true; QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true; -#ifndef OPENSSL_NO_SSL2 +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 #endif QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true; @@ -1950,7 +2032,7 @@ void tst_QSslSocket::verifyMode() QSKIP("Skipping flaky test - See QTBUG-29941"); QList<QSslError> expectedErrors = QList<QSslError>() - << QSslError(QSslError::SelfSignedCertificate, socket.peerCertificate()); + << QSslError(FLUKE_CERTIFICATE_ERROR, socket.peerCertificate()); QCOMPARE(socket.sslErrors(), expectedErrors); socket.abort(); @@ -1981,34 +2063,6 @@ void tst_QSslSocket::verifyDepth() QCOMPARE(socket.peerVerifyDepth(), 1); } -void tst_QSslSocket::peerVerifyError() -{ - QSslSocketPtr socket = newSocket(); - QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList<QSslError>))); - QSignalSpy peerVerifyErrorSpy(socket.data(), SIGNAL(peerVerifyError(QSslError))); - - socket->connectToHostEncrypted(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 443); - if (socket->waitForEncrypted(10000)) - QSKIP("Skipping flaky test - See QTBUG-29941"); - - // check HostNameMismatch was emitted by peerVerifyError - QVERIFY(!peerVerifyErrorSpy.isEmpty()); - SslErrorList peerErrors; - const QList<QVariantList> &peerVerifyList = peerVerifyErrorSpy; - foreach (const QVariantList &args, peerVerifyList) - peerErrors << qvariant_cast<QSslError>(args.first()).error(); - QVERIFY(peerErrors.contains(QSslError::HostNameMismatch)); - - // check HostNameMismatch was emitted by sslErrors - QVERIFY(!sslErrorsSpy.isEmpty()); - SslErrorList sslErrors; - foreach (const QSslError &err, qvariant_cast<QList<QSslError> >(sslErrorsSpy.first().first())) - sslErrors << err.error(); - QVERIFY(peerErrors.contains(QSslError::HostNameMismatch)); - - QCOMPARE(sslErrors.size(), peerErrors.size()); -} - void tst_QSslSocket::disconnectFromHostWhenConnecting() { QSslSocketPtr socket = newSocket(); @@ -2105,8 +2159,8 @@ void tst_QSslSocket::ignoreSslErrorsList_data() QList<QSslError> expectedSslErrors; // fromPath gives us a list of certs, but it actually only contains one QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")); - QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0)); - QSslError wrongError(QSslError::SelfSignedCertificate); + QSslError rightError(FLUKE_CERTIFICATE_ERROR, certs.at(0)); + QSslError wrongError(FLUKE_CERTIFICATE_ERROR); QTest::newRow("SSL-failure-empty-list") << expectedSslErrors << 1; @@ -2368,8 +2422,8 @@ void tst_QSslSocket::resume_data() QTest::newRow("ignoreAllErrors") << true << QList<QSslError>() << true; QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")); - QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0)); - QSslError wrongError(QSslError::SelfSignedCertificate); + QSslError rightError(FLUKE_CERTIFICATE_ERROR, certs.at(0)); + QSslError wrongError(FLUKE_CERTIFICATE_ERROR); errorsList.append(wrongError); QTest::newRow("ignoreSpecificErrors-Wrong") << true << errorsList << false; errorsList.clear(); @@ -2747,6 +2801,132 @@ void tst_QSslSocket::ecdhServer() QVERIFY(client->state() == QAbstractSocket::ConnectedState); } +void tst_QSslSocket::verifyClientCertificate_data() +{ + QTest::addColumn<QSslSocket::PeerVerifyMode>("peerVerifyMode"); + QTest::addColumn<QList<QSslCertificate> >("clientCerts"); + QTest::addColumn<QSslKey>("clientKey"); + QTest::addColumn<bool>("works"); + + // no certificate + QList<QSslCertificate> noCerts; + QSslKey noKey; + + QTest::newRow("NoCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << noCerts << noKey << true; + QTest::newRow("NoCert:QueryPeer") << QSslSocket::QueryPeer << noCerts << noKey << true; + QTest::newRow("NoCert:VerifyNone") << QSslSocket::VerifyNone << noCerts << noKey << true; + QTest::newRow("NoCert:VerifyPeer") << QSslSocket::VerifyPeer << noCerts << noKey << false; + + // self-signed certificate + QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); + QCOMPARE(flukeCerts.size(), 1); + + QFile flukeFile(SRCDIR "certs/fluke.key"); + QVERIFY(flukeFile.open(QIODevice::ReadOnly)); + QSslKey flukeKey(flukeFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + QVERIFY(!flukeKey.isNull()); + + QTest::newRow("SelfSignedCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << flukeCerts << flukeKey << true; + QTest::newRow("SelfSignedCert:QueryPeer") << QSslSocket::QueryPeer << flukeCerts << flukeKey << true; + QTest::newRow("SelfSignedCert:VerifyNone") << QSslSocket::VerifyNone << flukeCerts << flukeKey << true; + QTest::newRow("SelfSignedCert:VerifyPeer") << QSslSocket::VerifyPeer << flukeCerts << flukeKey << false; + + // valid certificate, but wrong usage (server certificate) + QList<QSslCertificate> serverCerts = QSslCertificate::fromPath(SRCDIR "certs/bogus-server.crt"); + QCOMPARE(serverCerts.size(), 1); + + QFile serverFile(SRCDIR "certs/bogus-server.key"); + QVERIFY(serverFile.open(QIODevice::ReadOnly)); + QSslKey serverKey(serverFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + QVERIFY(!serverKey.isNull()); + + QTest::newRow("ValidServerCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << serverCerts << serverKey << true; + QTest::newRow("ValidServerCert:QueryPeer") << QSslSocket::QueryPeer << serverCerts << serverKey << true; + QTest::newRow("ValidServerCert:VerifyNone") << QSslSocket::VerifyNone << serverCerts << serverKey << true; + QTest::newRow("ValidServerCert:VerifyPeer") << QSslSocket::VerifyPeer << serverCerts << serverKey << false; + + // valid certificate, correct usage (client certificate) + QList<QSslCertificate> validCerts = QSslCertificate::fromPath(SRCDIR "certs/bogus-client.crt"); + QCOMPARE(validCerts.size(), 1); + + QFile validFile(SRCDIR "certs/bogus-client.key"); + QVERIFY(validFile.open(QIODevice::ReadOnly)); + QSslKey validKey(validFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + QVERIFY(!validKey.isNull()); + + QTest::newRow("ValidClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:QueryPeer") << QSslSocket::QueryPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyNone") << QSslSocket::VerifyNone << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true; + + // valid certificate, correct usage (client certificate), with chain + validCerts += QSslCertificate::fromPath(SRCDIR "certs/bogus-ca.crt"); + QCOMPARE(validCerts.size(), 2); + + QTest::newRow("ValidClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:QueryPeer") << QSslSocket::QueryPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyNone") << QSslSocket::VerifyNone << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true; +} + +void tst_QSslSocket::verifyClientCertificate() +{ + if (!QSslSocket::supportsSsl()) { + qWarning("SSL not supported, skipping test"); + return; + } + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QFETCH(QSslSocket::PeerVerifyMode, peerVerifyMode); + SslServer server; + server.addCaCertificates = QLatin1String(SRCDIR "certs/bogus-ca.crt"); + server.ignoreSslErrors = false; + server.peerVerifyMode = peerVerifyMode; + QVERIFY(server.listen()); + + QEventLoop loop; + QTimer::singleShot(5000, &loop, SLOT(quit())); + + QFETCH(QList<QSslCertificate>, clientCerts); + QFETCH(QSslKey, clientKey); + QSslSocketPtr client(new QSslSocket); + client->setLocalCertificateChain(clientCerts); + client->setPrivateKey(clientKey); + socket = client.data(); + + connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); + connect(socket, SIGNAL(disconnected()), &loop, SLOT(quit())); + connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit())); + + client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); + + loop.exec(); + + QFETCH(bool, works); + QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState; + + // check server socket + QVERIFY(server.socket); + + QCOMPARE(int(server.socket->state()), int(expectedState)); + QCOMPARE(server.socket->isEncrypted(), works); + + if (peerVerifyMode == QSslSocket::VerifyNone || clientCerts.isEmpty()) { + QVERIFY(server.socket->peerCertificate().isNull()); + QVERIFY(server.socket->peerCertificateChain().isEmpty()); + } else { + QCOMPARE(server.socket->peerCertificate(), clientCerts.first()); + QCOMPARE(server.socket->peerCertificateChain(), clientCerts); + } + + // check client socket + QCOMPARE(int(client->state()), int(expectedState)); + QCOMPARE(client->isEncrypted(), works); +} + void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, as it has some side effects { // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265 @@ -2757,14 +2937,330 @@ void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, QSslConfiguration emptyConf; QSslConfiguration::setDefaultConfiguration(emptyConf); - QSslSocketPtr socket = newSocket(); - connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); + QSslSocketPtr client = newSocket(); + socket = client.data(); + + connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); QFETCH_GLOBAL(bool, setProxy); if (setProxy && socket->waitForEncrypted(4000)) QSKIP("Skipping flaky test - See QTBUG-29941"); } +#ifndef QT_NO_OPENSSL +class PskProvider : public QObject +{ + Q_OBJECT + +public: + explicit PskProvider(QObject *parent = 0) + : QObject(parent) + { + } + + void setIdentity(const QByteArray &identity) + { + m_identity = identity; + } + + void setPreSharedKey(const QByteArray &psk) + { + m_psk = psk; + } + +public slots: + void providePsk(QSslPreSharedKeyAuthenticator *authenticator) + { + QVERIFY(authenticator); + QCOMPARE(authenticator->identityHint(), PSK_SERVER_IDENTITY_HINT); + QVERIFY(authenticator->maximumIdentityLength() > 0); + QVERIFY(authenticator->maximumPreSharedKeyLength() > 0); + + if (!m_identity.isEmpty()) { + authenticator->setIdentity(m_identity); + QCOMPARE(authenticator->identity(), m_identity); + } + + if (!m_psk.isEmpty()) { + authenticator->setPreSharedKey(m_psk); + QCOMPARE(authenticator->preSharedKey(), m_psk); + } + } + +private: + QByteArray m_identity; + QByteArray m_psk; +}; + +void tst_QSslSocket::simplePskConnect_data() +{ + QTest::addColumn<PskConnectTestType>("pskTestType"); + QTest::newRow("PskConnectDoNotHandlePsk") << PskConnectDoNotHandlePsk; + QTest::newRow("PskConnectEmptyCredentials") << PskConnectEmptyCredentials; + QTest::newRow("PskConnectWrongCredentials") << PskConnectWrongCredentials; + QTest::newRow("PskConnectWrongIdentity") << PskConnectWrongIdentity; + QTest::newRow("PskConnectWrongPreSharedKey") << PskConnectWrongPreSharedKey; + QTest::newRow("PskConnectRightCredentialsPeerVerifyFailure") << PskConnectRightCredentialsPeerVerifyFailure; + QTest::newRow("PskConnectRightCredentialsVerifyPeer") << PskConnectRightCredentialsVerifyPeer; + QTest::newRow("PskConnectRightCredentialsDoNotVerifyPeer") << PskConnectRightCredentialsDoNotVerifyPeer; +} + +void tst_QSslSocket::simplePskConnect() +{ + QFETCH(PskConnectTestType, pskTestType); + QSKIP("This test requires change 1f8cab2c3bcd91335684c95afa95ae71e00a94e4 on the network test server, QTQAINFRA-917"); + + if (!QSslSocket::supportsSsl()) + QSKIP("No SSL support"); + + bool pskCipherFound = false; + const QList<QSslCipher> supportedCiphers = QSslSocket::supportedCiphers(); + foreach (const QSslCipher &cipher, supportedCiphers) { + if (cipher.name() == PSK_CIPHER_WITHOUT_AUTH) { + pskCipherFound = true; + break; + } + } + + if (!pskCipherFound) + QSKIP("SSL implementation does not support the necessary PSK cipher(s)"); + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + QSKIP("This test must not be going through a proxy"); + + QSslSocket socket; + this->socket = &socket; + + QSignalSpy connectedSpy(&socket, SIGNAL(connected())); + QVERIFY(connectedSpy.isValid()); + + QSignalSpy hostFoundSpy(&socket, SIGNAL(hostFound())); + QVERIFY(hostFoundSpy.isValid()); + + QSignalSpy disconnectedSpy(&socket, SIGNAL(disconnected())); + QVERIFY(disconnectedSpy.isValid()); + + QSignalSpy connectionEncryptedSpy(&socket, SIGNAL(encrypted())); + QVERIFY(connectionEncryptedSpy.isValid()); + + QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(QList<QSslError>))); + QVERIFY(sslErrorsSpy.isValid()); + + QSignalSpy socketErrorsSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError))); + QVERIFY(socketErrorsSpy.isValid()); + + QSignalSpy peerVerifyErrorSpy(&socket, SIGNAL(peerVerifyError(QSslError))); + QVERIFY(peerVerifyErrorSpy.isValid()); + + QSignalSpy pskAuthenticationRequiredSpy(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*))); + QVERIFY(pskAuthenticationRequiredSpy.isValid()); + + connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop())); + connect(&socket, SIGNAL(disconnected()), this, SLOT(exitLoop())); + connect(&socket, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(exitLoop())); + connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop())); + connect(&socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(exitLoop())); + connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(exitLoop())); + connect(&socket, SIGNAL(peerVerifyError(QSslError)), this, SLOT(exitLoop())); + connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(exitLoop())); + + // force a PSK cipher w/o auth + socket.setCiphers(PSK_CIPHER_WITHOUT_AUTH); + + PskProvider provider; + + switch (pskTestType) { + case PskConnectDoNotHandlePsk: + // don't connect to the provider + break; + + case PskConnectEmptyCredentials: + // connect to the psk provider, but don't actually provide any PSK nor identity + connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*))); + break; + + case PskConnectWrongCredentials: + // provide totally wrong credentials + provider.setIdentity(PSK_CLIENT_IDENTITY.left(PSK_CLIENT_IDENTITY.length() - 1)); + provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY.left(PSK_CLIENT_PRESHAREDKEY.length() - 1)); + connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*))); + break; + + case PskConnectWrongIdentity: + // right PSK, wrong identity + provider.setIdentity(PSK_CLIENT_IDENTITY.left(PSK_CLIENT_IDENTITY.length() - 1)); + provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY); + connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*))); + break; + + case PskConnectWrongPreSharedKey: + // right identity, wrong PSK + provider.setIdentity(PSK_CLIENT_IDENTITY); + provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY.left(PSK_CLIENT_PRESHAREDKEY.length() - 1)); + connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*))); + break; + + case PskConnectRightCredentialsPeerVerifyFailure: + // right identity, right PSK, but since we can't verify the other peer, we'll fail + provider.setIdentity(PSK_CLIENT_IDENTITY); + provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY); + connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*))); + break; + + case PskConnectRightCredentialsVerifyPeer: + // right identity, right PSK, verify the peer (but ignore the failure) and establish the connection + provider.setIdentity(PSK_CLIENT_IDENTITY); + provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY); + connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*))); + connect(&socket, SIGNAL(peerVerifyError(QSslError)), this, SLOT(ignoreErrorSlot())); + break; + + case PskConnectRightCredentialsDoNotVerifyPeer: + // right identity, right PSK, do not verify the peer and establish the connection + provider.setIdentity(PSK_CLIENT_IDENTITY); + provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY); + connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*))); + socket.setPeerVerifyMode(QSslSocket::VerifyNone); + break; + } + + // check the peer verification mode + switch (pskTestType) { + case PskConnectDoNotHandlePsk: + case PskConnectEmptyCredentials: + case PskConnectWrongCredentials: + case PskConnectWrongIdentity: + case PskConnectWrongPreSharedKey: + case PskConnectRightCredentialsPeerVerifyFailure: + case PskConnectRightCredentialsVerifyPeer: + QCOMPARE(socket.peerVerifyMode(), QSslSocket::AutoVerifyPeer); + break; + + case PskConnectRightCredentialsDoNotVerifyPeer: + QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyNone); + break; + } + + // Start connecting + socket.connectToHost(QtNetworkSettings::serverName(), PSK_SERVER_PORT); + QCOMPARE(socket.state(), QAbstractSocket::HostLookupState); + enterLoop(10); + + // Entered connecting state + QCOMPARE(socket.state(), QAbstractSocket::ConnectingState); + QCOMPARE(connectedSpy.count(), 0); + QCOMPARE(hostFoundSpy.count(), 1); + QCOMPARE(disconnectedSpy.count(), 0); + enterLoop(10); + + // Entered connected state + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode); + QVERIFY(!socket.isEncrypted()); + QCOMPARE(connectedSpy.count(), 1); + QCOMPARE(hostFoundSpy.count(), 1); + QCOMPARE(disconnectedSpy.count(), 0); + + // Enter encrypted mode + socket.startClientEncryption(); + QCOMPARE(socket.mode(), QSslSocket::SslClientMode); + QVERIFY(!socket.isEncrypted()); + QCOMPARE(connectionEncryptedSpy.count(), 0); + QCOMPARE(sslErrorsSpy.count(), 0); + QCOMPARE(peerVerifyErrorSpy.count(), 0); + + // Start handshake. + enterLoop(10); + + // We must get the PSK signal in all cases + QCOMPARE(pskAuthenticationRequiredSpy.count(), 1); + + switch (pskTestType) { + case PskConnectDoNotHandlePsk: + case PskConnectEmptyCredentials: + case PskConnectWrongCredentials: + case PskConnectWrongIdentity: + case PskConnectWrongPreSharedKey: + // Handshake failure + QCOMPARE(socketErrorsSpy.count(), 1); + QCOMPARE(qvariant_cast<QAbstractSocket::SocketError>(socketErrorsSpy.at(0).at(0)), QAbstractSocket::SslHandshakeFailedError); + QCOMPARE(sslErrorsSpy.count(), 0); + QCOMPARE(peerVerifyErrorSpy.count(), 0); + QCOMPARE(connectionEncryptedSpy.count(), 0); + QVERIFY(!socket.isEncrypted()); + break; + + case PskConnectRightCredentialsPeerVerifyFailure: + // Peer verification failure + QCOMPARE(socketErrorsSpy.count(), 1); + QCOMPARE(qvariant_cast<QAbstractSocket::SocketError>(socketErrorsSpy.at(0).at(0)), QAbstractSocket::SslHandshakeFailedError); + QCOMPARE(sslErrorsSpy.count(), 1); + QCOMPARE(peerVerifyErrorSpy.count(), 1); + QCOMPARE(connectionEncryptedSpy.count(), 0); + QVERIFY(!socket.isEncrypted()); + break; + + case PskConnectRightCredentialsVerifyPeer: + // Peer verification failure, but ignore it and keep connecting + QCOMPARE(socketErrorsSpy.count(), 0); + QCOMPARE(sslErrorsSpy.count(), 1); + QCOMPARE(peerVerifyErrorSpy.count(), 1); + QCOMPARE(connectionEncryptedSpy.count(), 1); + QVERIFY(socket.isEncrypted()); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + break; + + case PskConnectRightCredentialsDoNotVerifyPeer: + // No peer verification => no failure + QCOMPARE(socketErrorsSpy.count(), 0); + QCOMPARE(sslErrorsSpy.count(), 0); + QCOMPARE(peerVerifyErrorSpy.count(), 0); + QCOMPARE(connectionEncryptedSpy.count(), 1); + QVERIFY(socket.isEncrypted()); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + break; + } + + // check writing + switch (pskTestType) { + case PskConnectDoNotHandlePsk: + case PskConnectEmptyCredentials: + case PskConnectWrongCredentials: + case PskConnectWrongIdentity: + case PskConnectWrongPreSharedKey: + case PskConnectRightCredentialsPeerVerifyFailure: + break; + + case PskConnectRightCredentialsVerifyPeer: + case PskConnectRightCredentialsDoNotVerifyPeer: + socket.write("Hello from Qt TLS/PSK!"); + QVERIFY(socket.waitForBytesWritten()); + break; + } + + // disconnect + switch (pskTestType) { + case PskConnectDoNotHandlePsk: + case PskConnectEmptyCredentials: + case PskConnectWrongCredentials: + case PskConnectWrongIdentity: + case PskConnectWrongPreSharedKey: + case PskConnectRightCredentialsPeerVerifyFailure: + break; + + case PskConnectRightCredentialsVerifyPeer: + case PskConnectRightCredentialsDoNotVerifyPeer: + socket.disconnectFromHost(); + enterLoop(10); + break; + } + + QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState); + QCOMPARE(disconnectedSpy.count(), 1); +} +#endif // QT_NO_OPENSSL + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslSocket) diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp index 1a65d5f9f3..137b9f160f 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp @@ -227,6 +227,7 @@ void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMe bool works; #if defined (Q_OS_WIN) works = false; // on Windows, this won't work even though we use on demand loading + Q_UNUSED(rootCertLoadingAllowed) #else works = rootCertLoadingAllowed; #endif diff --git a/tests/auto/network/ssl/ssl.pro b/tests/auto/network/ssl/ssl.pro index 4e30a9cded..25d79ebfe8 100644 --- a/tests/auto/network/ssl/ssl.pro +++ b/tests/auto/network/ssl/ssl.pro @@ -2,10 +2,11 @@ TEMPLATE=subdirs SUBDIRS=\ qsslcertificate \ qsslcipher \ + qsslellipticcurve \ qsslerror \ qsslkey \ -contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) { +contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) { contains(QT_CONFIG, private_tests) { SUBDIRS += \ qsslsocket \ diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp index 7a10c00e1f..7dab6687c8 100644 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp @@ -728,7 +728,7 @@ void tst_QGLThreads::painterOnPixmapInThread() if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL) || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) QSKIP("No platformsupport for ThreadedOpenGL or ThreadedPixmaps"); -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 QSKIP("Drawing text in threads onto X11 drawables currently crashes on some X11 servers."); #endif PaintThreadManager<PixmapWrapper> painterThreads(5); diff --git a/tests/auto/other/android/android.pro b/tests/auto/other/android/android.pro new file mode 100644 index 0000000000..60faf8050e --- /dev/null +++ b/tests/auto/other/android/android.pro @@ -0,0 +1,11 @@ +CONFIG += testcase +TARGET = tst_android +QT = core testlib + +SOURCES += \ + tst_android.cpp + +ANDROID_PACKAGE_SOURCE_DIR = $$PWD/testdata + +DISTFILES += \ + testdata/assets/test.txt diff --git a/tests/auto/other/android/testdata/assets/test.txt b/tests/auto/other/android/testdata/assets/test.txt new file mode 100644 index 0000000000..61e2c47c25 --- /dev/null +++ b/tests/auto/other/android/testdata/assets/test.txt @@ -0,0 +1 @@ +FooBar
\ No newline at end of file diff --git a/tests/auto/other/android/tst_android.cpp b/tests/auto/other/android/tst_android.cpp new file mode 100644 index 0000000000..245382ded3 --- /dev/null +++ b/tests/auto/other/android/tst_android.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +class tst_Android : public QObject +{ +Q_OBJECT +private slots: + void assetsRead(); + void assetsNotWritable(); +}; + +void tst_Android::assetsRead() +{ + { + QFile file("assets:/test.txt"); + QVERIFY(file.open(QIODevice::ReadOnly)); + QCOMPARE(file.readAll(), QByteArray("FooBar")); + } + + { + QFile file("assets:/test.txt"); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + QCOMPARE(file.readAll(), QByteArray("FooBar")); + } +} + +void tst_Android::assetsNotWritable() +{ + QFile file("assets:/test.txt"); + QVERIFY(!file.open(QIODevice::WriteOnly)); + QVERIFY(!file.open(QIODevice::ReadWrite)); + QVERIFY(!file.open(QIODevice::Append)); +} + +QTEST_MAIN(tst_Android) +#include "tst_android.moc" + diff --git a/tests/auto/other/lancelot/paintcommands.cpp b/tests/auto/other/lancelot/paintcommands.cpp index 76a309a7ec..c0034153d3 100644 --- a/tests/auto/other/lancelot/paintcommands.cpp +++ b/tests/auto/other/lancelot/paintcommands.cpp @@ -2385,7 +2385,7 @@ void PaintCommands::command_surface_begin(QRegExp re) m_painter = new QPainter(m_surface_glpaintdevice); m_painter->fillRect(QRect(0, 0, qRound(w), qRound(h)), Qt::transparent); #endif -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 } else if (m_type == WidgetType) { m_surface_pixmap = QPixmap(qRound(w), qRound(h)); m_surface_pixmap.fill(Qt::transparent); @@ -2436,7 +2436,7 @@ void PaintCommands::command_surface_end(QRegExp) m_painter->beginNativePainting(); m_painter->endNativePainting(); #endif -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 } else if (m_type == WidgetType) { m_painter->drawPixmap(m_surface_rect.topLeft(), m_surface_pixmap); m_surface_pixmap = QPixmap(); diff --git a/tests/auto/other/languagechange/tst_languagechange.cpp b/tests/auto/other/languagechange/tst_languagechange.cpp index 7b71231382..caf000a418 100644 --- a/tests/auto/other/languagechange/tst_languagechange.cpp +++ b/tests/auto/other/languagechange/tst_languagechange.cpp @@ -243,7 +243,7 @@ void tst_languageChange::retranslatability() QSKIP("The input data are not suitable for this layout (QDialogButtonBox::GnomeLayout)"); // This will always be queried for when a language changes - expected.insert("QCoreApplication::QT_LAYOUT_DIRECTION::Translate this string to the string 'LTR' in left-to-right " + expected.insert("QGuiApplication::QT_LAYOUT_DIRECTION::Translate this string to the string 'LTR' in left-to-right " "languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to " "get proper widget layout."); diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index bd3997f8c9..c5673727be 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -24,6 +24,7 @@ SUBDIRS=\ qprocess_and_guieventloop \ qtokenautomaton \ windowsmobile \ + toolsupport \ !qtHaveModule(widgets): SUBDIRS -= \ baselineexample \ @@ -70,3 +71,6 @@ wince*|!contains(QT_CONFIG, accessibility): SUBDIRS -= qaccessibility winrt: SUBDIRS -= \ qprocess_and_guieventloop + +android: SUBDIRS += \ + android diff --git a/tests/auto/other/qaccessibility/qaccessibility.pro b/tests/auto/other/qaccessibility/qaccessibility.pro index 8d445437df..70cced1dac 100644 --- a/tests/auto/other/qaccessibility/qaccessibility.pro +++ b/tests/auto/other/qaccessibility/qaccessibility.pro @@ -5,7 +5,7 @@ QT += testlib core-private gui-private widgets-private SOURCES += tst_qaccessibility.cpp HEADERS += accessiblewidgets.h -unix:!mac:LIBS+=-lm +unix:!mac:!haiku:LIBS+=-lm wince*: { accessneeded.files = $$QT_BUILD_TREE\\plugins\\accessible\\*.dll diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index e59509a944..19462b5342 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -41,13 +41,7 @@ # include <servprov.h> # include <winuser.h> # ifdef QT_SUPPORTS_IACCESSIBLE2 -# include <Accessible2.h> -# include <AccessibleAction.h> -# include <AccessibleComponent.h> -# include <AccessibleEditableText.h> -# include <AccessibleText.h> -# include <AccessibleTable2.h> -# include <AccessibleTableCell.h> +# include <ia2_api_all.h> # endif #endif #include <QtTest/QtTest> diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm index a0dfe5446e..4c57e4d42a 100644 --- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm +++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm @@ -80,11 +80,13 @@ bool trusted() { AXUIElementRef reference; NSString *_role; + NSString *_title; NSString *_description; NSString *_value; CGRect _rect; } @property (readonly) NSString *role; + @property (readonly) NSString *title; @property (readonly) NSString *description; @property (readonly) NSString *value; @property (readonly) CGRect rect; @@ -93,6 +95,7 @@ bool trusted() @implementation TestAXObject @synthesize role = _role; + @synthesize title = _title; @synthesize description = _description; @synthesize value = _value; @synthesize rect = _rect; @@ -102,6 +105,7 @@ bool trusted() if ( self = [super init] ) { reference = ref; AXUIElementCopyAttributeValue(ref, kAXRoleAttribute, (CFTypeRef*)&_role); + AXUIElementCopyAttributeValue(ref, kAXTitleAttribute, (CFTypeRef*)&_title); AXUIElementCopyAttributeValue(ref, kAXDescriptionAttribute, (CFTypeRef*)&_description); AXUIElementCopyAttributeValue(ref, kAXValueAttribute, (CFTypeRef*)&_value); AXValueRef sizeValue; @@ -116,7 +120,7 @@ bool trusted() - (AXUIElementRef) ref { return reference; } - (void) print { - NSLog(@"Accessible Object role: '%@', description: '%@', value: '%@', rect: '%@'", self.role, self.description, self.value, NSStringFromRect(self.rect)); + NSLog(@"Accessible Object role: '%@', title: '%@', description: '%@', value: '%@', rect: '%@'", self.role, self.title, self.description, self.value, NSStringFromRect(self.rect)); NSLog(@" Children: %ld", [[self childList] count]); } @@ -282,7 +286,7 @@ bool testHierarchy(QWidget *w) TestAXObject *focusButton2 = [[TestAXObject alloc] initWithAXUIElementRef: focussedElement]; EXPECT([[focusButton2 role] isEqualToString: NSAccessibilityButtonRole]); - EXPECT([[focusButton2 description] isEqualToString: @"Button 2"]); + EXPECT([[focusButton2 title] isEqualToString: @"Button 2"]); button1->setFocus(); @@ -292,7 +296,7 @@ bool testHierarchy(QWidget *w) EXPECT(focussedElement); TestAXObject *focusButton1 = [[TestAXObject alloc] initWithAXUIElementRef: focussedElement]; EXPECT([[focusButton1 role] isEqualToString: NSAccessibilityButtonRole]); - EXPECT([[focusButton1 description] isEqualToString: @"I am a button"]); + EXPECT([[focusButton1 title] isEqualToString: @"I am a button"]); return true; } diff --git a/tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp b/tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp index bddffc2c6a..352968729e 100644 --- a/tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp +++ b/tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp @@ -33,7 +33,7 @@ #include <stdio.h> -int main(int argc, char **argv) +int main(int, char **argv) { const char *msg = argv[1]; char buf[2]; diff --git a/tests/auto/other/toolsupport/toolsupport.pro b/tests/auto/other/toolsupport/toolsupport.pro new file mode 100644 index 0000000000..274ead2c35 --- /dev/null +++ b/tests/auto/other/toolsupport/toolsupport.pro @@ -0,0 +1,4 @@ +CONFIG += testcase parallel_test +TARGET = tst_toolsupport +QT = testlib core-private +SOURCES = $$PWD/tst_toolsupport.cpp diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp new file mode 100644 index 0000000000..0785033621 --- /dev/null +++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include <QtTest> + +// Don't do this at home. This is test code, not production. +#define protected public +#define private public + +#include <private/qdatetime_p.h> +#include <private/qfile_p.h> +#include <private/qfileinfo_p.h> +#include <private/qobject_p.h> +#include <qobject.h> + +#if defined(Q_CC_GNU) || defined(Q_CC_MSVC) +#define RUN_MEMBER_OFFSET_TEST 1 +#else +#define RUN_MEMBER_OFFSET_TEST 0 +#endif + +#if RUN_MEMBER_OFFSET_TEST +template <typename T, typename K> +size_t pmm_to_offsetof(T K:: *pmm) +{ +#ifdef Q_CC_MSVC + // Even on 64 bit MSVC uses 4 byte offsets. + quint32 ret; +#else + size_t ret; +#endif + Q_STATIC_ASSERT(sizeof(ret) == sizeof(pmm)); + memcpy(&ret, &pmm, sizeof(ret)); + return ret; +} +#endif + +class tst_toolsupport : public QObject +{ + Q_OBJECT + +private slots: + void offsets(); + void offsets_data(); +}; + +void tst_toolsupport::offsets() +{ + QFETCH(size_t, actual); + QFETCH(int, expected32); + QFETCH(int, expected64); + size_t expect = sizeof(void *) == 4 ? expected32 : expected64; + QCOMPARE(actual, expect); +} + +void tst_toolsupport::offsets_data() +{ + QTest::addColumn<size_t>("actual"); + QTest::addColumn<int>("expected32"); + QTest::addColumn<int>("expected64"); + + { + QTestData &data = QTest::newRow("sizeof(QObjectData)") + << sizeof(QObjectData); + data << 28 << 48; // vptr + 3 ptr + 2 int + ptr + } + +#if RUN_MEMBER_OFFSET_TEST + { + QTestData &data = QTest::newRow("QObjectPrivate::extraData") + << pmm_to_offsetof(&QObjectPrivate::extraData); + data << 28 << 48; // sizeof(QObjectData) + } + + { + QTestData &data = QTest::newRow("QFileInfoPrivate::fileEntry") + << pmm_to_offsetof(&QFileInfoPrivate::fileEntry); + data << 4 << 8; + } + + { + QTestData &data = QTest::newRow("QFileSystemEntry::filePath") + << pmm_to_offsetof(&QFileSystemEntry::m_filePath); + data << 0 << 0; + } + +#ifdef Q_OS_LINUX + if (sizeof(void *) == 8) { + QTestData &data = QTest::newRow("QFilePrivate::fileName") + << pmm_to_offsetof(&QFilePrivate::fileName); + data << -1 << 248; + } +#endif + + { +#ifdef Q_OS_WIN + QTest::newRow("QDateTimePrivate::m_msecs") + << pmm_to_offsetof(&QDateTimePrivate::m_msecs) << 8 << 8; + QTest::newRow("QDateTimePrivate::m_spec") + << pmm_to_offsetof(&QDateTimePrivate::m_spec) << 16 << 16; + QTest::newRow("QDateTimePrivate::m_offsetFromUtc") + << pmm_to_offsetof(&QDateTimePrivate::m_offsetFromUtc) << 20 << 20; + QTest::newRow("QDateTimePrivate::m_timeZone") + << pmm_to_offsetof(&QDateTimePrivate::m_timeZone) << 24 << 24; + QTest::newRow("QDateTimePrivate::m_status") + << pmm_to_offsetof(&QDateTimePrivate::m_status) << 28 << 32; +#else + QTest::newRow("QDateTimePrivate::m_msecs") + << pmm_to_offsetof(&QDateTimePrivate::m_msecs) << 4 << 8; + QTest::newRow("QDateTimePrivate::m_spec") + << pmm_to_offsetof(&QDateTimePrivate::m_spec) << 12 << 16; + QTest::newRow("QDateTimePrivate::m_offsetFromUtc") + << pmm_to_offsetof(&QDateTimePrivate::m_offsetFromUtc) << 16 << 20; + QTest::newRow("QDateTimePrivate::m_timeZone") + << pmm_to_offsetof(&QDateTimePrivate::m_timeZone) << 20 << 24; + QTest::newRow("QDateTimePrivate::m_status") + << pmm_to_offsetof(&QDateTimePrivate::m_status) << 24 << 32; +#endif + } +#endif // RUN_MEMBER_OFFSET_TEST +} + + +QTEST_APPLESS_MAIN(tst_toolsupport); + +#include "tst_toolsupport.moc" + diff --git a/tests/auto/testlib/selftests/expected_badxml.lightxml b/tests/auto/testlib/selftests/expected_badxml.lightxml index 94f479a79a..e0de44f0be 100644 --- a/tests/auto/testlib/selftests/expected_badxml.lightxml +++ b/tests/auto/testlib/selftests/expected_badxml.lightxml @@ -113,7 +113,7 @@ </TestFunction> <TestFunction name="encoding"> <Message type="qdebug" file="" line="0"> - <Description><![CDATA["Ülrich Ümläut"]]></Description> + <Description><![CDATA["\u00DClrich \u00DCml\u00E4ut"]]></Description> </Message> <Incident type="pass" file="" line="0" /> <Duration msecs="0"/> diff --git a/tests/auto/testlib/selftests/expected_badxml.xml b/tests/auto/testlib/selftests/expected_badxml.xml index c1266bfeed..8667c2d9cd 100644 --- a/tests/auto/testlib/selftests/expected_badxml.xml +++ b/tests/auto/testlib/selftests/expected_badxml.xml @@ -115,7 +115,7 @@ </TestFunction> <TestFunction name="encoding"> <Message type="qdebug" file="" line="0"> - <Description><![CDATA["Ülrich Ümläut"]]></Description> + <Description><![CDATA["\u00DClrich \u00DCml\u00E4ut"]]></Description> </Message> <Incident type="pass" file="" line="0" /> <Duration msecs="0"/> diff --git a/tests/auto/testlib/selftests/expected_badxml.xunitxml b/tests/auto/testlib/selftests/expected_badxml.xunitxml index 49048fdad6..46f4be4391 100644 --- a/tests/auto/testlib/selftests/expected_badxml.xunitxml +++ b/tests/auto/testlib/selftests/expected_badxml.xunitxml @@ -30,7 +30,7 @@ <failure message="failure message" result="fail"/> </testcase> <testcase result="pass" name="encoding"> - <!-- message=""Ülrich Ümläut"" type="qdebug" --> + <!-- message=""\u00DClrich \u00DCml\u00E4ut"" type="qdebug" --> </testcase> <testcase result="pass" name="cleanupTestCase"/> <system-err> @@ -46,6 +46,6 @@ <![CDATA[quotes " text" more text]]> <![CDATA[xml close > open < tags < text]]> <![CDATA[all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]> -<![CDATA["Ülrich Ümläut"]]> +<![CDATA["\u00DClrich \u00DCml\u00E4ut"]]> </system-err> </testsuite> diff --git a/tests/auto/testlib/selftests/expected_warnings.lightxml b/tests/auto/testlib/selftests/expected_warnings.lightxml index 31b3d842aa..afbbf5b5e2 100644 --- a/tests/auto/testlib/selftests/expected_warnings.lightxml +++ b/tests/auto/testlib/selftests/expected_warnings.lightxml @@ -20,6 +20,12 @@ <Message type="qdebug" file="" line="0"> <Description><![CDATA[Debug]]></Description> </Message> +<Message type="qinfo" file="" line="0"> + <Description><![CDATA[Info]]></Description> +</Message> +<Message type="qinfo" file="" line="0"> + <Description><![CDATA[Info]]></Description> +</Message> <Message type="qdebug" file="" line="0"> <Description><![CDATA[Baba]]></Description> </Message> diff --git a/tests/auto/testlib/selftests/expected_warnings.txt b/tests/auto/testlib/selftests/expected_warnings.txt index bb77257b79..9f7393e90f 100644 --- a/tests/auto/testlib/selftests/expected_warnings.txt +++ b/tests/auto/testlib/selftests/expected_warnings.txt @@ -5,6 +5,8 @@ QWARN : tst_Warnings::testWarnings() Warning QWARN : tst_Warnings::testWarnings() Warning QDEBUG : tst_Warnings::testWarnings() Debug QDEBUG : tst_Warnings::testWarnings() Debug +QINFO : tst_Warnings::testWarnings() Info +QINFO : tst_Warnings::testWarnings() Info QDEBUG : tst_Warnings::testWarnings() Baba QDEBUG : tst_Warnings::testWarnings() Baba QDEBUG : tst_Warnings::testWarnings() Bubublabla diff --git a/tests/auto/testlib/selftests/expected_warnings.xml b/tests/auto/testlib/selftests/expected_warnings.xml index a3821f84df..7023e35e0c 100644 --- a/tests/auto/testlib/selftests/expected_warnings.xml +++ b/tests/auto/testlib/selftests/expected_warnings.xml @@ -22,6 +22,12 @@ <Message type="qdebug" file="" line="0"> <Description><![CDATA[Debug]]></Description> </Message> +<Message type="qinfo" file="" line="0"> + <Description><![CDATA[Info]]></Description> +</Message> +<Message type="qinfo" file="" line="0"> + <Description><![CDATA[Info]]></Description> +</Message> <Message type="qdebug" file="" line="0"> <Description><![CDATA[Baba]]></Description> </Message> diff --git a/tests/auto/testlib/selftests/expected_warnings.xunitxml b/tests/auto/testlib/selftests/expected_warnings.xunitxml index 7ea66522c6..5cca215f12 100644 --- a/tests/auto/testlib/selftests/expected_warnings.xunitxml +++ b/tests/auto/testlib/selftests/expected_warnings.xunitxml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<testsuite errors="15" failures="4" tests="6" name="tst_Warnings"> +<testsuite errors="17" failures="4" tests="6" name="tst_Warnings"> <properties> <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/> <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/> @@ -11,6 +11,8 @@ <!-- message="Warning" type="qwarn" --> <!-- message="Debug" type="qdebug" --> <!-- message="Debug" type="qdebug" --> + <!-- message="Info" type="qinfo" --> + <!-- message="Info" type="qinfo" --> <!-- message="Baba" type="qdebug" --> <!-- message="Baba" type="qdebug" --> <!-- message="Bubublabla" type="qdebug" --> @@ -39,6 +41,8 @@ <![CDATA[Warning]]> <![CDATA[Debug]]> <![CDATA[Debug]]> +<![CDATA[Info]]> +<![CDATA[Info]]> <![CDATA[Baba]]> <![CDATA[Baba]]> <![CDATA[Bubublabla]]> diff --git a/tests/auto/testlib/selftests/silent/tst_silent.cpp b/tests/auto/testlib/selftests/silent/tst_silent.cpp index 545f7d3420..335411e466 100644 --- a/tests/auto/testlib/selftests/silent/tst_silent.cpp +++ b/tests/auto/testlib/selftests/silent/tst_silent.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -83,6 +83,7 @@ void tst_Silent::messages() QWARN("This is an internal testlib warning that should not appear in silent test output"); qDebug("This is a debug message that should not appear in silent test output"); qCritical("This is a critical message that should not appear in silent test output"); + qInfo("This is an info message that should not appear in silent test output"); QTestLog::info("This is an internal testlib info message that should not appear in silent test output", __FILE__, __LINE__); qFatal("This is a fatal error message that should still appear in silent test output"); } diff --git a/tests/auto/testlib/selftests/warnings/tst_warnings.cpp b/tests/auto/testlib/selftests/warnings/tst_warnings.cpp index b000f37687..9266b83934 100644 --- a/tests/auto/testlib/selftests/warnings/tst_warnings.cpp +++ b/tests/auto/testlib/selftests/warnings/tst_warnings.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -63,6 +63,13 @@ void tst_Warnings::testWarnings() qDebug("Debug"); + qInfo("Info"); + + QTest::ignoreMessage(QtInfoMsg, "Info"); + qInfo("Info"); + + qInfo("Info"); + QTest::ignoreMessage(QtDebugMsg, "Bubu"); qDebug("Baba"); qDebug("Bubu"); diff --git a/tests/auto/tools/moc/cstyle-enums.h b/tests/auto/tools/moc/cstyle-enums.h index a930fa1117..ce89878e97 100644 --- a/tests/auto/tools/moc/cstyle-enums.h +++ b/tests/auto/tools/moc/cstyle-enums.h @@ -39,8 +39,10 @@ class CStyleEnums { Q_GADGET public: - Q_ENUMS(Baz) typedef enum { Foo, Bar } Baz; + typedef enum { Foo2, Bar2 } Baz2; + Q_ENUM(Baz) + Q_ENUMS(Baz2) }; #endif // CSTYLE_ENUMS_H diff --git a/tests/auto/tools/moc/cxx11-enums.h b/tests/auto/tools/moc/cxx11-enums.h index 21d17d0039..32acb25515 100644 --- a/tests/auto/tools/moc/cxx11-enums.h +++ b/tests/auto/tools/moc/cxx11-enums.h @@ -40,11 +40,26 @@ class CXX11Enums { Q_GADGET public: - Q_ENUMS(EnumClass TypedEnum TypedEnumClass NormalEnum) enum class EnumClass { A0, A1, A2, A3 }; enum TypedEnum : char { B0, B1 , B2, B3 }; enum class TypedEnumClass : char { C0, C1, C2, C3 }; enum NormalEnum { D2 = 2, D3, D0 =0 , D1 }; + Q_ENUM(EnumClass) + Q_ENUM(TypedEnum) + Q_ENUM(TypedEnumClass) + Q_ENUM(NormalEnum) +}; + +// Also test the Q_ENUMS macro +class CXX11Enums2 +{ + Q_GADGET +public: + enum class EnumClass { A0, A1, A2, A3 }; + enum TypedEnum : char { B0, B1 , B2, B3 }; + enum class TypedEnumClass : char { C0, C1, C2, C3 }; + enum NormalEnum { D2 = 2, D3, D0 =0 , D1 }; + Q_ENUMS(EnumClass TypedEnum TypedEnumClass NormalEnum) }; #else @@ -58,5 +73,10 @@ public: enum NormalEnum { D2 = 2, D3, D0 =0 , D1 }; enum TypedEnum { B0, B1 , B2, B3 }; }; + +class CXX11Enums2 : public CXX11Enums +{ + Q_GADGET +}; #endif #endif // CXX11_ENUMS_H diff --git a/tests/auto/tools/moc/gadgetwithnoenums.h b/tests/auto/tools/moc/gadgetwithnoenums.h index a19b970ab9..6a515862de 100644 --- a/tests/auto/tools/moc/gadgetwithnoenums.h +++ b/tests/auto/tools/moc/gadgetwithnoenums.h @@ -47,10 +47,10 @@ public: class DerivedGadgetWithEnums : public GadgetWithNoEnums { Q_GADGET - Q_ENUMS( FooEnum ) public: enum FooEnum { FooValue }; + Q_ENUM( FooEnum ) DerivedGadgetWithEnums() {} ~DerivedGadgetWithEnums() {} }; diff --git a/tests/auto/tools/moc/grand-parent-gadget-class.h b/tests/auto/tools/moc/grand-parent-gadget-class.h new file mode 100644 index 0000000000..b589e55b27 --- /dev/null +++ b/tests/auto/tools/moc/grand-parent-gadget-class.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GRANDPARENTGADGETCLASS_H +#define GRANDPARENTGADGETCLASS_H + +#include <QtCore/qobjectdefs.h> + +namespace GrandParentGadget { + +struct BaseGadget { Q_GADGET }; +struct Derived : BaseGadget {}; +struct DerivedGadget : Derived { Q_GADGET }; + +} + +#endif // GRANDPARENTGADGETCLASS_H + diff --git a/tests/auto/tools/moc/moc.pro b/tests/auto/tools/moc/moc.pro index cc8c2c671d..99e226c5f4 100644 --- a/tests/auto/tools/moc/moc.pro +++ b/tests/auto/tools/moc/moc.pro @@ -27,6 +27,7 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n single-quote-digit-separator-n3781.h \ related-metaobjects-in-namespaces.h \ qtbug-35657-gadget.h \ + non-gadget-parent-class.h grand-parent-gadget-class.h \ related-metaobjects-in-gadget.h \ related-metaobjects-name-conflict.h diff --git a/tests/auto/tools/moc/namespaced-flags.h b/tests/auto/tools/moc/namespaced-flags.h index 2b63ed0ae1..9448176218 100644 --- a/tests/auto/tools/moc/namespaced-flags.h +++ b/tests/auto/tools/moc/namespaced-flags.h @@ -38,13 +38,14 @@ namespace Foo { class Bar : public QObject { Q_OBJECT - Q_FLAGS( Flags ) Q_PROPERTY( Flags flags READ flags WRITE setFlags ) public: explicit Bar( QObject * parent=0 ) : QObject( parent ), mFlags() {} enum Flag { Read=1, Write=2 }; Q_DECLARE_FLAGS( Flags, Flag ) + Q_FLAG(Flags) + void setFlags( Flags f ) { mFlags = f; } Flags flags() const { return mFlags; } diff --git a/tests/auto/tools/moc/non-gadget-parent-class.h b/tests/auto/tools/moc/non-gadget-parent-class.h new file mode 100644 index 0000000000..9e2158d170 --- /dev/null +++ b/tests/auto/tools/moc/non-gadget-parent-class.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NONGADGETPARENTCLASS_H +#define NONGADGETPARENTCLASS_H + +#include <QtCore/qobjectdefs.h> + +namespace NonGadgetParent { + +struct Base {}; +struct Derived : Base { Q_GADGET }; + +} + +#endif // NONGADGETPARENTCLASS_H + diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index edb6488eaa..740b6ba814 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -72,6 +72,12 @@ #include "related-metaobjects-in-gadget.h" #include "related-metaobjects-name-conflict.h" +#include "non-gadget-parent-class.h" +#include "grand-parent-gadget-class.h" + +Q_DECLARE_METATYPE(const QMetaObject*); + + QT_USE_NAMESPACE template <bool b> struct QTBUG_31218 {}; @@ -415,7 +421,7 @@ public: enum TestEnum { One, Two, Three }; - Q_ENUMS(TestEnum) + Q_ENUM(TestEnum) }; class PropertyUseClass : public QObject @@ -434,7 +440,7 @@ class EnumSourceClass : public QObject public: enum TestEnum { Value = 37 }; - Q_ENUMS(TestEnum) + Q_ENUM(TestEnum) }; class EnumUserClass : public QObject @@ -572,6 +578,9 @@ private slots: void relatedMetaObjectsInGadget(); void relatedMetaObjectsNameConflict_data(); void relatedMetaObjectsNameConflict(); + void strignLiteralsInMacroExtension(); + void veryLongStringData(); + void gadgetHierarchy(); signals: void sigWithUnsignedArg(unsigned foo); @@ -594,6 +603,7 @@ private: void setMember3( const QString &sVal ) { sMember = sVal; } private: + QString m_moc; QString m_sourceDirectory; QString qtIncludePath; class PrivateClass; @@ -604,12 +614,16 @@ private: void tst_Moc::initTestCase() { + QString binpath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QString qmake = QString("%1/qmake").arg(binpath); + m_moc = QString("%1/moc").arg(binpath); + const QString testHeader = QFINDTESTDATA("backslash-newlines.h"); QVERIFY(!testHeader.isEmpty()); m_sourceDirectory = QFileInfo(testHeader).absolutePath(); #if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS) QProcess proc; - proc.start("qmake", QStringList() << "-query" << "QT_INSTALL_HEADERS"); + proc.start(qmake, QStringList() << "-query" << "QT_INSTALL_HEADERS"); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray output = proc.readAllStandardOutput(); @@ -653,7 +667,7 @@ void tst_Moc::oldStyleCasts() #endif #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; - proc.start("moc", QStringList(m_sourceDirectory + QStringLiteral("/oldstyle-casts.h"))); + proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/oldstyle-casts.h"))); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -684,7 +698,7 @@ void tst_Moc::warnOnExtraSignalSlotQualifiaction() #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; const QString header = m_sourceDirectory + QStringLiteral("/extraqualification.h"); - proc.start("moc", QStringList(header)); + proc.start(m_moc, QStringList(header)); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -723,7 +737,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; proc.setWorkingDirectory(m_sourceDirectory + QStringLiteral("/task71021")); - proc.start("moc", QStringList("../Header")); + proc.start(m_moc, QStringList("../Header")); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -971,7 +985,7 @@ void tst_Moc::warnOnMultipleInheritance() QStringList args; const QString header = m_sourceDirectory + QStringLiteral("/warn-on-multiple-qobject-subclasses.h"); args << "-I" << qtIncludePath + "/QtGui" << header; - proc.start("moc", args); + proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -996,7 +1010,7 @@ void tst_Moc::ignoreOptionClashes() const QString includeDir = m_sourceDirectory + "/Test.framework/Headers"; // given --ignore-option-clashes, -pthread should be ignored, but the -I path should not be. args << "--ignore-option-clashes" << "-pthread" << "-I" << includeDir << "-fno-builtin" << header; - proc.start("moc", args); + proc.start(m_moc, args); bool finished = proc.waitForFinished(); if (!finished) qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error()); @@ -1034,7 +1048,7 @@ void tst_Moc::forgottenQInterface() QStringList args; const QString header = m_sourceDirectory + QStringLiteral("/forgotten-qinterface.h"); args << "-I" << qtIncludePath + "/QtCore" << header; - proc.start("moc", args); + proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -1118,7 +1132,7 @@ void tst_Moc::frameworkSearchPath() ; QProcess proc; - proc.start("moc", args); + proc.start(m_moc, args); bool finished = proc.waitForFinished(); if (!finished) qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error()); @@ -1136,12 +1150,18 @@ void tst_Moc::frameworkSearchPath() void tst_Moc::cstyleEnums() { const QMetaObject &obj = CStyleEnums::staticMetaObject; - QCOMPARE(obj.enumeratorCount(), 1); + QCOMPARE(obj.enumeratorCount(), 2); QMetaEnum metaEnum = obj.enumerator(0); QCOMPARE(metaEnum.name(), "Baz"); QCOMPARE(metaEnum.keyCount(), 2); QCOMPARE(metaEnum.key(0), "Foo"); QCOMPARE(metaEnum.key(1), "Bar"); + + QMetaEnum metaEnum2 = obj.enumerator(1); + QCOMPARE(metaEnum2.name(), "Baz2"); + QCOMPARE(metaEnum2.keyCount(), 2); + QCOMPARE(metaEnum2.key(0), "Foo2"); + QCOMPARE(metaEnum2.key(1), "Bar2"); } void tst_Moc::templateGtGt() @@ -1151,7 +1171,7 @@ void tst_Moc::templateGtGt() #endif #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; - proc.start("moc", QStringList(m_sourceDirectory + QStringLiteral("/template-gtgt.h"))); + proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/template-gtgt.h"))); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -1172,7 +1192,7 @@ void tst_Moc::defineMacroViaCmdline() args << "-DFOO"; args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); - proc.start("moc", args); + proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QCOMPARE(proc.readAllStandardError(), QByteArray()); @@ -1299,13 +1319,13 @@ public: PrivatePropertyTest(QObject *parent = 0) : QObject(parent), mFoo(0), d (new MyDPointer) {} int foo() { return mFoo ; } void setFoo(int value) { mFoo = value; } - MyDPointer *d_func() {return d;} + MyDPointer *d_func() {return d.data();} signals: void blub4Changed(); void blub5Changed(const QString &newBlub); private: int mFoo; - MyDPointer *d; + QScopedPointer<MyDPointer> d; }; @@ -1350,7 +1370,7 @@ void tst_Moc::warnOnPropertyWithoutREAD() #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; const QString header = m_sourceDirectory + QStringLiteral("/warn-on-property-without-read.h"); - proc.start("moc", QStringList(header)); + proc.start(m_moc, QStringList(header)); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -1409,19 +1429,19 @@ void tst_Moc::constructors() QCOMPARE(mo->indexOfConstructor("CtorTestClass2(QObject*)"), -1); QCOMPARE(mo->indexOfConstructor("CtorTestClass(float,float)"), -1); - QObject *o1 = mo->newInstance(); + QScopedPointer<QObject> o1(mo->newInstance()); QVERIFY(o1 != 0); QCOMPARE(o1->parent(), (QObject*)0); - QVERIFY(qobject_cast<CtorTestClass*>(o1) != 0); + QVERIFY(qobject_cast<CtorTestClass*>(o1.data()) != 0); - QObject *o2 = mo->newInstance(Q_ARG(QObject*, o1)); + QObject *o2 = mo->newInstance(Q_ARG(QObject*, o1.data())); QVERIFY(o2 != 0); - QCOMPARE(o2->parent(), o1); + QCOMPARE(o2->parent(), o1.data()); QString str = QString::fromLatin1("hello"); - QObject *o3 = mo->newInstance(Q_ARG(QString, str)); + QScopedPointer<QObject> o3(mo->newInstance(Q_ARG(QString, str))); QVERIFY(o3 != 0); - QCOMPARE(qobject_cast<CtorTestClass*>(o3)->m_str, str); + QCOMPARE(qobject_cast<CtorTestClass*>(o3.data())->m_str, str); { //explicit constructor @@ -1461,7 +1481,7 @@ void tst_Moc::warnOnVirtualSignal() #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; const QString header = m_sourceDirectory + QStringLiteral("/pure-virtual-signals.h"); - proc.start("moc", QStringList(header)); + proc.start(m_moc, QStringList(header)); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -1593,7 +1613,7 @@ void tst_Moc::notifyError() #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; const QString header = m_sourceDirectory + QStringLiteral("/error-on-wrong-notify.h"); - proc.start("moc", QStringList(header)); + proc.start(m_moc, QStringList(header)); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 1); QCOMPARE(proc.exitStatus(), QProcess::NormalExit); @@ -1638,7 +1658,6 @@ class VersionTest : public QObject Q_OBJECT Q_PROPERTY(int prop1 READ foo) Q_PROPERTY(int prop2 READ foo REVISION 2) - Q_ENUMS(TestEnum); public: int foo() const { return 0; } @@ -1647,6 +1666,8 @@ public: Q_INVOKABLE Q_REVISION(4) void method2() {} enum TestEnum { One, Two }; + Q_ENUM(TestEnum); + public slots: void slot1() {} @@ -1671,7 +1692,6 @@ class VersionTestNotify : public QObject Q_OBJECT Q_PROPERTY(int prop1 READ foo NOTIFY fooChanged) Q_PROPERTY(int prop2 READ foo REVISION 2) - Q_ENUMS(TestEnum); public: int foo() const { return 0; } @@ -1680,6 +1700,7 @@ public: Q_INVOKABLE Q_REVISION(4) void method2() {} enum TestEnum { One, Two }; + Q_ENUM(TestEnum); public slots: void slot1() {} @@ -1871,7 +1892,7 @@ void tst_Moc::warnings() env.insert("QT_MESSAGE_PATTERN", "no qDebug or qWarning please"); proc.setProcessEnvironment(env); - proc.start("moc", args); + proc.start(m_moc, args); QVERIFY(proc.waitForStarted()); QCOMPARE(proc.write(input), qint64(input.size())); @@ -1909,19 +1930,26 @@ void tst_Moc::privateClass() void tst_Moc::cxx11Enums_data() { + QTest::addColumn<const QMetaObject *>("meta"); QTest::addColumn<QByteArray>("enumName"); QTest::addColumn<char>("prefix"); - QTest::newRow("EnumClass") << QByteArray("EnumClass") << 'A'; - QTest::newRow("TypedEnum") << QByteArray("TypedEnum") << 'B'; - QTest::newRow("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C'; - QTest::newRow("NormalEnum") << QByteArray("NormalEnum") << 'D'; -} + const QMetaObject *meta1 = &CXX11Enums::staticMetaObject; + const QMetaObject *meta2 = &CXX11Enums2::staticMetaObject; + QTest::newRow("EnumClass") << meta1 << QByteArray("EnumClass") << 'A'; + QTest::newRow("EnumClass 2") << meta2 << QByteArray("EnumClass") << 'A'; + QTest::newRow("TypedEnum") << meta1 << QByteArray("TypedEnum") << 'B'; + QTest::newRow("TypedEnum 2") << meta2 << QByteArray("TypedEnum") << 'B'; + QTest::newRow("TypedEnumClass") << meta1 << QByteArray("TypedEnumClass") << 'C'; + QTest::newRow("TypedEnumClass 2") << meta2 << QByteArray("TypedEnumClass") << 'C'; + QTest::newRow("NormalEnum") << meta1 << QByteArray("NormalEnum") << 'D'; + QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << 'D'; +} void tst_Moc::cxx11Enums() { - const QMetaObject *meta = &CXX11Enums::staticMetaObject; + QFETCH(const QMetaObject *,meta); QCOMPARE(meta->enumeratorOffset(), 0); QFETCH(QByteArray, enumName); @@ -2529,8 +2557,6 @@ void tst_Moc::finalClasses() QCOMPARE(className, expected); } -Q_DECLARE_METATYPE(const QMetaObject*); - void tst_Moc::explicitOverrideControl_data() { QTest::addColumn<const QMetaObject*>("mo"); @@ -3094,7 +3120,7 @@ void tst_Moc::preprocessorOnly() #endif #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; - proc.start("moc", QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/pp-dollar-signs.h")); + proc.start(m_moc, QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/pp-dollar-signs.h")); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); QByteArray mocOut = proc.readAllStandardOutput(); @@ -3115,7 +3141,7 @@ void tst_Moc::unterminatedFunctionMacro() #endif #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; - proc.start("moc", QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/unterminated-function-macro.h")); + proc.start(m_moc, QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/unterminated-function-macro.h")); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 1); QCOMPARE(proc.readAllStandardOutput(), QByteArray()); @@ -3269,6 +3295,119 @@ void tst_Moc::relatedMetaObjectsNameConflict() QCOMPARE(dependency.size(), relatedMetaObjects.size()); } +class StringLiteralsInMacroExtension: public QObject +{ + Q_OBJECT +#define Macro(F) F " " F + Q_CLASSINFO(Macro("String"), Macro("Literal")) +#undef Macro + +#define Macro(F) F + Q_CLASSINFO("String" Macro("!"), "Literal" Macro("!")) + Q_CLASSINFO(Macro("!") "String", Macro("!") "Literal") +#undef Macro + +#define Macro "foo" + Q_CLASSINFO("String" Macro, "Literal" Macro) + Q_CLASSINFO(Macro "String", Macro "Literal") +#undef Macro +}; + +void tst_Moc::strignLiteralsInMacroExtension() +{ + const QMetaObject *mobj = &StringLiteralsInMacroExtension::staticMetaObject; + QCOMPARE(mobj->classInfoCount(), 5); + + QCOMPARE(mobj->classInfo(0).name(), "String String"); + QCOMPARE(mobj->classInfo(0).value(), "Literal Literal"); + + QCOMPARE(mobj->classInfo(1).name(), "String!"); + QCOMPARE(mobj->classInfo(1).value(), "Literal!"); + + QCOMPARE(mobj->classInfo(2).name(), "!String"); + QCOMPARE(mobj->classInfo(2).value(), "!Literal"); + + QCOMPARE(mobj->classInfo(3).name(), "Stringfoo"); + QCOMPARE(mobj->classInfo(3).value(), "Literalfoo"); + + QCOMPARE(mobj->classInfo(4).name(), "fooString"); + QCOMPARE(mobj->classInfo(4).value(), "fooLiteral"); +} + +class VeryLongStringData : public QObject +{ + Q_OBJECT + + #define repeat2(V) V V + #define repeat4(V) repeat2(V) repeat2(V) + #define repeat8(V) repeat4(V) repeat4(V) + #define repeat16(V) repeat8(V) repeat8(V) + #define repeat32(V) repeat16(V) repeat16(V) + #define repeat64(V) repeat32(V) repeat32(V) + #define repeat128(V) repeat64(V) repeat64(V) + #define repeat256(V) repeat128(V) repeat128(V) + #define repeat512(V) repeat256(V) repeat256(V) + #define repeat1024(V) repeat512(V) repeat512(V) + #define repeat2048(V) repeat1024(V) repeat1024(V) + #define repeat4096(V) repeat2048(V) repeat2048(V) + #define repeat8192(V) repeat4096(V) repeat4096(V) + #define repeat16384(V) repeat8192(V) repeat8192(V) + #define repeat32768(V) repeat16384(V) repeat16384(V) + #define repeat65534(V) repeat32768(V) repeat16384(V) repeat8192(V) repeat4096(V) repeat2048(V) repeat1024(V) repeat512(V) repeat256(V) repeat128(V) repeat64(V) repeat32(V) repeat16(V) repeat8(V) repeat4(V) repeat2(V) + + Q_CLASSINFO(repeat65534("n"), repeat65534("i")) + Q_CLASSINFO(repeat65534("e"), repeat65534("r")) + Q_CLASSINFO(repeat32768("o"), repeat32768("b")) + Q_CLASSINFO(":", ")") + + #undef repeat2 + #undef repeat4 + #undef repeat8 + #undef repeat16 + #undef repeat32 + #undef repeat64 + #undef repeat128 + #undef repeat256 + #undef repeat512 + #undef repeat1024 + #undef repeat2048 + #undef repeat4096 + #undef repeat8192 + #undef repeat16384 + #undef repeat32768 + #undef repeat65534 +}; + +void tst_Moc::veryLongStringData() +{ + const QMetaObject *mobj = &VeryLongStringData::staticMetaObject; + QCOMPARE(mobj->classInfoCount(), 4); + + QCOMPARE(mobj->classInfo(0).name()[0], 'n'); + QCOMPARE(mobj->classInfo(0).value()[0], 'i'); + QCOMPARE(mobj->classInfo(1).name()[0], 'e'); + QCOMPARE(mobj->classInfo(1).value()[0], 'r'); + QCOMPARE(mobj->classInfo(2).name()[0], 'o'); + QCOMPARE(mobj->classInfo(2).value()[0], 'b'); + QCOMPARE(mobj->classInfo(3).name()[0], ':'); + QCOMPARE(mobj->classInfo(3).value()[0], ')'); + + QCOMPARE(strlen(mobj->classInfo(0).name()), static_cast<size_t>(65534)); + QCOMPARE(strlen(mobj->classInfo(0).value()), static_cast<size_t>(65534)); + QCOMPARE(strlen(mobj->classInfo(1).name()), static_cast<size_t>(65534)); + QCOMPARE(strlen(mobj->classInfo(1).value()), static_cast<size_t>(65534)); + QCOMPARE(strlen(mobj->classInfo(2).name()), static_cast<size_t>(32768)); + QCOMPARE(strlen(mobj->classInfo(2).value()), static_cast<size_t>(32768)); + QCOMPARE(strlen(mobj->classInfo(3).name()), static_cast<size_t>(1)); + QCOMPARE(strlen(mobj->classInfo(3).value()), static_cast<size_t>(1)); +} + +void tst_Moc::gadgetHierarchy() +{ + QCOMPARE(NonGadgetParent::Derived::staticMetaObject.superClass(), static_cast<const QMetaObject*>(Q_NULLPTR)); + QCOMPARE(GrandParentGadget::DerivedGadget::staticMetaObject.superClass(), &GrandParentGadget::BaseGadget::staticMetaObject); +} + QTEST_MAIN(tst_Moc) // the generated code must compile with QT_NO_KEYWORDS diff --git a/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp b/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp index a47676369c..bccca98180 100644 --- a/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp +++ b/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp @@ -134,7 +134,8 @@ void tst_qdbuscpp2xml::qdbuscpp2xml() } // Launch - const QString command = QLatin1String("qdbuscpp2xml"); + const QString binpath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + const QString command = binpath + QLatin1String("/qdbuscpp2xml"); QProcess process; process.start(command, QStringList() << options << (QFINDTESTDATA(inputfile + QStringLiteral(".h")))); if (!process.waitForFinished()) { diff --git a/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp b/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp index 7d0c5d8d99..f510d8f669 100644 --- a/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp +++ b/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp @@ -162,6 +162,16 @@ void tst_qdbusxml2cpp::process_data() .arg(basicTypeList[i].cppType), QRegularExpression::DotMatchesEverythingOption); } + QTest::newRow("method-name") + << "<method name=\"Method\">" + "<arg type=\"s\" direction=\"in\"/>" + "<annotation name=\"org.qtproject.QtDBus.MethodName\" value=\"MethodRenamed\" />" + "</method>" + << QRegularExpression("Q_SLOTS:.*QDBusPendingReply<> MethodRenamed\\(const QString &\\w*", + QRegularExpression::DotMatchesEverythingOption) + << QRegularExpression("Q_SLOTS:.*void MethodRenamed\\(const QString &\\w*", + QRegularExpression::DotMatchesEverythingOption); + QTest::newRow("method-complex") << "<method name=\"Method\">" "<arg type=\"(dd)\" direction=\"in\"/>" @@ -213,8 +223,10 @@ void tst_qdbusxml2cpp::process() QFETCH_GLOBAL(QString, commandLineArg); // Run the tool + const QString binpath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + const QString command = binpath + QLatin1String("/qdbusxml2cpp"); QProcess process; - process.start("qdbusxml2cpp", QStringList() << commandLineArg << "-" << "-N"); + process.start(command, QStringList() << commandLineArg << "-" << "-N"); QVERIFY2(process.waitForStarted(), qPrintable(process.errorString())); // feed it our XML data diff --git a/tests/auto/tools/qmake/testcompiler.cpp b/tests/auto/tools/qmake/testcompiler.cpp index 7551f5bfbf..61970d0e17 100644 --- a/tests/auto/tools/qmake/testcompiler.cpp +++ b/tests/auto/tools/qmake/testcompiler.cpp @@ -146,14 +146,22 @@ static inline QStringList systemEnvironment() return result; } -bool TestCompiler::runCommand( QString cmdline, bool expectFail ) +bool TestCompiler::runCommand(const QString &cmd, const QStringList &args, bool expectFail) { - testOutput_.append("Running command: " + cmdline); + QString dbg = cmd; + if (dbg.contains(' ')) + dbg.prepend('"').append('"'); + foreach (QString arg, args) { + if (arg.contains(' ')) + arg.prepend('"').append('"'); + dbg.append(' ').append(arg); + } + testOutput_.append("Running command: " + dbg); QProcess child; child.setEnvironment(systemEnvironment() + environment_); - child.start(cmdline); + child.start(cmd, args); if (!child.waitForStarted(-1)) { testOutput_.append( "Unable to start child process." ); return errorOut(); @@ -185,7 +193,7 @@ void TestCompiler::resetArguments() qmakeArgs_.clear(); } -void TestCompiler::setArguments( QString makeArgs, QString qmakeArgs ) +void TestCompiler::setArguments(const QStringList &makeArgs, const QStringList &qmakeArgs) { makeArgs_ = makeArgs; qmakeArgs_ = qmakeArgs; @@ -213,7 +221,7 @@ bool TestCompiler::makeClean( const QString &workPath ) QFileInfo Fi( workPath + "/Makefile"); if (Fi.exists()) // Run make clean - return runCommand( makeCmd_ + " clean" ); + return runCommand(makeCmd_, QStringList() << "clean"); return true; } @@ -230,7 +238,7 @@ bool TestCompiler::makeDistClean( const QString &workPath ) QFileInfo Fi( workPath + "/Makefile"); if (Fi.exists()) // Run make distclean - return runCommand( makeCmd_ + " distclean" ); + return runCommand(makeCmd_, QStringList() << "distclean"); return true; @@ -249,7 +257,7 @@ bool TestCompiler::qmakeProject( const QString &workDir, const QString &proName if (!projectFile.endsWith(".pro")) projectFile += ".pro"; - return runCommand(qmakeCmd_ + " -project -o " + projectFile + " DESTDIR=./"); + return runCommand(qmakeCmd_, QStringList() << "-project" << "-o" << projectFile << "DESTDIR=./"); } bool TestCompiler::qmake( const QString &workDir, const QString &proName, const QString &buildDir ) @@ -269,7 +277,7 @@ bool TestCompiler::qmake( const QString &workDir, const QString &proName, const makeFile += "Makefile"; // Now start qmake and generate the makefile - return runCommand( qmakeCmd_ + " " + qmakeArgs_ + " " + projectFile + " -o " + makeFile ); + return runCommand(qmakeCmd_, QStringList(qmakeArgs_) << projectFile << "-o" << makeFile); } bool TestCompiler::make( const QString &workPath, const QString &target, bool expectFail ) @@ -277,13 +285,13 @@ bool TestCompiler::make( const QString &workPath, const QString &target, bool ex QDir D; D.setCurrent( workPath ); - QString cmdline = makeCmd_ + " " + makeArgs_; - if ( cmdline.contains("nmake", Qt::CaseInsensitive) ) - cmdline.append(" /NOLOGO"); - if ( !target.isEmpty() ) - cmdline += " " + target; + QStringList args = makeArgs_; + if (makeCmd_.contains("nmake", Qt::CaseInsensitive)) + args << "/NOLOGO"; + if (!target.isEmpty()) + args << target; - return runCommand( cmdline, expectFail ); + return runCommand(makeCmd_, args, expectFail); } bool TestCompiler::exists( const QString &destDir, const QString &exeName, BuildType buildType, const QString &version ) diff --git a/tests/auto/tools/qmake/testcompiler.h b/tests/auto/tools/qmake/testcompiler.h index 5e0d706c68..ee73b6cbb3 100644 --- a/tests/auto/tools/qmake/testcompiler.h +++ b/tests/auto/tools/qmake/testcompiler.h @@ -49,7 +49,7 @@ public: void setBaseCommands( QString makeCmd, QString qmakeCmd ); void resetArguments(); - void setArguments( QString makeArgs, QString qmakeArgs ); + void setArguments(const QStringList &makeArgs, const QStringList &qmakeArgs); void resetEnvironment(); void addToEnvironment( QString varAssignment ); @@ -78,11 +78,13 @@ public: void clearCommandOutput(); private: - bool runCommand( QString cmdLine, bool expectFail = false ); + bool runCommand(const QString &cmd, const QStringList &args, bool expectFail = false); bool errorOut(); - QString makeCmd_, makeArgs_; - QString qmakeCmd_, qmakeArgs_; + QString makeCmd_; + QStringList makeArgs_; + QString qmakeCmd_; + QStringList qmakeArgs_; QStringList environment_; QStringList testOutput_; diff --git a/tests/auto/tools/qmake/testdata/export_across_file_boundaries/features/default_post.prf b/tests/auto/tools/qmake/testdata/export_across_file_boundaries/features/default_post.prf new file mode 100644 index 0000000000..6b7c1a31ec --- /dev/null +++ b/tests/auto/tools/qmake/testdata/export_across_file_boundaries/features/default_post.prf @@ -0,0 +1 @@ +# This just balances default_pre.prf (which does not daisy-chain to the one from qmake). diff --git a/tests/auto/tools/qmake/testdata/export_across_file_boundaries/foo.pro b/tests/auto/tools/qmake/testdata/export_across_file_boundaries/foo.pro index f21173783a..9ea0e19338 100644 --- a/tests/auto/tools/qmake/testdata/export_across_file_boundaries/foo.pro +++ b/tests/auto/tools/qmake/testdata/export_across_file_boundaries/foo.pro @@ -1,3 +1,6 @@ +TEMPLATE = aux +CONFIG = + !equals(FOO,bar) { message( "FAILED: export() invisible from default_pre.prf to foo.pro" ) } diff --git a/tests/auto/tools/qmake/testdata/functions/functions.pro b/tests/auto/tools/qmake/testdata/functions/functions.pro index a0e88300d4..5db8036188 100644 --- a/tests/auto/tools/qmake/testdata/functions/functions.pro +++ b/tests/auto/tools/qmake/testdata/functions/functions.pro @@ -156,9 +156,9 @@ testReplace($$relative_path("/fake/trolls", "/fake/path"), "../trolls", "relativ testReplace($$relative_path(""), "", "relative_path of empty") #this test is very rudimentary. the backend function is thoroughly tested in qt creator -in = "some nasty\" path\\" -out_cmd = "\"some nasty\"\\^\"\" path\"\\" -out_sh = "'some nasty\" path\\'" +in = "some nasty & ugly\" path & thing\\" +out_cmd = "\"some nasty & ugly\\\" path ^& thing\\\\^\"" +out_sh = "'some nasty & ugly\" path & thing\\'" equals(QMAKE_HOST.os, Windows): \ out = $$out_cmd else: \ diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index 53d90aa5ce..cc69b78a52 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -461,7 +461,8 @@ void tst_qmake::bundle_spaces() // Bundles and since this might be the wrong output we rely on dry-running // make (-n). - test_compiler.setArguments("-n", "-spec macx-clang"); + test_compiler.setArguments(QStringList() << "-n", + QStringList() << "-spec" << "macx-clang"); QVERIFY( test_compiler.qmake(workDir, "bundle-spaces") ); diff --git a/tests/auto/tools/uic/tst_uic.cpp b/tests/auto/tools/uic/tst_uic.cpp index a5bffced6c..dacb5fcb61 100644 --- a/tests/auto/tools/uic/tst_uic.cpp +++ b/tests/auto/tools/uic/tst_uic.cpp @@ -95,8 +95,8 @@ void tst_uic::initTestCase() const QString out = QString::fromLocal8Bit(process.readAllStandardError()).remove(QLatin1Char('\r')); const QStringList outLines = out.split(QLatin1Char('\n')); // Print version - QString msg = QString::fromLatin1("uic test built %1 running in '%2' using: "). - arg(QString::fromLatin1(__DATE__), QDir::currentPath()); + QString msg = QString::fromLatin1("uic test running in '%1' using: "). + arg(QDir::currentPath()); if (!outLines.empty()) msg += outLines.front(); qDebug("%s", qPrintable(msg)); diff --git a/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp index fb656b7c69..da81600dd0 100644 --- a/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp +++ b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp @@ -52,6 +52,7 @@ private Q_SLOTS: void cleanup(); void autoShow_data(); void autoShow(); + void autoShowCtor(); void getSetCheck(); void task198202(); void QTBUG_31046(); @@ -68,30 +69,62 @@ void tst_QProgressDialog::autoShow_data() { QTest::addColumn<int>("min"); QTest::addColumn<int>("max"); - QTest::addColumn<int>("delay"); + QTest::addColumn<int>("value"); // initial setValue call + QTest::addColumn<int>("delay"); // then we wait for this long, and setValue(min+1) + QTest::addColumn<int>("minDuration"); QTest::addColumn<bool>("expectedAutoShow"); - QTest::newRow("50_to_100_long") << 50 << 100 << 100 << true; // 50*100ms = 5s - QTest::newRow("50_to_100_short") << 50 << 1 << 100 << false; // 50*1ms = 50ms + // Check that autoshow works even when not starting at 0 + QTest::newRow("50_to_100_slow_shown") << 50 << 100 << 50 << 100 << 100 << true; // 50*100ms = 5s + QTest::newRow("50_to_100_fast_not_shown") << 50 << 100 << 50 << 1 << 100 << false; // 1ms is too short to even start estimating + QTest::newRow("50_to_60_high_minDuration_not_shown") << 50 << 60 << 50 << 100 << 2000 << false; // 10*100ms = 1s < 2s + + // Check that setValue(0) still starts the timer as previously documented + QTest::newRow("50_to_100_slow_0_compat") << 50 << 100 << 0 << 100 << 100 << true; // 50*100ms = 5s + QTest::newRow("50_to_100_fast_0_compat") << 50 << 100 << 0 << 1 << 100 << false; // 1ms is too short to even start estimating + QTest::newRow("50_to_60_high_minDuration_0_compat") << 50 << 60 << 0 << 100 << 2000 << false; // 10*100ms = 1s < 2s + + // Check the typical case of starting at 0 + QTest::newRow("0_to_100_slow_shown") << 0 << 100 << 0 << 100 << 100 << true; // 100*100ms = 10s > 100ms + QTest::newRow("0_to_10_slow_shown") << 0 << 10 << 0 << 100 << 500 << true; // 10*100ms = 1s > 0.5s + QTest::newRow("0_to_10_high_minDuration_not_shown") << 0 << 10 << 0 << 100 << 2000 << false; // 10*100ms = 1s < 2s + + // Check the special case of going via 0 at some point + QTest::newRow("-1_to_1_slow_shown") << -1 << 1 << -1 << 200 << 100 << true; // 1*200ms = 200ms > 100ms + QTest::newRow("-1_to_1_fast_not_shown") << -1 << 1 << -1 << 10 << 100 << false; // 10ms is too short to even start estimating + QTest::newRow("-1_to_1_high_minDuration_not_shown") << -1 << 1 << -1 << 100 << 2000 << false; // 1*100ms = 100ms < 2s - QTest::newRow("0_to_100_long") << 0 << 100 << 100 << true; // 100*100ms = 10s - QTest::newRow("0_to_10_short") << 0 << 10 << 100 << false; // 10*100ms = 1s } void tst_QProgressDialog::autoShow() { QFETCH(int, min); QFETCH(int, max); + QFETCH(int, value); QFETCH(int, delay); + QFETCH(int, minDuration); QFETCH(bool, expectedAutoShow); QProgressDialog dlg("", "", min, max); - dlg.setValue(0); + if (minDuration != dlg.minimumDuration()) + dlg.setMinimumDuration(minDuration); + dlg.reset(); // cancel the timer started in the constructor, + // in order to test for the setValue() behavior instead + // See autoShowCtor() for the ctor timer check + dlg.setValue(value); QThread::msleep(delay); dlg.setValue(min+1); QCOMPARE(dlg.isVisible(), expectedAutoShow); } +void tst_QProgressDialog::autoShowCtor() +{ + QProgressDialog dlg; + QVERIFY(!dlg.isVisible()); + QThread::msleep(dlg.minimumDuration()); + QTRY_VERIFY(dlg.isVisible()); +} + // Testing get/set functions void tst_QProgressDialog::getSetCheck() { diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 3b55fcd5fc..7eb682075e 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -1682,6 +1682,23 @@ void tst_QGraphicsGridLayout::sizeHint_data() << QSizeF(100, 100) << QSizeF(100, 100); + QTest::newRow("colSpan_with_ignored_column") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(40,20)) + .maxSize(QSizeF(60,20)) + .colSpan(2) + << ItemDesc(0,2) + .minSize(QSizeF(20, 20)) + .maxSize(QSizeF(30, 20)) + << ItemDesc(1,0) + .minSize(QSizeF(60, 20)) + .maxSize(QSizeF(90, 20)) + .colSpan(3) + ) + << QSizeF(60, 40) + << QSizeF(80, 40) + << QSizeF(90, 40); + } // public QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 51efc47094..44d06c6244 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -1799,6 +1799,12 @@ void tst_QGraphicsItem::selected_multi() // Ctrl-click on scene QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(0, 0)); QTest::qWait(20); + QVERIFY(item1->isSelected()); + QVERIFY(!item2->isSelected()); + + // Click on scene + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(0, 0)); + QTest::qWait(20); QVERIFY(!item1->isSelected()); QVERIFY(!item2->isSelected()); diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 5aea845f90..c2ec7be9e7 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -2783,7 +2783,7 @@ void tst_QGraphicsProxyWidget::windowOpacity() // disabled on platforms without alpha channel support in QPixmap (e.g., // X11 without XRender). int paints = 0; -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 paints = !X11->use_xrender; #endif QTRY_COMPARE(eventSpy.counts[QEvent::UpdateRequest], 0); diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 250790d9fa..c051f38ffb 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -164,6 +164,7 @@ private slots: void dragMode_scrollHand(); void dragMode_rubberBand(); void rubberBandSelectionMode(); + void rubberBandExtendSelection(); void rotated_rubberBand(); void backgroundBrush(); void foregroundBrush(); @@ -941,6 +942,61 @@ void tst_QGraphicsView::rubberBandSelectionMode() QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>() << rect); } +void tst_QGraphicsView::rubberBandExtendSelection() +{ + QWidget toplevel; + setFrameless(&toplevel); + + QGraphicsScene scene(0, 0, 1000, 1000); + + QGraphicsView view(&scene, &toplevel); + view.setDragMode(QGraphicsView::RubberBandDrag); + toplevel.show(); + + // Disable mouse tracking to prevent the window system from sending mouse + // move events to the viewport while we are synthesizing events. If + // QGraphicsView gets a mouse move event with no buttons down, it'll + // terminate the rubber band. + view.viewport()->setMouseTracking(false); + + QGraphicsItem *item1 = scene.addRect(10, 10, 100, 100); + QGraphicsItem *item2 = scene.addRect(10, 120, 100, 100); + QGraphicsItem *item3 = scene.addRect(10, 230, 100, 100); + + item1->setFlag(QGraphicsItem::ItemIsSelectable); + item2->setFlag(QGraphicsItem::ItemIsSelectable); + item3->setFlag(QGraphicsItem::ItemIsSelectable); + + // select first item + item1->setSelected(true); + QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>() << item1); + + // first rubberband without modifier key + sendMousePress(view.viewport(), view.mapFromScene(20, 115), Qt::LeftButton); + sendMouseMove(view.viewport(), view.mapFromScene(20, 300), Qt::LeftButton, Qt::LeftButton); + QVERIFY(!item1->isSelected()); + QVERIFY(item2->isSelected()); + QVERIFY(item3->isSelected()); + sendMouseRelease(view.viewport(), QPoint(), Qt::LeftButton); + + scene.clearSelection(); + + // select first item + item1->setSelected(true); + QVERIFY(item1->isSelected()); + + // now rubberband with modifier key + { + QPoint clickPoint = view.mapFromScene(20, 115); + QMouseEvent event(QEvent::MouseButtonPress, clickPoint, view.viewport()->mapToGlobal(clickPoint), Qt::LeftButton, 0, Qt::ControlModifier); + QApplication::sendEvent(view.viewport(), &event); + } + sendMouseMove(view.viewport(), view.mapFromScene(20, 300), Qt::LeftButton, Qt::LeftButton); + QVERIFY(item1->isSelected()); + QVERIFY(item2->isSelected()); + QVERIFY(item3->isSelected()); +} + void tst_QGraphicsView::rotated_rubberBand() { QWidget toplevel; @@ -2110,8 +2166,7 @@ void tst_QGraphicsView::sendEvent() QCOMPARE(item->events.at(item->events.size() - 2), QEvent::GraphicsSceneMouseRelease); QCOMPARE(item->events.at(item->events.size() - 1), QEvent::UngrabMouse); - QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Space, 0); - QApplication::sendEvent(view.viewport(), &keyPress); + QTest::keyPress(view.viewport(), Qt::Key_Space); QCOMPARE(item->events.size(), 9); QCOMPARE(item->events.at(item->events.size() - 2), QEvent::ShortcutOverride); QCOMPARE(item->events.last(), QEvent::KeyPress); diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index ff910ba359..930367e580 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -530,11 +530,16 @@ void tst_QAbstractItemView::basic_tests(TestView *view) // setIconSize view->setIconSize(QSize(16, 16)); QCOMPARE(view->iconSize(), QSize(16, 16)); + QSignalSpy spy(view, &QAbstractItemView::iconSizeChanged); + QVERIFY(spy.isValid()); view->setIconSize(QSize(32, 32)); QCOMPARE(view->iconSize(), QSize(32, 32)); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).value<QSize>(), QSize(32, 32)); // Should this happen? view->setIconSize(QSize(-1, -1)); QCOMPARE(view->iconSize(), QSize(-1, -1)); + QCOMPARE(spy.count(), 2); QCOMPARE(view->currentIndex(), QModelIndex()); QCOMPARE(view->rootIndex(), QModelIndex()); @@ -1112,7 +1117,7 @@ void tst_QAbstractItemView::setItemDelegate() centerOnScreen(&v); moveCursorAway(&v); v.show(); -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 QCursor::setPos(v.geometry().center()); #endif QApplication::setActiveWindow(&v); @@ -1822,7 +1827,6 @@ void tst_QAbstractItemView::testFocusPolicy() QVERIFY(!qApp->focusWidget()); } -Q_DECLARE_METATYPE(QItemSelection) void tst_QAbstractItemView::QTBUG31411_noSelection() { QWidget window; diff --git a/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp b/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp index 2c3fdb1baa..4e2dbd4de4 100644 --- a/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp +++ b/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp @@ -30,14 +30,22 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <QtGui/QtGui> -#include <QtWidgets/QtWidgets> -#include <QtTest/QtTest> +#include <QDataWidgetMapper> +#include <QStandardItemModel> +#include <QLineEdit> +#include <QComboBox> +#include <QTextEdit> +#include <QVBoxLayout> +#include <QTest> +#include <QSignalSpy> +#include <QMetaType> class tst_QDataWidgetMapper: public QObject { Q_OBJECT private slots: + void initTestCase(); + void setModel(); void navigate(); void addMapping(); @@ -47,8 +55,12 @@ private slots: void mappedWidgetAt(); void comboBox(); + + void textEditDoesntChangeFocusOnTab_qtbug3305(); }; +Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint) + static QStandardItemModel *testModel(QObject *parent = 0) { QStandardItemModel *model = new QStandardItemModel(10, 10, parent); @@ -61,6 +73,11 @@ static QStandardItemModel *testModel(QObject *parent = 0) return model; } +void tst_QDataWidgetMapper::initTestCase() +{ + qRegisterMetaType<QAbstractItemDelegate::EndEditHint>(); +} + void tst_QDataWidgetMapper::setModel() { QDataWidgetMapper mapper; @@ -400,5 +417,63 @@ void tst_QDataWidgetMapper::mappedWidgetAt() QCOMPARE(mapper.mappedWidgetAt(4242), static_cast<QWidget *>(&lineEdit2)); } +void tst_QDataWidgetMapper::textEditDoesntChangeFocusOnTab_qtbug3305() +{ + QDataWidgetMapper mapper; + QAbstractItemModel *model = testModel(&mapper); + mapper.setModel(model); + + QSignalSpy closeEditorSpy(mapper.itemDelegate(), SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint))); + QVERIFY(closeEditorSpy.isValid()); + + QWidget container; + container.setLayout(new QVBoxLayout); + + QLineEdit *lineEdit = new QLineEdit; + mapper.addMapping(lineEdit, 0); + container.layout()->addWidget(lineEdit); + + QTextEdit *textEdit = new QTextEdit; + mapper.addMapping(textEdit, 1); + container.layout()->addWidget(textEdit); + + lineEdit->setFocus(); + + container.show(); + + QApplication::setActiveWindow(&container); + QVERIFY(QTest::qWaitForWindowActive(&container)); + + int closeEditorSpyCount = 0; + const QString textEditContents = textEdit->toPlainText(); + + QCOMPARE(closeEditorSpy.count(), closeEditorSpyCount); + QVERIFY(lineEdit->hasFocus()); + QVERIFY(!textEdit->hasFocus()); + + // this will generate a closeEditor for the tab key, and another for the focus out + QTest::keyClick(QApplication::focusWidget(), Qt::Key_Tab); + closeEditorSpyCount += 2; + QTRY_COMPARE(closeEditorSpy.count(), closeEditorSpyCount); + + QTRY_VERIFY(textEdit->hasFocus()); + QVERIFY(!lineEdit->hasFocus()); + + // now that the text edit is focused, a tab keypress will insert a tab, not change focus + QTest::keyClick(QApplication::focusWidget(), Qt::Key_Tab); + QTRY_COMPARE(closeEditorSpy.count(), closeEditorSpyCount); + + QVERIFY(!lineEdit->hasFocus()); + QVERIFY(textEdit->hasFocus()); + QCOMPARE(textEdit->toPlainText(), QLatin1Char('\t') + textEditContents); + + // now give focus back to the line edit and check closeEditor gets emitted + lineEdit->setFocus(); + QTRY_VERIFY(lineEdit->hasFocus()); + QVERIFY(!textEdit->hasFocus()); + ++closeEditorSpyCount; + QCOMPARE(closeEditorSpy.count(), closeEditorSpyCount); +} + QTEST_MAIN(tst_QDataWidgetMapper) #include "tst_qdatawidgetmapper.moc" diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index e632af1262..b9bf42f67f 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -176,6 +176,7 @@ private slots: void moveSectionAndRemove(); void saveRestore(); void defaultSectionSizeTest(); + void defaultSectionSizeTestStyles(); void defaultAlignment_data(); void defaultAlignment(); @@ -1710,6 +1711,41 @@ void tst_QHeaderView::defaultSectionSizeTest() QVERIFY(hv->sectionSize(2) == 0); // section is hidden. It should not be resized. } +class TestHeaderViewStyle : public QProxyStyle +{ +public: + TestHeaderViewStyle() : horizontalSectionSize(100) {} + int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE + { + if (metric == QStyle::PM_HeaderDefaultSectionSizeHorizontal) + return horizontalSectionSize; + else + return QProxyStyle::pixelMetric(metric, option, widget); + } + int horizontalSectionSize; +}; + +void tst_QHeaderView::defaultSectionSizeTestStyles() +{ + TestHeaderViewStyle style1; + TestHeaderViewStyle style2; + style1.horizontalSectionSize = 100; + style2.horizontalSectionSize = 200; + + QHeaderView hv(Qt::Horizontal); + hv.setStyle(&style1); + QCOMPARE(hv.defaultSectionSize(), style1.horizontalSectionSize); + hv.setStyle(&style2); + QCOMPARE(hv.defaultSectionSize(), style2.horizontalSectionSize); + hv.setDefaultSectionSize(70); + QCOMPARE(hv.defaultSectionSize(), 70); + hv.setStyle(&style1); + QCOMPARE(hv.defaultSectionSize(), 70); + hv.resetDefaultSectionSize(); + QCOMPARE(hv.defaultSectionSize(), style1.horizontalSectionSize); + hv.setStyle(&style2); + QCOMPARE(hv.defaultSectionSize(), style2.horizontalSectionSize); +} void tst_QHeaderView::defaultAlignment_data() { diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index f000907e0e..0d1f11c1b5 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -1083,8 +1083,6 @@ void tst_QItemDelegate::decoration() void tst_QItemDelegate::editorEvent_data() { - QTest::addColumn<QRect>("rect"); - QTest::addColumn<QString>("text"); QTest::addColumn<int>("checkState"); QTest::addColumn<int>("flags"); QTest::addColumn<bool>("inCheck"); @@ -1093,16 +1091,16 @@ void tst_QItemDelegate::editorEvent_data() QTest::addColumn<bool>("edited"); QTest::addColumn<int>("expectedCheckState"); - QTest::newRow("unchecked, checkable, release") - << QRect(0, 0, 20, 20) - << QString("foo") - << (int)(Qt::Unchecked) - << (int)(Qt::ItemIsEditable + const int defaultFlags = (int)(Qt::ItemIsEditable |Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + |Qt::ItemIsDropEnabled); + + QTest::newRow("unchecked, checkable, release") + << (int)(Qt::Unchecked) + << defaultFlags << true << (int)(QEvent::MouseButtonRelease) << (int)(Qt::LeftButton) @@ -1110,15 +1108,8 @@ void tst_QItemDelegate::editorEvent_data() << (int)(Qt::Checked); QTest::newRow("checked, checkable, release") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::Checked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << defaultFlags << true << (int)(QEvent::MouseButtonRelease) << (int)(Qt::LeftButton) @@ -1126,15 +1117,8 @@ void tst_QItemDelegate::editorEvent_data() << (int)(Qt::Unchecked); QTest::newRow("unchecked, checkable, release") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::Unchecked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << defaultFlags << true << (int)(QEvent::MouseButtonRelease) << (int)(Qt::LeftButton) @@ -1142,15 +1126,8 @@ void tst_QItemDelegate::editorEvent_data() << (int)(Qt::Checked); QTest::newRow("unchecked, checkable, release, right button") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::Unchecked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << defaultFlags << true << (int)(QEvent::MouseButtonRelease) << (int)(Qt::RightButton) @@ -1158,15 +1135,8 @@ void tst_QItemDelegate::editorEvent_data() << (int)(Qt::Unchecked); QTest::newRow("unchecked, checkable, release outside") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::Unchecked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << defaultFlags << false << (int)(QEvent::MouseButtonRelease) << (int)(Qt::LeftButton) @@ -1174,15 +1144,8 @@ void tst_QItemDelegate::editorEvent_data() << (int)(Qt::Unchecked); QTest::newRow("unchecked, checkable, dblclick") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::Unchecked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << defaultFlags << true << (int)(QEvent::MouseButtonDblClick) << (int)(Qt::LeftButton) @@ -1190,33 +1153,17 @@ void tst_QItemDelegate::editorEvent_data() << (int)(Qt::Unchecked); QTest::newRow("unchecked, tristate, release") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::Unchecked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsTristate - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << (int)(defaultFlags | Qt::ItemIsTristate) << true << (int)(QEvent::MouseButtonRelease) << (int)(Qt::LeftButton) << true - << (int)(Qt::PartiallyChecked); + << (int)(Qt::Checked); QTest::newRow("partially checked, tristate, release") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::PartiallyChecked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsTristate - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << (int)(defaultFlags | Qt::ItemIsTristate) << true << (int)(QEvent::MouseButtonRelease) << (int)(Qt::LeftButton) @@ -1224,16 +1171,35 @@ void tst_QItemDelegate::editorEvent_data() << (int)(Qt::Checked); QTest::newRow("checked, tristate, release") - << QRect(0, 0, 20, 20) - << QString("foo") << (int)(Qt::Checked) - << (int)(Qt::ItemIsEditable - |Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsTristate - |Qt::ItemIsEnabled - |Qt::ItemIsDragEnabled - |Qt::ItemIsDropEnabled) + << (int)(defaultFlags | Qt::ItemIsTristate) + << true + << (int)(QEvent::MouseButtonRelease) + << (int)(Qt::LeftButton) + << true + << (int)(Qt::Unchecked); + + QTest::newRow("unchecked, user-tristate, release") + << (int)(Qt::Unchecked) + << (int)(defaultFlags | Qt::ItemIsUserTristate) + << true + << (int)(QEvent::MouseButtonRelease) + << (int)(Qt::LeftButton) + << true + << (int)(Qt::PartiallyChecked); + + QTest::newRow("partially checked, user-tristate, release") + << (int)(Qt::PartiallyChecked) + << (int)(defaultFlags | Qt::ItemIsUserTristate) + << true + << (int)(QEvent::MouseButtonRelease) + << (int)(Qt::LeftButton) + << true + << (int)(Qt::Checked); + + QTest::newRow("checked, user-tristate, release") + << (int)(Qt::Checked) + << (int)(defaultFlags | Qt::ItemIsUserTristate) << true << (int)(QEvent::MouseButtonRelease) << (int)(Qt::LeftButton) @@ -1243,8 +1209,6 @@ void tst_QItemDelegate::editorEvent_data() void tst_QItemDelegate::editorEvent() { - QFETCH(QRect, rect); - QFETCH(QString, text); QFETCH(int, checkState); QFETCH(int, flags); QFETCH(bool, inCheck); @@ -1258,12 +1222,12 @@ void tst_QItemDelegate::editorEvent() QVERIFY(index.isValid()); QStandardItem *item = model.itemFromIndex(index); - item->setText(text); + item->setText("foo"); item->setCheckState((Qt::CheckState)checkState); item->setFlags((Qt::ItemFlags)flags); QStyleOptionViewItem option; - option.rect = rect; + option.rect = QRect(0, 0, 20, 20); option.state |= QStyle::State_Enabled; // mimic QStyledItemDelegate::initStyleOption logic option.features |= QStyleOptionViewItem::HasCheckIndicator | QStyleOptionViewItem::HasDisplay; @@ -1302,11 +1266,19 @@ void tst_QItemDelegate::enterKey_data() QTest::addColumn<bool>("expectedFocus"); QTest::newRow("lineedit enter") << LineEdit << int(Qt::Key_Enter) << false; + QTest::newRow("lineedit return") << LineEdit << int(Qt::Key_Return) << false; + QTest::newRow("lineedit tab") << LineEdit << int(Qt::Key_Tab) << false; + QTest::newRow("lineedit backtab") << LineEdit << int(Qt::Key_Backtab) << false; + QTest::newRow("textedit enter") << TextEdit << int(Qt::Key_Enter) << true; + QTest::newRow("textedit return") << TextEdit << int(Qt::Key_Return) << true; + QTest::newRow("textedit tab") << TextEdit << int(Qt::Key_Tab) << true; + QTest::newRow("textedit backtab") << TextEdit << int(Qt::Key_Backtab) << false; + QTest::newRow("plaintextedit enter") << PlainTextEdit << int(Qt::Key_Enter) << true; QTest::newRow("plaintextedit return") << PlainTextEdit << int(Qt::Key_Return) << true; - QTest::newRow("plaintextedit tab") << PlainTextEdit << int(Qt::Key_Tab) << false; - QTest::newRow("lineedit tab") << LineEdit << int(Qt::Key_Tab) << false; + QTest::newRow("plaintextedit tab") << PlainTextEdit << int(Qt::Key_Tab) << true; + QTest::newRow("plaintextedit backtab") << PlainTextEdit << int(Qt::Key_Backtab) << false; } void tst_QItemDelegate::enterKey() @@ -1364,10 +1336,11 @@ void tst_QItemDelegate::enterKey() QTest::keyClick(editor, Qt::Key(key)); QApplication::processEvents(); - // The line edit has already been destroyed, so avoid that case. - if (widget == TextEdit || widget == PlainTextEdit) { + if (expectedFocus) { QVERIFY(!editor.isNull()); - QCOMPARE(editor && editor->hasFocus(), expectedFocus); + QVERIFY(editor->hasFocus()); + } else { + QTRY_VERIFY(editor.isNull()); // editor deletion happens via deleteLater } } diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index 6428bbba10..428b2f0c42 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -123,7 +123,7 @@ private slots: void task258949_keypressHangup(); void QTBUG8086_currentItemChangedOnClick(); void QTBUG14363_completerWithAnyKeyPressedEditTriggers(); - + void mimeData(); protected slots: void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last) @@ -1082,6 +1082,9 @@ public: Q_UNUSED(item); return QListWidget::state() == QListWidget::EditingState; } + + using QListWidget::mimeData; + using QListWidget::indexFromItem; }; void tst_QListWidget::closeEditor() @@ -1662,7 +1665,57 @@ void tst_QListWidget::QTBUG14363_completerWithAnyKeyPressedEditTriggers() QCOMPARE(le->completer()->currentCompletion(), QString("completer")); } +void tst_QListWidget::mimeData() +{ + TestListWidget list; + + for (int x = 0; x < 10; ++x) { + QListWidgetItem *item = new QListWidgetItem(QStringLiteral("123")); + list.addItem(item); + } + + QList<QListWidgetItem *> tableWidgetItemList; + QModelIndexList modelIndexList; + + // do these checks more than once to ensure that the "cached indexes" work as expected + QVERIFY(!list.mimeData(tableWidgetItemList)); + QVERIFY(!list.model()->mimeData(modelIndexList)); + QVERIFY(!list.model()->mimeData(modelIndexList)); + QVERIFY(!list.mimeData(tableWidgetItemList)); + + tableWidgetItemList << list.item(1); + modelIndexList << list.indexFromItem(list.item(1)); + + QMimeData *data; + + QVERIFY(data = list.mimeData(tableWidgetItemList)); + delete data; + QVERIFY(data = list.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = list.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = list.mimeData(tableWidgetItemList)); + delete data; + + // check the saved data is actually the same + + QMimeData *data2; + + data = list.mimeData(tableWidgetItemList); + data2 = list.model()->mimeData(modelIndexList); + + const QString format = QStringLiteral("application/x-qabstractitemmodeldatalist"); + + QVERIFY(data->hasFormat(format)); + QVERIFY(data2->hasFormat(format)); + QVERIFY(data->data(format) == data2->data(format)); + + delete data; + delete data2; +} QTEST_MAIN(tst_QListWidget) #include "tst_qlistwidget.moc" diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index 8335497c6c..de88e832aa 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -93,6 +93,7 @@ private slots: void task219380_removeLastRow(); void task262056_sortDuplicate(); void itemWithHeaderItems(); + void mimeData(); private: QTableWidget *testWidget; @@ -1497,5 +1498,72 @@ void tst_QTableWidget::itemWithHeaderItems() QCOMPARE(table.item(0, 1), static_cast<QTableWidgetItem *>(0)); } +class TestTableWidget : public QTableWidget +{ + Q_OBJECT +public: + TestTableWidget(int rows, int columns, QWidget *parent = 0) + : QTableWidget(rows, columns, parent) + { + } + + using QTableWidget::mimeData; + using QTableWidget::indexFromItem; +}; + +void tst_QTableWidget::mimeData() +{ + TestTableWidget table(10, 10); + + for (int x = 0; x < 10; ++x) { + for (int y = 0; y < 10; ++y) { + QTableWidgetItem *item = new QTableWidgetItem(QStringLiteral("123")); + table.setItem(y, x, item); + } + } + + QList<QTableWidgetItem *> tableWidgetItemList; + QModelIndexList modelIndexList; + + // do these checks more than once to ensure that the "cached indexes" work as expected + QVERIFY(!table.mimeData(tableWidgetItemList)); + QVERIFY(!table.model()->mimeData(modelIndexList)); + QVERIFY(!table.model()->mimeData(modelIndexList)); + QVERIFY(!table.mimeData(tableWidgetItemList)); + + tableWidgetItemList << table.item(1, 1); + modelIndexList << table.indexFromItem(table.item(1, 1)); + + QMimeData *data; + + QVERIFY(data = table.mimeData(tableWidgetItemList)); + delete data; + + QVERIFY(data = table.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = table.model()->mimeData(modelIndexList)); + delete data; + + QVERIFY(data = table.mimeData(tableWidgetItemList)); + delete data; + + // check the saved data is actually the same + + QMimeData *data2; + + data = table.mimeData(tableWidgetItemList); + data2 = table.model()->mimeData(modelIndexList); + + const QString format = QStringLiteral("application/x-qabstractitemmodeldatalist"); + + QVERIFY(data->hasFormat(format)); + QVERIFY(data2->hasFormat(format)); + QVERIFY(data->data(format) == data2->data(format)); + + delete data; + delete data2; +} + QTEST_MAIN(tst_QTableWidget) #include "tst_qtablewidget.moc" diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index bdeaaf38db..6f7a6c2491 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -132,6 +132,8 @@ private slots: void task245280_sortChildren(); void task253109_itemHeight(); + void nonEditableTristate(); + // QTreeWidgetItem void itemOperatorLessThan(); void addChild(); @@ -1050,6 +1052,12 @@ void tst_QTreeWidget::checkState() QCOMPARE(item->checkState(0), Qt::Unchecked); QCOMPARE(firstChild->checkState(0), Qt::Unchecked); QCOMPARE(seccondChild->checkState(0), Qt::Unchecked); + + // Can't force the state to PartiallyChecked; state comes from children + item->setCheckState(0, Qt::PartiallyChecked); + QCOMPARE(item->checkState(0), Qt::Unchecked); + QCOMPARE(firstChild->checkState(0), Qt::Unchecked); + QCOMPARE(seccondChild->checkState(0), Qt::Unchecked); } void tst_QTreeWidget::findItems_data() @@ -3166,6 +3174,40 @@ void tst_QTreeWidget::task217309() QVERIFY(item.data(0, Qt::CheckStateRole) == Qt::Checked); } +void tst_QTreeWidget::nonEditableTristate() +{ + // A tree with checkable items, the parent is tristate + QTreeWidget *tree = new QTreeWidget; + QTreeWidgetItem *item = new QTreeWidgetItem(); + tree->insertTopLevelItem(0, item); + item->setFlags(item->flags() | Qt::ItemIsTristate); + item->setCheckState(0, Qt::Unchecked); + QTreeWidgetItem *subitem1 = new QTreeWidgetItem(item); + subitem1->setCheckState(0, Qt::Unchecked); + QTreeWidgetItem *subitem2 = new QTreeWidgetItem(item); + subitem2->setCheckState(0, Qt::Unchecked); + QCOMPARE(int(item->checkState(0)), int(Qt::Unchecked)); + tree->show(); + + // Test clicking on the parent item, it should become Checked (not PartiallyChecked) + QStyleOptionViewItem option; + option.rect = tree->visualRect(tree->model()->index(0, 0)); + option.state |= QStyle::State_Enabled; + option.features |= QStyleOptionViewItem::HasCheckIndicator | QStyleOptionViewItem::HasDisplay; + option.checkState = item->checkState(0); + + const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1; + QPoint pos = qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0); + QTest::mouseClick(tree->viewport(), Qt::LeftButton, Qt::NoModifier, pos); + QCOMPARE(int(item->checkState(0)), int(Qt::Checked)); + + // Click again, it should become Unchecked. + QTest::mouseClick(tree->viewport(), Qt::LeftButton, Qt::NoModifier, pos); + QCOMPARE(int(item->checkState(0)), int(Qt::Unchecked)); + + delete tree; +} + class TreeWidgetItem : public QTreeWidgetItem { diff --git a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp index 1d6f577192..0691801553 100644 --- a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp +++ b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp @@ -42,6 +42,7 @@ #include <qdebug.h> #include <qstring.h> #include <qshortcut.h> +#include <qscreen.h> class AccelForm; QT_BEGIN_NAMESPACE @@ -119,6 +120,7 @@ private slots: void keypressConsumption(); void unicodeCompare(); void context(); + void duplicatedShortcutOverride(); protected: static Qt::KeyboardModifiers toButtons( int key ); @@ -1082,6 +1084,36 @@ void tst_QShortcut::context() clearAllShortcuts(); } +// QTBUG-38986, do not generate duplicated QEvent::ShortcutOverride in event processing. +class OverrideCountingWidget : public QWidget +{ +public: + OverrideCountingWidget(QWidget *parent = 0) : QWidget(parent), overrideCount(0) {} + + int overrideCount; + + bool event(QEvent *e) Q_DECL_OVERRIDE + { + if (e->type() == QEvent::ShortcutOverride) + overrideCount++; + return QWidget::event(e); + } +}; + +void tst_QShortcut::duplicatedShortcutOverride() +{ + OverrideCountingWidget w; + w.setWindowTitle(Q_FUNC_INFO); + w.resize(200, 200); + w.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(100, 100)); + w.show(); + QApplication::setActiveWindow(&w); + QVERIFY(QTest::qWaitForWindowActive(&w)); + QTest::keyPress(w.windowHandle(), Qt::Key_A); + QCoreApplication::processEvents(); + QCOMPARE(w.overrideCount, 1); +} + // ------------------------------------------------------------------ // Element Testing helper functions --------------------------------- // ------------------------------------------------------------------ @@ -1226,7 +1258,7 @@ void tst_QShortcut::testElement() setupShortcut(testWidget, txt, k1, k2, k3, k4); } else { sendKeyEvents(k1, c1, k2, c2, k3, c3, k4, c4); - QCOMPARE(currentResult, result); + QCOMPARE((int)currentResult, (int)result); } } diff --git a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp index 1facf99afa..e0533d129a 100644 --- a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp +++ b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp @@ -31,39 +31,83 @@ ** ****************************************************************************/ - #include <QtTest/QtTest> #include <qsizepolicy.h> +Q_DECLARE_METATYPE(Qt::Orientations) +Q_DECLARE_METATYPE(QSizePolicy) +Q_DECLARE_METATYPE(QSizePolicy::Policy) +Q_DECLARE_METATYPE(QSizePolicy::ControlType) + class tst_QSizePolicy : public QObject { -Q_OBJECT + Q_OBJECT -public: - tst_QSizePolicy(); - virtual ~tst_QSizePolicy(); - -private slots: +private Q_SLOTS: + void qtest(); + void defaultValues(); + void getSetCheck_data() { data(); } void getSetCheck(); void dataStream(); void horizontalStretch(); void verticalStretch(); +private: + void data() const; }; -tst_QSizePolicy::tst_QSizePolicy() -{ -} -tst_QSizePolicy::~tst_QSizePolicy() +struct PrettyPrint { + const char *m_s; + template <typename T> + explicit PrettyPrint(const T &t) : m_s(Q_NULLPTR) + { + using QT_PREPEND_NAMESPACE(QTest)::toString; + m_s = toString(t); + } + ~PrettyPrint() { delete[] m_s; } + const char* s() const { return m_s ? m_s : "<null>" ; } +}; + +void tst_QSizePolicy::qtest() { +#define CHECK(x) QCOMPARE(PrettyPrint(QSizePolicy::x).s(), #x) + // Policy: + CHECK(Fixed); + CHECK(Minimum); + CHECK(Ignored); + CHECK(MinimumExpanding); + CHECK(Expanding); + CHECK(Maximum); + CHECK(Preferred); + // ControlType: + CHECK(ButtonBox); + CHECK(CheckBox); + CHECK(ComboBox); + CHECK(Frame); + CHECK(GroupBox); + CHECK(Label); + CHECK(Line); + CHECK(LineEdit); + CHECK(PushButton); + CHECK(RadioButton); + CHECK(Slider); + CHECK(SpinBox); + CHECK(TabWidget); + CHECK(ToolButton); +#undef CHECK +#define CHECK2(x, y) QCOMPARE(PrettyPrint(QSizePolicy::x|QSizePolicy::y).s(), \ + QSizePolicy::x < QSizePolicy::y ? #x "|" #y : #y "|" #x) + // ControlTypes (sample) + CHECK2(ButtonBox, CheckBox); + CHECK2(CheckBox, ButtonBox); + CHECK2(ToolButton, Slider); +#undef CHECK2 } - -// Testing get/set functions -void tst_QSizePolicy::getSetCheck() +void tst_QSizePolicy::defaultValues() { { - // check values of a default constructed QSizePolicy + // check values of a default-constructed QSizePolicy QSizePolicy sp; QCOMPARE(sp.horizontalPolicy(), QSizePolicy::Fixed); QCOMPARE(sp.verticalPolicy(), QSizePolicy::Fixed); @@ -74,6 +118,61 @@ void tst_QSizePolicy::getSetCheck() QCOMPARE(sp.hasHeightForWidth(), false); QCOMPARE(sp.hasWidthForHeight(), false); } +} + +#define FETCH_TEST_DATA \ + QFETCH(QSizePolicy, sp); \ + QFETCH(QSizePolicy::Policy, hp); \ + QFETCH(QSizePolicy::Policy, vp); \ + QFETCH(int, hst); \ + QFETCH(int, vst); \ + QFETCH(QSizePolicy::ControlType, ct); \ + QFETCH(bool, hfw); \ + QFETCH(bool, wfh); \ + QFETCH(Qt::Orientations, ed) + + +// Testing get/set functions +void tst_QSizePolicy::getSetCheck() +{ + FETCH_TEST_DATA; + + QCOMPARE(QPixmap(), QPixmap()); + + QCOMPARE(sp.horizontalPolicy(), hp); + QCOMPARE(sp.verticalPolicy(), vp); + QCOMPARE(sp.horizontalStretch(), hst); + QCOMPARE(sp.verticalStretch(), vst); + QCOMPARE(sp.controlType(), ct); + QCOMPARE(sp.hasHeightForWidth(), hfw); + QCOMPARE(sp.hasWidthForHeight(), wfh); + QCOMPARE(sp.expandingDirections(), ed); +} + +#undef FETCH_TEST_DATA + +static void makeRow(QSizePolicy sp, QSizePolicy::Policy hp, QSizePolicy::Policy vp, + int hst, int vst, QSizePolicy::ControlType ct, bool hfw, bool wfh, + Qt::Orientations orients) +{ + QTest::newRow(qPrintable(QString().sprintf("%s-%s-%d-%d-%s-%s-%s", + PrettyPrint(hp).s(), PrettyPrint(vp).s(), hst, vst, + PrettyPrint(ct).s(), + hfw ? "true" : "false", wfh ? "true" : "false"))) + << sp << hp << vp << hst << vst << ct << hfw << wfh << orients; +} + +void tst_QSizePolicy::data() const +{ + QTest::addColumn<QSizePolicy>("sp"); + QTest::addColumn<QSizePolicy::Policy>("hp"); + QTest::addColumn<QSizePolicy::Policy>("vp"); + QTest::addColumn<int>("hst"); + QTest::addColumn<int>("vst"); + QTest::addColumn<QSizePolicy::ControlType>("ct"); + QTest::addColumn<bool>("hfw"); + QTest::addColumn<bool>("wfh"); + QTest::addColumn<Qt::Orientations>("ed"); { static const QSizePolicy::Policy policies[3] = { @@ -118,18 +217,11 @@ void tst_QSizePolicy::getSetCheck() case 0: sp.setHorizontalPolicy(hp); break; case 1: sp.setVerticalPolicy(vp); break; case 2: sp.setHorizontalStretch(hst); break; - case 3: sp.setVerticalStretch(vst); break; + case 3: sp.setVerticalStretch(vst); break; case 4: sp.setControlType(ct); break; case 5: sp.setHeightForWidth(hfw); sp.setWidthForHeight(wfh); break; default: break; } - QCOMPARE(sp.horizontalPolicy(), (i >= 0 ? hp : oldsp.horizontalPolicy())); - QCOMPARE(sp.verticalPolicy(), (i >= 1 ? vp : oldsp.verticalPolicy())); - QCOMPARE(sp.horizontalStretch(), (i >= 2 ? hst : oldsp.horizontalStretch())); - QCOMPARE(sp.verticalStretch(), (i >= 3 ? vst : oldsp.verticalStretch())); - QCOMPARE(sp.controlType(), (i >= 4 ? ct : oldsp.controlType())); - QCOMPARE(sp.hasHeightForWidth(), (i >= 5 ? hfw : oldsp.hasHeightForWidth())); - QCOMPARE(sp.hasWidthForHeight(), (i >= 5 ? wfh : oldsp.hasWidthForHeight())); Qt::Orientations orients; if (sp.horizontalPolicy() & QSizePolicy::ExpandFlag) @@ -137,7 +229,15 @@ void tst_QSizePolicy::getSetCheck() if (sp.verticalPolicy() & QSizePolicy::ExpandFlag) orients |= Qt::Vertical; - QCOMPARE(sp.expandingDirections(), orients); + makeRow(sp, + i >= 0 ? hp : oldsp.horizontalPolicy(), + i >= 1 ? vp : oldsp.verticalPolicy(), + i >= 2 ? hst : oldsp.horizontalStretch(), + i >= 3 ? vst : oldsp.verticalStretch(), + i >= 4 ? ct : oldsp.controlType(), + i >= 5 ? hfw : oldsp.hasHeightForWidth(), + i >= 5 ? wfh : oldsp.hasWidthForHeight(), + orients); #ifdef GENERATE_BASELINE stream << sp; #endif @@ -152,6 +252,7 @@ void tst_QSizePolicy::getSetCheck() out.close(); } #endif +#undef ITEMCOUNT } } @@ -212,5 +313,6 @@ void tst_QSizePolicy::verticalStretch() sp.setVerticalStretch(257); QCOMPARE(sp.verticalStretch(), 255); } + QTEST_MAIN(tst_QSizePolicy) #include "tst_qsizepolicy.moc" diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index d977f78b23..8dacab7c3b 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -69,6 +69,7 @@ #include <QtWidgets/QGraphicsView> #include <QtWidgets/QGraphicsProxyWidget> #include <QtGui/qwindow.h> +#include <qtimer.h> #include "../../../qtest-config.h" @@ -76,7 +77,7 @@ #include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile. #endif -#include <QtTest/QtTest> +#include <QtTest/QTest> #ifdef Q_OS_WIN # include <QtCore/qt_windows.h> @@ -446,6 +447,8 @@ private slots: void resizeStaticContentsChildWidget_QTBUG35282(); + void qmlSetParentHelper(); + private: bool ensureScreenSize(int width, int height); QWidget *testWidget; @@ -10418,5 +10421,20 @@ void tst_QWidget::resizeStaticContentsChildWidget_QTBUG35282() msgComparisonFailed(childWidget.numPaintEvents, ">=", 1)); } +void tst_QWidget::qmlSetParentHelper() +{ +#ifdef QT_BUILD_INTERNAL + QWidget parent; + QWidget child; + QVERIFY(QAbstractDeclarativeData::setWidgetParent); + QAbstractDeclarativeData::setWidgetParent(&child, &parent); + QVERIFY(child.parentWidget() == &parent); + QAbstractDeclarativeData::setWidgetParent(&child, 0); + QVERIFY(!child.parentWidget()); +#else + QSKIP("Needs QT_BUILD_INTERNAL"); +#endif +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 36791293ab..6a06884989 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -336,7 +336,7 @@ void tst_QWidget_window::tst_windowFilePath() void tst_QWidget_window::tst_showWithoutActivating() { -#ifndef Q_WS_X11 +#ifndef Q_DEAD_CODE_FROM_QT4_X11 QSKIP("This test is X11-only."); #else QWidget w; @@ -359,7 +359,7 @@ void tst_QWidget_window::tst_showWithoutActivating() // Note the use of the , before window because we want the XGetInputFocus to be re-executed // in each iteration of the inside loop of the QTRY_COMPARE macro -#endif // Q_WS_X11 +#endif // Q_DEAD_CODE_FROM_QT4_X11 } void tst_QWidget_window::tst_paintEventOnSecondShow() diff --git a/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp b/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp index 917a00e6db..30b0b2b896 100644 --- a/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp +++ b/tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp @@ -70,6 +70,7 @@ void tst_QWidgetMetaType::metaObject() QCOMPARE(QMetaType::metaObjectForType(qMetaTypeId<QWidget*>()), &QWidget::staticMetaObject); QCOMPARE(QMetaType::metaObjectForType(qMetaTypeId<QLabel*>()), &QLabel::staticMetaObject); QCOMPARE(QMetaType::metaObjectForType(qMetaTypeId<CustomWidget*>()), &CustomWidget::staticMetaObject); + QCOMPARE(QMetaType::metaObjectForType(qMetaTypeId<QSizePolicy>()), &QSizePolicy::staticMetaObject); } QTEST_MAIN(tst_QWidgetMetaType) diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp index b18801220c..83e6b94db9 100644 --- a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp +++ b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp @@ -60,6 +60,8 @@ private slots: void viewportCrash(); void task214488_layoutDirection_data(); void task214488_layoutDirection(); + + void margins(); }; tst_QAbstractScrollArea::tst_QAbstractScrollArea() @@ -375,5 +377,22 @@ void tst_QAbstractScrollArea::patternBackground() QCOMPARE(image.pixel(QPoint(20,20)) , QColor(Qt::red).rgb()); } +class ScrollArea : public QAbstractScrollArea +{ +public: + using QAbstractScrollArea::setViewportMargins; + using QAbstractScrollArea::viewportMargins; +}; + +void tst_QAbstractScrollArea::margins() +{ + ScrollArea area; + QCOMPARE(area.viewportMargins(), QMargins()); + + QMargins margins(10, 20, 30, 40); + area.setViewportMargins(margins); + QCOMPARE(area.viewportMargins(), margins); +} + QTEST_MAIN(tst_QAbstractScrollArea) #include "tst_qabstractscrollarea.moc" diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 23d0ffd2d2..0873c6bbb1 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -1576,6 +1576,35 @@ void tst_QComboBox::setModel() box.setModel(new QStandardItemModel(2,1, &box)); QCOMPARE(box.currentIndex(), 0); QVERIFY(box.model() != oldModel); + + // set a new root index + QModelIndex rootModelIndex; + rootModelIndex = box.model()->index(0, 0); + QVERIFY(rootModelIndex.isValid()); + box.setRootModelIndex(rootModelIndex); + QCOMPARE(box.rootModelIndex(), rootModelIndex); + + // change the model, ensure that the root index gets reset + oldModel = box.model(); + box.setModel(new QStandardItemModel(2, 1, &box)); + QCOMPARE(box.currentIndex(), 0); + QVERIFY(box.model() != oldModel); + QVERIFY(box.rootModelIndex() != rootModelIndex); + QVERIFY(box.rootModelIndex() == QModelIndex()); + + // check that setting the very same model doesn't move the current item + box.setCurrentIndex(1); + QCOMPARE(box.currentIndex(), 1); + box.setModel(box.model()); + QCOMPARE(box.currentIndex(), 1); + + // check that setting the very same model doesn't move the root index + rootModelIndex = box.model()->index(0, 0); + QVERIFY(rootModelIndex.isValid()); + box.setRootModelIndex(rootModelIndex); + QCOMPARE(box.rootModelIndex(), rootModelIndex); + box.setModel(box.model()); + QCOMPARE(box.rootModelIndex(), rootModelIndex); } void tst_QComboBox::setCustomModelAndView() diff --git a/tests/auto/widgets/widgets/qframe/.gitignore b/tests/auto/widgets/widgets/qframe/.gitignore new file mode 100644 index 0000000000..d01744a6bd --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/.gitignore @@ -0,0 +1 @@ +tst_qframe diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_0.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_0.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_1.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_1.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_2.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_2.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_0.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_0.png Binary files differnew file mode 100644 index 0000000000..0cc9090e3b --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_1.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_1.png Binary files differnew file mode 100644 index 0000000000..0cc9090e3b --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_2.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_2.png Binary files differnew file mode 100644 index 0000000000..0cc9090e3b --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_0.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_1.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_2.png b/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_noshadow_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_0_0.png b/tests/auto/widgets/widgets/qframe/images/box_plain_0_0.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_0_1.png b/tests/auto/widgets/widgets/qframe/images/box_plain_0_1.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_0_2.png b/tests/auto/widgets/widgets/qframe/images/box_plain_0_2.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_1_0.png b/tests/auto/widgets/widgets/qframe/images/box_plain_1_0.png Binary files differnew file mode 100644 index 0000000000..0cc9090e3b --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_1_1.png b/tests/auto/widgets/widgets/qframe/images/box_plain_1_1.png Binary files differnew file mode 100644 index 0000000000..0cc9090e3b --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_1_2.png b/tests/auto/widgets/widgets/qframe/images/box_plain_1_2.png Binary files differnew file mode 100644 index 0000000000..0cc9090e3b --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_2_0.png b/tests/auto/widgets/widgets/qframe/images/box_plain_2_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_2_1.png b/tests/auto/widgets/widgets/qframe/images/box_plain_2_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_plain_2_2.png b/tests/auto/widgets/widgets/qframe/images/box_plain_2_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_plain_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_0_0.png b/tests/auto/widgets/widgets/qframe/images/box_raised_0_0.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_0_1.png b/tests/auto/widgets/widgets/qframe/images/box_raised_0_1.png Binary files differnew file mode 100644 index 0000000000..b2ab941d30 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_0_2.png b/tests/auto/widgets/widgets/qframe/images/box_raised_0_2.png Binary files differnew file mode 100644 index 0000000000..21ebe53eff --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_1_0.png b/tests/auto/widgets/widgets/qframe/images/box_raised_1_0.png Binary files differnew file mode 100644 index 0000000000..4f097cee48 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_1_1.png b/tests/auto/widgets/widgets/qframe/images/box_raised_1_1.png Binary files differnew file mode 100644 index 0000000000..86f9ed6186 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_1_2.png b/tests/auto/widgets/widgets/qframe/images/box_raised_1_2.png Binary files differnew file mode 100644 index 0000000000..51a7899d05 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_2_0.png b/tests/auto/widgets/widgets/qframe/images/box_raised_2_0.png Binary files differnew file mode 100644 index 0000000000..8c3769c32d --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_2_1.png b/tests/auto/widgets/widgets/qframe/images/box_raised_2_1.png Binary files differnew file mode 100644 index 0000000000..81e0c2a152 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_raised_2_2.png b/tests/auto/widgets/widgets/qframe/images/box_raised_2_2.png Binary files differnew file mode 100644 index 0000000000..107272d0b9 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_raised_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_0_0.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_0_0.png Binary files differnew file mode 100644 index 0000000000..f1d6392779 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_0_1.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_0_1.png Binary files differnew file mode 100644 index 0000000000..b2ab941d30 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_0_2.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_0_2.png Binary files differnew file mode 100644 index 0000000000..21ebe53eff --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_1_0.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_1_0.png Binary files differnew file mode 100644 index 0000000000..6905baa1fd --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_1_1.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_1_1.png Binary files differnew file mode 100644 index 0000000000..9d5440b3aa --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_1_2.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_1_2.png Binary files differnew file mode 100644 index 0000000000..17eb7f59c0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_2_0.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_2_0.png Binary files differnew file mode 100644 index 0000000000..a6ccd54a39 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_2_1.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_2_1.png Binary files differnew file mode 100644 index 0000000000..3736bf6c99 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/box_sunken_2_2.png b/tests/auto/widgets/widgets/qframe/images/box_sunken_2_2.png Binary files differnew file mode 100644 index 0000000000..5750751c58 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/box_sunken_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_noshadow_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_0.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_1.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_2.png Binary files differnew file mode 100644 index 0000000000..61f683df52 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_plain_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_0.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_1.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_2.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_0.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_1.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_2.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_0.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_1.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_2.png Binary files differnew file mode 100644 index 0000000000..a75833c89c --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_raised_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_0.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_1.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_2.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_0_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_0.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_1.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_2.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_1_2.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_0.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_0.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_0.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_1.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_1.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_1.png diff --git a/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_2.png b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_2.png Binary files differnew file mode 100644 index 0000000000..d656ac56f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/images/winpanel_sunken_2_2.png diff --git a/tests/auto/widgets/widgets/qframe/qframe.pro b/tests/auto/widgets/widgets/qframe/qframe.pro new file mode 100644 index 0000000000..1da7eb1d11 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/qframe.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_qframe + +QT += testlib widgets + +SOURCES += tst_qframe.cpp + +TESTDATA += images/* diff --git a/tests/auto/widgets/widgets/qframe/tst_qframe.cpp b/tests/auto/widgets/widgets/qframe/tst_qframe.cpp new file mode 100644 index 0000000000..ee6b3313a6 --- /dev/null +++ b/tests/auto/widgets/widgets/qframe/tst_qframe.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTest> +#include <QFrame> +#include <QStyleOptionFrame> +#include <QPixmap> +#include <QStyle> +#include <QStyleFactory> + +class tst_QFrame : public QObject +{ + Q_OBJECT +private slots: + void testDefaults(); + void testInitStyleOption_data(); + void testInitStyleOption(); + void testPainting_data(); + void testPainting(); +}; + +Q_DECLARE_METATYPE(QFrame::Shape) +Q_DECLARE_METATYPE(QFrame::Shadow) + +void tst_QFrame::testDefaults() +{ + QFrame frame; + QCOMPARE(frame.frameStyle(), int(QFrame::NoFrame | QFrame::Plain)); + frame.setFrameShape(QFrame::Box); + QCOMPARE(frame.frameStyle(), int(QFrame::Box | QFrame::Plain)); + frame.setFrameStyle(QFrame::Box); // no shadow specified! + QCOMPARE(frame.frameStyle(), int(QFrame::Box)); +} + +static void provideFrameData() +{ + QTest::addColumn<QString>("basename"); + QTest::addColumn<int>("lineWidth"); + QTest::addColumn<int>("midLineWidth"); + QTest::addColumn<QFrame::Shape>("shape"); + QTest::addColumn<QFrame::Shadow>("shadow"); + + for (int lineWidth = 0; lineWidth < 3; ++lineWidth) { + for (int midLineWidth = 0; midLineWidth < 3; ++midLineWidth) { + QTest::newRow(qPrintable(QStringLiteral("box_noshadow_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "box_noshadow" << lineWidth << midLineWidth << QFrame::Box << (QFrame::Shadow)0; + QTest::newRow(qPrintable(QStringLiteral("box_plain_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "box_plain" << lineWidth << midLineWidth << QFrame::Box << QFrame::Plain; + QTest::newRow(qPrintable(QStringLiteral("box_raised_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "box_raised" << lineWidth << midLineWidth << QFrame::Box << QFrame::Raised; + QTest::newRow(qPrintable(QStringLiteral("box_sunken_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "box_sunken" << lineWidth << midLineWidth << QFrame::Box << QFrame::Sunken; + + QTest::newRow(qPrintable(QStringLiteral("winpanel_noshadow_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "winpanel_noshadow" << lineWidth << midLineWidth << QFrame::WinPanel << (QFrame::Shadow)0; + QTest::newRow(qPrintable(QStringLiteral("winpanel_plain_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "winpanel_plain" << lineWidth << midLineWidth << QFrame::WinPanel << QFrame::Plain; + QTest::newRow(qPrintable(QStringLiteral("winpanel_raised_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "winpanel_raised" << lineWidth << midLineWidth << QFrame::WinPanel << QFrame::Raised; + QTest::newRow(qPrintable(QStringLiteral("winpanel_sunken_%1_%2").arg(lineWidth).arg(midLineWidth))) + << "winpanel_sunken" << lineWidth << midLineWidth << QFrame::WinPanel << QFrame::Sunken; + } + } +} + +class Frame : public QFrame +{ +public: + using QFrame::initStyleOption; +}; + +void tst_QFrame::testInitStyleOption_data() +{ + provideFrameData(); +} + +void tst_QFrame::testInitStyleOption() +{ + QFETCH(QString, basename); + QFETCH(int, lineWidth); + QFETCH(int, midLineWidth); + QFETCH(QFrame::Shape, shape); + QFETCH(QFrame::Shadow, shadow); + + Frame frame; + frame.setFrameStyle(shape | shadow); + frame.setLineWidth(lineWidth); + frame.setMidLineWidth(midLineWidth); + frame.resize(16, 16); + + QStyleOptionFrame styleOption; + frame.initStyleOption(&styleOption); + + switch (shape) { + case QFrame::Box: + case QFrame::Panel: + case QFrame::StyledPanel: + case QFrame::HLine: + case QFrame::VLine: + QCOMPARE(styleOption.lineWidth, lineWidth); + QCOMPARE(styleOption.midLineWidth, midLineWidth); + break; + + case QFrame::NoFrame: + case QFrame::WinPanel: + QCOMPARE(styleOption.lineWidth, frame.frameWidth()); + QCOMPARE(styleOption.midLineWidth, 0); + break; + } + + QCOMPARE(styleOption.features, QStyleOptionFrame::None); + QCOMPARE(styleOption.frameShape, shape); + if (shadow == QFrame::Sunken) + QVERIFY(styleOption.state & QStyle::State_Sunken); + else if (shadow == QFrame::Raised) + QVERIFY(styleOption.state & QStyle::State_Raised); +} + +QT_BEGIN_NAMESPACE +Q_GUI_EXPORT QPalette qt_fusionPalette(); +QT_END_NAMESPACE + +void tst_QFrame::testPainting_data() +{ + provideFrameData(); +} + +void tst_QFrame::testPainting() +{ + QFETCH(QString, basename); + QFETCH(int, lineWidth); + QFETCH(int, midLineWidth); + QFETCH(QFrame::Shape, shape); + QFETCH(QFrame::Shadow, shadow); + + QFrame frame; + frame.setStyle(QStyleFactory::create(QStringLiteral("fusion"))); + frame.setPalette(qt_fusionPalette()); + frame.setFrameStyle(shape | shadow); + frame.setLineWidth(lineWidth); + frame.setMidLineWidth(midLineWidth); + frame.resize(16, 16); + + const QPixmap pixmap = frame.grab(); + + const QString referenceFilePath = QFINDTESTDATA(QStringLiteral("images/%1_%2_%3.png").arg(basename).arg(lineWidth).arg(midLineWidth)); + const QPixmap referencePixmap(referenceFilePath); + QVERIFY2(!referencePixmap.isNull(), qPrintable(QStringLiteral("Could not load reference pixmap %1").arg(referenceFilePath))); + QCOMPARE(pixmap, referencePixmap); +} + +QTEST_MAIN(tst_QFrame) + +#include "tst_qframe.moc" diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index ff9bc7c4a2..66accce0a2 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -487,7 +487,7 @@ void tst_QMdiArea::subWindowActivated2() // Check that we only emit _one_ signal and the active window // is unchanged after hide/show. mdiArea.hide(); -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 qt_x11_wait_for_window_manager(&mdiArea); #endif QTest::qWait(100); diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp index 9f09a57a5a..82f7285267 100644 --- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp +++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp @@ -56,7 +56,7 @@ #include "../../../qtest-config.h" QT_BEGIN_NAMESPACE -#if !defined(Q_WS_WIN) +#if !defined(Q_DEAD_CODE_FROM_QT4_WIN) extern bool qt_tab_all_widgets(); #endif QT_END_NAMESPACE diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp index 3dfb08406f..4e3d45829b 100644 --- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp @@ -768,7 +768,7 @@ void tst_QSplitter::task169702_sizes() QTest::qWait(100); testW->m_iFactor++; testW->updateGeometry(); - QTest::qWait(500);//100 is too fast for Maemo + QTest::qWait(500); //Make sure the minimimSizeHint is respected QCOMPARE(testW->size().height(), testW->minimumSizeHint().height()); diff --git a/tests/auto/widgets/widgets/widgets.pro b/tests/auto/widgets/widgets/widgets.pro index 423b3952d4..0651583867 100644 --- a/tests/auto/widgets/widgets/widgets.pro +++ b/tests/auto/widgets/widgets/widgets.pro @@ -16,6 +16,7 @@ SUBDIRS=\ qdoublespinbox \ qfocusframe \ qfontcombobox \ + qframe \ qgroupbox \ qkeysequenceedit \ qlabel \ diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index 20143b4ee1..80cf69b7fc 100644 --- a/tests/auto/xml/dom/qdom/tst_qdom.cpp +++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp @@ -718,6 +718,9 @@ void tst_QDom::ownerDocument() OWNERDOCUMENT_IMPORTNODE_TEST( QDomEntityReference, doc2.createEntityReference( "foo" ) ); OWNERDOCUMENT_IMPORTNODE_TEST( QDomProcessingInstruction, doc2.createProcessingInstruction( "foo", "bar" ) ); OWNERDOCUMENT_IMPORTNODE_TEST( QDomText, doc2.createTextNode( "foo" ) ); + + // QTBUG-12927 + QVERIFY(doc2.importNode(QDomNode(), deep).isNull()); } } diff --git a/tests/benchmarks/corelib/io/io.pro b/tests/benchmarks/corelib/io/io.pro index 487171ac5e..38a1f6b15b 100644 --- a/tests/benchmarks/corelib/io/io.pro +++ b/tests/benchmarks/corelib/io/io.pro @@ -6,5 +6,6 @@ SUBDIRS = \ qfileinfo \ qiodevice \ qprocess \ - qtemporaryfile + qtemporaryfile \ + qtextstream diff --git a/tests/benchmarks/corelib/io/qtextstream/main.cpp b/tests/benchmarks/corelib/io/qtextstream/main.cpp new file mode 100644 index 0000000000..45c0297516 --- /dev/null +++ b/tests/benchmarks/corelib/io/qtextstream/main.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2014 David Faure <david.faure@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +#include <QIODevice> +#include <QString> +#include <QBuffer> +#include <qtest.h> + +class tst_qtextstream : public QObject +{ + Q_OBJECT +private slots: + void writeSingleChar_data(); + void writeSingleChar(); + +private: +}; + +enum Output { StringOutput, DeviceOutput }; +Q_DECLARE_METATYPE(Output); + +enum Input { CharStarInput, QStringInput, CharInput, QCharInput }; +Q_DECLARE_METATYPE(Input); + +void tst_qtextstream::writeSingleChar_data() +{ + QTest::addColumn<Output>("output"); + QTest::addColumn<Input>("input"); + + QTest::newRow("string_charstar") << StringOutput << CharStarInput; + QTest::newRow("string_string") << StringOutput << QStringInput; + QTest::newRow("string_char") << StringOutput << CharInput; + QTest::newRow("string_qchar") << StringOutput << QCharInput; + QTest::newRow("device_charstar") << DeviceOutput << CharStarInput; + QTest::newRow("device_string") << DeviceOutput << QStringInput; + QTest::newRow("device_char") << DeviceOutput << CharInput; + QTest::newRow("device_qchar") << DeviceOutput << QCharInput; +} + +void tst_qtextstream::writeSingleChar() +{ + QFETCH(Output, output); + QFETCH(Input, input); + + QString str; + QBuffer buffer; + QTextStream stream; + if (output == StringOutput) { + stream.setString(&str, QIODevice::WriteOnly); + } else { + QVERIFY(buffer.open(QIODevice::WriteOnly)); + stream.setDevice(&buffer); + } + // Test many different ways to write a single char into a QTextStream + QString inputString = "h"; + const int amount = 100000; + switch (input) { + case CharStarInput: + QBENCHMARK { + for (qint64 i = 0; i < amount; ++i) + stream << "h"; + } + break; + case QStringInput: + QBENCHMARK { + for (qint64 i = 0; i < amount; ++i) + stream << inputString; + } + break; + case CharInput: + QBENCHMARK { + for (qint64 i = 0; i < amount; ++i) + stream << 'h'; + } + break; + case QCharInput: + QBENCHMARK { + for (qint64 i = 0; i < amount; ++i) + stream << QChar('h'); + } + break; + } + QString result; + if (output == StringOutput) + result = str; + else + result = QString(buffer.data()); + + QCOMPARE(result.left(10), QString("hhhhhhhhhh")); +} + +QTEST_MAIN(tst_qtextstream) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qtextstream/qtextstream.pro b/tests/benchmarks/corelib/io/qtextstream/qtextstream.pro new file mode 100644 index 0000000000..3dcba655f2 --- /dev/null +++ b/tests/benchmarks/corelib/io/qtextstream/qtextstream.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = tst_bench_qtemporaryfile + +QT = core testlib + +CONFIG += release + +SOURCES += main.cpp +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp index 9403c3fbb4..53cf26d0f1 100644 --- a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -45,6 +45,8 @@ public: private slots: void typeBuiltin_data(); void typeBuiltin(); + void typeBuiltin_QByteArray_data(); + void typeBuiltin_QByteArray(); void typeBuiltinNotNormalized_data(); void typeBuiltinNotNormalized(); void typeCustom(); @@ -94,6 +96,7 @@ void tst_QMetaType::typeBuiltin_data() } } +// QMetaType::type(const char *) void tst_QMetaType::typeBuiltin() { QFETCH(QByteArray, typeName); @@ -104,6 +107,21 @@ void tst_QMetaType::typeBuiltin() } } +void tst_QMetaType::typeBuiltin_QByteArray_data() +{ + typeBuiltin_data(); +} + +// QMetaType::type(QByteArray) +void tst_QMetaType::typeBuiltin_QByteArray() +{ + QFETCH(QByteArray, typeName); + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + QMetaType::type(typeName); + } +} + void tst_QMetaType::typeBuiltinNotNormalized_data() { QTest::addColumn<QByteArray>("typeName"); diff --git a/tests/benchmarks/corelib/tools/qbytearray/main.cpp b/tests/benchmarks/corelib/tools/qbytearray/main.cpp index e42d85f844..c9cd77cb91 100644 --- a/tests/benchmarks/corelib/tools/qbytearray/main.cpp +++ b/tests/benchmarks/corelib/tools/qbytearray/main.cpp @@ -41,11 +41,25 @@ class tst_qbytearray : public QObject { Q_OBJECT + QByteArray sourcecode; private slots: + void initTestCase(); void append(); void append_data(); + + void latin1Uppercasing_qt54(); + void latin1Uppercasing_xlate(); + void latin1Uppercasing_xlate_checked(); + void latin1Uppercasing_category(); + void latin1Uppercasing_bitcheck(); }; +void tst_qbytearray::initTestCase() +{ + QFile self(QFINDTESTDATA("main.cpp")); + QVERIFY(self.open(QIODevice::ReadOnly)); + sourcecode = self.readAll(); +} void tst_qbytearray::append_data() { @@ -73,6 +87,181 @@ void tst_qbytearray::append() } } +void tst_qbytearray::latin1Uppercasing_qt54() +{ + QByteArray s = sourcecode; + s.detach(); + + // the following was copied from qbytearray.cpp (except for the QBENCHMARK macro): + uchar *p_orig = reinterpret_cast<uchar *>(s.data()); + uchar *e = reinterpret_cast<uchar *>(s.end()); + + QBENCHMARK { + uchar *p = p_orig; + if (p) { + while (p != e) { + *p = QChar::toLower((ushort)*p); + p++; + } + } + } +} + + +/* +#!/usr/bin/perl -l +use feature "unicode_strings" +for (0..255) { + $up = uc(chr($_)); + $up = chr($_) if ord($up) > 0x100 || length $up > 1; + printf "0x%02x,", ord($up); + print "" if ($_ & 0xf) == 0xf; +} +*/ +static const uchar uppercased[256] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, + 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, + 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, + 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, + 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, + 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xf7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xff +}; +void tst_qbytearray::latin1Uppercasing_xlate() +{ + QByteArray output = sourcecode; + output.detach(); + char *dst_orig = output.data(); + const char *src_orig = sourcecode.constBegin(); + const char *end = sourcecode.constEnd(); + QBENCHMARK { + char *dst = dst_orig; + for (const char *src = src_orig; src != end; ++src, ++dst) + *dst = uppercased[uchar(*src)]; + } +} + +void tst_qbytearray::latin1Uppercasing_xlate_checked() +{ + QByteArray output = sourcecode; + output.detach(); + char *dst_orig = output.data(); + const char *src_orig = sourcecode.constBegin(); + const char *end = sourcecode.constEnd(); + QBENCHMARK { + char *dst = dst_orig; + for (const char *src = src_orig; src != end; ++src, ++dst) { + uchar ch = uchar(*src); + uchar converted = uppercased[ch]; + if (ch != converted) + *dst = converted; + } + } +} + +/* +#!/bin/perl -l +use feature "unicode_strings"; +sub categorize($) { + # 'ß' and 'ÿ' are lowercase, but we cannot uppercase them + return 0 if $_[0] == 0xDF || $_[0] == 0xFF; + $ch = chr($_[0]); + return 2 if uc($ch) ne $ch; + return 1 if lc($ch) ne $ch; + return 0; +} +for (0..255) { + printf "%d,", categorize($_); + print "" if ($_ & 0xf) == 0xf; +} +*/ +static const char categories[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, + 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0 +}; + +void tst_qbytearray::latin1Uppercasing_category() +{ + QByteArray output = sourcecode; + output.detach(); + char *dst_orig = output.data(); + const char *src_orig = sourcecode.constBegin(); + const char *end = sourcecode.constEnd(); + QBENCHMARK { + char *dst = dst_orig; + for (const char *src = src_orig; src != end; ++src, ++dst) + *dst = categories[uchar(*src)] == 1 ? *src & ~0x20 : *src; + } +} + +/* +#!/bin/perl -l +use feature "unicode_strings"; +sub categorize($) { + # 'ß' and 'ÿ' are lowercase, but we cannot uppercase them + return 0 if $_[0] == 0xDF || $_[0] == 0xFF; + $ch = chr($_[0]); + return 2 if uc($ch) ne $ch; + return 1 if lc($ch) ne $ch; + return 0; +} +for $row (0..7) { + $val = 0; + for $col (0..31) { + $val |= (1<<$col) + if categorize($row * 31 + $col) == 2; + } + printf "0x%08x,", $val; +} +*/ + +static const quint32 shouldUppercase[8] = { + 0x00000000,0x00000000,0x00000000,0x3ffffff0,0x00000000,0x04000000,0x00000000,0xbfffff80 +}; + +static bool bittest(const quint32 *data, uchar bit) +{ + static const unsigned bitsperelem = sizeof(*data) * CHAR_BIT; + return data[bit / bitsperelem] & (1 << (bit & (bitsperelem - 1))); +} + +void tst_qbytearray::latin1Uppercasing_bitcheck() +{ + QByteArray output = sourcecode; + output.detach(); + char *dst_orig = output.data(); + const char *src_orig = sourcecode.constBegin(); + const char *end = sourcecode.constEnd(); + QBENCHMARK { + char *dst = dst_orig; + for (const char *src = src_orig; src != end; ++src, ++dst) + *dst = bittest(shouldUppercase, *src) ? uchar(*src) & ~0x20 : uchar(*src); + } +} + QTEST_MAIN(tst_qbytearray) diff --git a/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro b/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro index 14bf1d8272..0d5e7646ad 100644 --- a/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro +++ b/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro @@ -2,7 +2,6 @@ TEMPLATE = app TARGET = tst_bench_qbytearray QT = core testlib -CONFIG += release SOURCES += main.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/corelib/tools/qstack/main.cpp b/tests/benchmarks/corelib/tools/qstack/main.cpp new file mode 100644 index 0000000000..062482e792 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstack/main.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Robin Burchell <robin.burchell@viroteck.net> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QStack> +#include <QDebug> +#include <QtTest> + +#include <vector> + +class tst_QStack: public QObject +{ + Q_OBJECT + +private slots: + void qstack_push(); + void qstack_pop(); + void qstack_pushpopone(); +}; + +const int N = 1000000; + +void tst_QStack::qstack_push() +{ + QStack<int> v; + QBENCHMARK { + for (int i = 0; i != N; ++i) + v.push(i); + v = QStack<int>(); + } +} + +void tst_QStack::qstack_pop() +{ + QStack<int> v; + for (int i = 0; i != N; ++i) + v.push(i); + + QBENCHMARK { + QStack<int> v2 = v; + for (int i = 0; i != N; ++i) { + v2.pop(); + } + } +} + +void tst_QStack::qstack_pushpopone() +{ + QBENCHMARK { + QStack<int> v; + for (int i = 0; i != N; ++i) { + v.push(0); + v.pop(); + } + } +} + +QTEST_MAIN(tst_QStack) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qstack/qstack.pro b/tests/benchmarks/corelib/tools/qstack/qstack.pro new file mode 100644 index 0000000000..7d8a839610 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstack/qstack.pro @@ -0,0 +1,4 @@ +TARGET = tst_bench_stack +QT = core testlib core-private +SOURCES += main.cpp +CONFIG += release diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp index 64dfad82c9..2cd41280f1 100644 --- a/tests/benchmarks/corelib/tools/qstring/main.cpp +++ b/tests/benchmarks/corelib/tools/qstring/main.cpp @@ -40,18 +40,76 @@ class tst_QString: public QObject public: tst_QString(); private slots: + void section_regexp_data() { section_data_impl(); } + void section_regexp() { section_impl<QRegExp>(); } + void section_regularexpression_data() { section_data_impl(); } + void section_regularexpression() { section_impl<QRegularExpression>(); } + void section_string_data() { section_data_impl(false); } + void section_string() { section_impl<QString>(); } + void toUpper_data(); void toUpper(); void toLower_data(); void toLower(); void toCaseFolded_data(); void toCaseFolded(); + +private: + void section_data_impl(bool includeRegExOnly = true); + template <typename RX> void section_impl(); }; tst_QString::tst_QString() { } +void tst_QString::section_data_impl(bool includeRegExOnly) +{ + QTest::addColumn<QString>("s"); + QTest::addColumn<QString>("sep"); + QTest::addColumn<bool>("isRegExp"); + + QTest::newRow("IPv4") << QStringLiteral("192.168.0.1") << QStringLiteral(".") << false; + QTest::newRow("IPv6") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral(":") << false; + if (includeRegExOnly) { + QTest::newRow("IPv6-reversed-roles") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral("\\d+") << true; + QTest::newRow("IPv6-complex") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral("(\\d+):\\1") << true; + } +} + +template <typename RX> +inline QString escape(const QString &s) +{ return RX::escape(s); } + +template <> +inline QString escape<QString>(const QString &s) +{ return s; } + +template <typename RX> +inline void optimize(RX &) {} + +template <> +inline void optimize(QRegularExpression &rx) +{ rx.optimize(); } + +template <typename RX> +void tst_QString::section_impl() +{ + QFETCH(QString, s); + QFETCH(QString, sep); + QFETCH(bool, isRegExp); + + RX rx(isRegExp ? sep : escape<RX>(sep)); + optimize(rx); + for (int i = 0; i < 20; ++i) + (void) s.count(rx); // make (s, rx) hot + + QBENCHMARK { + const QString result = s.section(rx, 0, 16); + Q_UNUSED(result); + } +} + void tst_QString::toUpper_data() { QTest::addColumn<QString>("s"); diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro index 00abd75839..d9ec5edd7c 100644 --- a/tests/benchmarks/corelib/tools/tools.pro +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -12,6 +12,7 @@ SUBDIRS = \ qrect \ qregexp \ qringbuffer \ + qstack \ qstring \ qstringbuilder \ qstringlist \ diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp index df9d38e4fc..aad143ff68 100644 --- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp @@ -35,7 +35,7 @@ #include <QtGui> -#ifdef Q_WS_WIN +#ifdef Q_DEAD_CODE_FROM_QT4_WIN #define CALLGRIND_START_INSTRUMENTATION {} #define CALLGRIND_STOP_INSTRUMENTATION {} #else diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp index 1cddad4b91..579d32645e 100644 --- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp @@ -32,14 +32,14 @@ ****************************************************************************/ #include <QtGui> -#ifdef Q_WS_WIN +#ifdef Q_DEAD_CODE_FROM_QT4_WIN #define CALLGRIND_START_INSTRUMENTATION {} #define CALLGRIND_STOP_INSTRUMENTATION {} #else #include "valgrind/callgrind.h" #endif -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 extern void qt_x11_wait_for_window_manager(QWidget *); #endif @@ -94,7 +94,7 @@ int main(int argc, char *argv[]) View view(&scene, item); view.resize(300, 300); view.show(); -#ifdef Q_WS_X11 +#ifdef Q_DEAD_CODE_FROM_QT4_X11 qt_x11_wait_for_window_manager(&view); #endif diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp index 8bfe009b4e..c0dad860e4 100644 --- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include <QtGui> -#ifdef Q_WS_WIN +#ifdef Q_DEAD_CODE_FROM_QT4_WIN #define CALLGRIND_START_INSTRUMENTATION {} #define CALLGRIND_STOP_INSTRUMENTATION {} #else diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp index 00565c4f31..44d7854eb8 100644 --- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp +++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp @@ -147,6 +147,8 @@ void tst_QImageConversion::convertGeneric_data() QTest::newRow("argb32 -> rgb666") << argb32 << QImage::Format_RGB666; QTest::newRow("argb32 -> argb8565pm") << argb32 << QImage::Format_ARGB8565_Premultiplied; QTest::newRow("argb32 -> argb4444pm") << argb32 << QImage::Format_ARGB4444_Premultiplied; + QTest::newRow("argb32 -> argb32pm") << argb32 << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("argb32 -> rgba8888pm") << argb32 << QImage::Format_RGBA8888_Premultiplied; } void tst_QImageConversion::convertGeneric() diff --git a/tests/benchmarks/gui/painting/painting.pro b/tests/benchmarks/gui/painting/painting.pro index b3fb34757c..0eb7fa92a7 100644 --- a/tests/benchmarks/gui/painting/painting.pro +++ b/tests/benchmarks/gui/painting/painting.pro @@ -3,7 +3,6 @@ SUBDIRS = \ qpainter \ qregion \ qtransform \ - qtracebench \ qtbench !qtHaveModule(widgets): SUBDIRS -= \ diff --git a/tests/benchmarks/gui/painting/qtracebench/qtracebench.pro b/tests/benchmarks/gui/painting/qtracebench/qtracebench.pro deleted file mode 100644 index d8c5c8e85b..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/qtracebench.pro +++ /dev/null @@ -1,11 +0,0 @@ -QT += widgets testlib -QT += core-private gui-private widgets-private - -TEMPLATE = app -TARGET = tst_qtracebench - -RESOURCES += qtracebench.qrc - -SOURCES += tst_qtracebench.cpp - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/gui/painting/qtracebench/qtracebench.qrc b/tests/benchmarks/gui/painting/qtracebench/qtracebench.qrc deleted file mode 100644 index 5569550bc5..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/qtracebench.qrc +++ /dev/null @@ -1,10 +0,0 @@ -<RCC> - <qresource> - <file>traces/basicdrawing.trace</file> - <file>traces/webkit.trace</file> - <file>traces/textedit.trace</file> - <file>traces/creator.trace</file> - <file>traces/qmlphoneconcept.trace</file> - <file>traces/qmlsamegame.trace</file> - </qresource> -</RCC> diff --git a/tests/benchmarks/gui/painting/qtracebench/traces/basicdrawing.trace b/tests/benchmarks/gui/painting/qtracebench/traces/basicdrawing.trace Binary files differdeleted file mode 100644 index 0241d08a97..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/traces/basicdrawing.trace +++ /dev/null diff --git a/tests/benchmarks/gui/painting/qtracebench/traces/creator.trace b/tests/benchmarks/gui/painting/qtracebench/traces/creator.trace Binary files differdeleted file mode 100644 index 55ee9e183e..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/traces/creator.trace +++ /dev/null diff --git a/tests/benchmarks/gui/painting/qtracebench/traces/qmlphoneconcept.trace b/tests/benchmarks/gui/painting/qtracebench/traces/qmlphoneconcept.trace Binary files differdeleted file mode 100644 index 835ebfa8fb..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/traces/qmlphoneconcept.trace +++ /dev/null diff --git a/tests/benchmarks/gui/painting/qtracebench/traces/qmlsamegame.trace b/tests/benchmarks/gui/painting/qtracebench/traces/qmlsamegame.trace Binary files differdeleted file mode 100644 index 1d76195443..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/traces/qmlsamegame.trace +++ /dev/null diff --git a/tests/benchmarks/gui/painting/qtracebench/traces/textedit.trace b/tests/benchmarks/gui/painting/qtracebench/traces/textedit.trace Binary files differdeleted file mode 100644 index 998716d6c1..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/traces/textedit.trace +++ /dev/null diff --git a/tests/benchmarks/gui/painting/qtracebench/traces/webkit.trace b/tests/benchmarks/gui/painting/qtracebench/traces/webkit.trace Binary files differdeleted file mode 100644 index 43e752d193..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/traces/webkit.trace +++ /dev/null diff --git a/tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp b/tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp deleted file mode 100644 index 1b6cea23de..0000000000 --- a/tests/benchmarks/gui/painting/qtracebench/tst_qtracebench.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qtest.h> - -#include <QtGui> - -#include <private/qpaintengineex_p.h> -#include <private/qpaintbuffer_p.h> - -class ReplayWidget : public QWidget -{ - Q_OBJECT -public: - ReplayWidget(const QString &filename); - - void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *event); - - bool done() const { return m_done; } - qreal result() const { return m_result; } - -public slots: - void updateRect(); - -public: - QList<QRegion> updates; - QPaintBuffer buffer; - - int currentFrame; - int currentIteration; - QTime timer; - - QList<uint> visibleUpdates; - QList<uint> iterationTimes; - QString filename; - - bool m_done; - qreal m_result; - - uint m_total; -}; - -void ReplayWidget::updateRect() -{ - if (!visibleUpdates.isEmpty()) - update(updates.at(visibleUpdates.at(currentFrame))); -} - -void ReplayWidget::paintEvent(QPaintEvent *) -{ - if (m_done) - return; - - QPainter p(this); - - // if partial updates don't work - // p.setClipRegion(frames.at(currentFrame).updateRegion); - - buffer.draw(&p, visibleUpdates.at(currentFrame)); - - ++currentFrame; - if (currentFrame >= visibleUpdates.size()) { - currentFrame = 0; - ++currentIteration; - - uint currentElapsed = timer.isNull() ? 0 : timer.elapsed(); - timer.restart(); - - m_total += currentElapsed; - - // warm up for at most 5 iterations or half a second - if (currentIteration >= 5 || m_total >= 500) { - iterationTimes << currentElapsed; - - if (iterationTimes.size() >= 5) { - qreal mean = 0; - qreal stddev = 0; - uint min = INT_MAX; - - for (int i = 0; i < iterationTimes.size(); ++i) { - mean += iterationTimes.at(i); - min = qMin(min, iterationTimes.at(i)); - } - - mean /= qreal(iterationTimes.size()); - - for (int i = 0; i < iterationTimes.size(); ++i) { - qreal delta = iterationTimes.at(i) - mean; - stddev += delta * delta; - } - - stddev = qSqrt(stddev / iterationTimes.size()); - - qSort(iterationTimes.begin(), iterationTimes.end()); - uint median = iterationTimes.at(iterationTimes.size() / 2); - - stddev = 100 * stddev / mean; - // do 100 iterations, break earlier if we spend more than 5 seconds or have a low std deviation after 2 seconds - if (iterationTimes.size() >= 100 || m_total >= 5000 || (m_total >= 2000 && stddev < 4)) { - printf("%s, iterations: %d, frames: %d, min(ms): %d, median(ms): %d, stddev: %f %%, max(fps): %f\n", qPrintable(filename), - iterationTimes.size(), visibleUpdates.size(), min, median, stddev, 1000. * visibleUpdates.size() / min); - m_result = min; - m_done = true; - return; - } - } - } - } -} - -void ReplayWidget::resizeEvent(QResizeEvent * /* event */) -{ - visibleUpdates.clear(); - - QRect bounds = rect(); - for (int i = 0; i < updates.size(); ++i) { - if (updates.at(i).intersects(bounds)) - visibleUpdates << i; - } - - if (visibleUpdates.size() != updates.size()) - printf("Warning: skipped %d frames due to limited resolution\n", updates.size() - visibleUpdates.size()); - -} - -ReplayWidget::ReplayWidget(const QString &filename_) - : currentFrame(0) - , currentIteration(0) - , filename(filename_) - , m_done(false) - , m_result(0) - , m_total(0) -{ - setWindowTitle(filename); - QFile file(filename); - - if (!file.open(QIODevice::ReadOnly)) { - printf("Failed to load input file '%s'\n", qPrintable(filename_)); - return; - } - - QDataStream in(&file); - in.setVersion(QDataStream::Qt_4_7); - - char *data; - uint size; - in.readBytes(data, size); - bool isTraceFile = size >= 7 && qstrncmp(data, "qttrace", 7) == 0; - uint version = 0; - if (size == 9 && qstrncmp(data, "qttraceV2", 9) == 0) { - in.setFloatingPointPrecision(QDataStream::SinglePrecision); - in >> version; - } - - delete [] data; - if (!isTraceFile) { - printf("File '%s' is not a trace file\n", qPrintable(filename_)); - return; - } - - in >> buffer >> updates; - - resize(buffer.boundingRect().size().toSize()); - - setAutoFillBackground(false); - setAttribute(Qt::WA_NoSystemBackground); -} - - -class tst_QTraceBench : public QObject -{ - Q_OBJECT - -private slots: - void trace(); - void trace_data(); -}; - -static const QLatin1String prefix(":/traces/"); - -void tst_QTraceBench::trace_data() -{ - QTest::addColumn<QString>("filename"); - - QTest::newRow("basicdrawing") << (prefix + "basicdrawing.trace"); - QTest::newRow("webkit") << (prefix + "webkit.trace"); - QTest::newRow("creator") << (prefix + "creator.trace"); - QTest::newRow("textedit") << (prefix + "textedit.trace"); - QTest::newRow("qmlphoneconcept") << (prefix + "qmlphoneconcept.trace"); - QTest::newRow("qmlsamegame") << (prefix + "qmlsamegame.trace"); -} - -void tst_QTraceBench::trace() -{ - QFETCH(QString, filename); - - QFile file(filename); - if (!file.exists()) { - qWarning() << "Missing file" << filename; - return; - } - - ReplayWidget widget(filename); - - if (widget.updates.isEmpty()) { - qWarning() << "No trace updates" << filename; - return; - } - - widget.show(); - QTest::qWaitForWindowShown(&widget); - - while (!widget.done()) { - widget.updateRect(); - QApplication::processEvents(); - } - - QTest::setBenchmarkResult(widget.result(), QTest::WalltimeMilliseconds); -} - -QTEST_MAIN(tst_QTraceBench) -#include "tst_qtracebench.moc" diff --git a/tests/manual/bearerex/bearerex.h b/tests/manual/bearerex/bearerex.h index 40cfe09111..f0aefa686f 100644 --- a/tests/manual/bearerex/bearerex.h +++ b/tests/manual/bearerex/bearerex.h @@ -38,13 +38,8 @@ #include "ui_detailedinfodialog.h" -#if defined(Q_WS_MAEMO_6) -#include "ui_bearerex_maemo.h" -#include "ui_sessiondialog_maemo.h" -#else #include "ui_bearerex.h" #include "ui_sessiondialog.h" -#endif #include "qnetworkconfigmanager.h" #include "qnetworksession.h" #include "datatransferer.h" diff --git a/tests/manual/bearerex/bearerex.pro b/tests/manual/bearerex/bearerex.pro index 57b82a0b51..8f0af52b40 100644 --- a/tests/manual/bearerex/bearerex.pro +++ b/tests/manual/bearerex/bearerex.pro @@ -6,15 +6,9 @@ QT += core \ widgets \ network -FORMS += detailedinfodialog.ui -maemo5|maemo6 { - FORMS += sessiondialog_maemo.ui \ - bearerex_maemo.ui -} else { - FORMS += sessiondialog.ui \ - bearerex.ui -} - +FORMS += detailedinfodialog.ui \ + sessiondialog.ui \ + bearerex.ui # Example headers and sources HEADERS += bearerex.h \ diff --git a/tests/manual/diaglib/nativewindowdump_win.cpp b/tests/manual/diaglib/nativewindowdump_win.cpp index a8e715583d..0fbba08a21 100644 --- a/tests/manual/diaglib/nativewindowdump_win.cpp +++ b/tests/manual/diaglib/nativewindowdump_win.cpp @@ -41,6 +41,10 @@ #include <QtCore/qt_windows.h> +#ifndef WS_EX_NOREDIRECTIONBITMAP +# define WS_EX_NOREDIRECTIONBITMAP 0x00200000L +#endif + namespace QtDiag { struct DumpContext { diff --git a/tests/manual/lance/main.cpp b/tests/manual/lance/main.cpp index 3ad9417da5..8668df330f 100644 --- a/tests/manual/lance/main.cpp +++ b/tests/manual/lance/main.cpp @@ -332,7 +332,7 @@ int main(int argc, char **argv) checkers_background = false; } } else { -#if defined (Q_WS_WIN) +#if defined (Q_DEAD_CODE_FROM_QT4_WIN) QString input = QString::fromLocal8Bit(argv[i]); if (input.indexOf('*') >= 0) { QFileInfo info(input); diff --git a/tests/manual/qnetworkaccessmanager/qget/downloadmanager.cpp b/tests/manual/qnetworkaccessmanager/qget/downloadmanager.cpp index 0694003e0a..0d1014a6ff 100644 --- a/tests/manual/qnetworkaccessmanager/qget/downloadmanager.cpp +++ b/tests/manual/qnetworkaccessmanager/qget/downloadmanager.cpp @@ -130,7 +130,7 @@ void DownloadManager::proxyAuthenticationRequired(const QNetworkProxy &, QAuthen } #ifndef QT_NO_SSL -void DownloadManager::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors) +void DownloadManager::sslErrors(QNetworkReply *, const QList<QSslError> &errors) { qDebug() << "sslErrors"; foreach (const QSslError &error, errors) { diff --git a/tests/manual/qnetworkreply/main.cpp b/tests/manual/qnetworkreply/main.cpp index 08a9df1144..a0680b5af9 100644 --- a/tests/manual/qnetworkreply/main.cpp +++ b/tests/manual/qnetworkreply/main.cpp @@ -181,6 +181,8 @@ void tst_qnetworkreply::setSslConfiguration() QCOMPARE(rootCertLoadingAllowed, true); #elif defined(Q_OS_MAC) QCOMPARE(rootCertLoadingAllowed, false); +#else + Q_UNUSED(rootCertLoadingAllowed) #endif // other platforms: undecided (Windows: depends on the version) if (works) { QCOMPARE(reply->error(), QNetworkReply::NoError); diff --git a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp index e2b2373e76..bdae3751e7 100644 --- a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp +++ b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp @@ -35,6 +35,7 @@ #include <QtGui/QPainter> #include <QtGui/QOpenGLTexture> +#include <QtGui/QOpenGLFunctions> #include <QtGui/QMatrix4x4> #include <QtCore/QCoreApplication> @@ -67,10 +68,11 @@ void QOpenGLTextureBlitWindow::render() m_context->makeCurrent(this); QRect viewport(0,0,dWidth(),dHeight()); - glViewport(0,0,dWidth(), dHeight()); + QOpenGLFunctions *functions = m_context->functions(); + functions->glViewport(0,0,dWidth(), dHeight()); - glClearColor(0.f, .6f, .0f, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + functions->glClearColor(0.f, .6f, .0f, 0.f); + functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); QOpenGLTexture texture(m_image); texture.setWrapMode(QOpenGLTexture::ClampToEdge); diff --git a/tests/manual/textrendering/glyphshaping/main.cpp b/tests/manual/textrendering/glyphshaping/main.cpp index 3b47061396..0d785b8f2b 100644 --- a/tests/manual/textrendering/glyphshaping/main.cpp +++ b/tests/manual/textrendering/glyphshaping/main.cpp @@ -165,7 +165,7 @@ bool dumpHtml(const QString &pathName) QString platformName = QString::fromLatin1( #if defined(Q_OS_WIN) "Win32" -#elif defined(Q_WS_X11) +#elif defined(Q_DEAD_CODE_FROM_QT4_X11) "X11" #else "" diff --git a/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp b/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp index cfe24a25da..e01e2cec5e 100644 --- a/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp +++ b/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp @@ -33,6 +33,148 @@ #include <QtWidgets/QtWidgets> +struct ManualTask { + const char *title; + const char *instructions; + unsigned sectionsMovable : 1; + unsigned selectionMode : 3; +}; + +ManualTask tasks[] = { +{ QT_TR_NOOP("0. Default"), + "Please provide instructions", + true, QAbstractItemView::SingleSelection +}, +{ QT_TR_NOOP("1. Autoscroll"), + "<ol>" + "<li>Press and hold on section 9 of vertical header.<br/>" + "<em>(all cells in the row will be selected)</em>" + "</li>" + "<li>Extend the selection by moving the mouse down.<br/>" + "<em>(selection will extend to the next rows)</em>" + "</li>" + "<li>Continue to move the mouse down and outside the window geometry.<br/>" + "<em>(The view should scroll automatically and the selection should still extend)</em>" + "</li>" + "<li>While still holding the button, do the same in the opposite direction, i.e. move mouse up and outside the window geometry.<br/>" + "<em>(Verify that the view scrolls automatically and the selection changes)</em>" + "</li>" + "<li>Verify that it works in the other dimension, i.e Press and hold section 9 of the horizontal header.<br/>" + "<em>All cells in the column will be selected</em>" + "</li>" + "<li>Extend the selection by moving the mouse to the far right and outside the window geometry.<br/>" + "<em>(selection will extend to the next columns)</em>" + "</li>" + "<li>Verify that it works in the opposite direction (i.e. move mouse to the left of the window geometry).<br/>" + "<em>(Verify that the view scrolls automatically and the selection changes)</em>" + "</li>" + "</ol>", + false, QAbstractItemView::ExtendedSelection +} + +}; + + +class Window : public QWidget +{ + Q_OBJECT +public: + Window(QWidget *parent = 0): QWidget(parent), ckMovable(0), tableView(0), cbSelectionMode(0), m_taskInstructions(0) + { + m_taskInstructions = new QLabel(); + if (sizeof(tasks) > 0) + m_taskInstructions->setText(tr(tasks[0].instructions)); + + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->addLayout(setupComboBox()); + vbox->addWidget(setupGroupBox()); + vbox->addWidget(setupTableView()); + vbox->addWidget(m_taskInstructions); + } + + void updateControls() + { + ckMovable->setChecked(tableView->verticalHeader()->sectionsMovable()); + QAbstractItemView::SelectionMode sMode = tableView->selectionMode(); + cbSelectionMode->setCurrentIndex((int)sMode); + } + +private: + QFormLayout *setupComboBox() + { + QComboBox *combo = new QComboBox; + for (size_t i = 0; i < sizeof(tasks) / sizeof(tasks[0]); ++i) { + combo->addItem(tr(tasks[i].title)); + } + + connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(on_taskCombo_currentIndexChanged(int))); + QFormLayout *form = new QFormLayout; + form->addRow(tr("Choose task:"), combo); + return form; + } + + QGroupBox *setupGroupBox() + { + QGroupBox *grp = new QGroupBox(tr("Properties")); + QFormLayout *form = new QFormLayout; + grp->setLayout(form); + ckMovable = new QCheckBox; + ckMovable->setObjectName(QLatin1String("ckMovable")); + connect(ckMovable, SIGNAL(toggled(bool)), this, SLOT(on_ckMovable_toggled(bool))); + form->addRow(tr("SectionsMovable"), ckMovable); + + cbSelectionMode = new QComboBox; + cbSelectionMode->setObjectName(QLatin1String("cbSelectionMode")); + cbSelectionMode->addItems(QStringList() << QLatin1String("NoSelection") + << QLatin1String("SingleSelection") + << QLatin1String("MultiSelection") + << QLatin1String("ExtendedSelection") + << QLatin1String("ContiguousSelection") + ); + + connect(cbSelectionMode, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cbSelectionMode_currentIndexChanged(int))); + form->addRow(tr("SelectionMode"), cbSelectionMode); + return grp; + } + + QTableView *setupTableView() + { + tableView = new QTableView; + m.setRowCount(500); + m.setColumnCount(250); + tableView->setSelectionMode(QAbstractItemView::SingleSelection); + tableView->setModel(&m); + return tableView; + } + +private Q_SLOTS: + void on_ckMovable_toggled(bool arg) + { + tableView->verticalHeader()->setSectionsMovable(arg); + tableView->horizontalHeader()->setSectionsMovable(arg); + } + + void on_cbSelectionMode_currentIndexChanged(int idx) + { + tableView->setSelectionMode((QAbstractItemView::SelectionMode)idx); + } + + void on_taskCombo_currentIndexChanged(int idx) + { + ManualTask &task = tasks[idx]; + m_taskInstructions->setText(tr(task.instructions)); + ckMovable->setChecked(task.sectionsMovable); + cbSelectionMode->setCurrentIndex((QAbstractItemView::SelectionMode)task.selectionMode); + } + +public: + QCheckBox *ckMovable; + QTableView *tableView; + QStandardItemModel m; + QComboBox *cbSelectionMode; + QLabel *m_taskInstructions; +}; + class SomeHandler : public QObject { Q_OBJECT @@ -86,19 +228,18 @@ void SomeHandler::slotSectionResized(int logsection, int oldsize, int newsize) int main(int argc, char *argv[]) { QApplication app(argc, argv); - QTableView tv; - QStandardItemModel m; - m.setRowCount(500); - m.setColumnCount(250); - tv.setModel(&m); - tv.setSelectionMode(QAbstractItemView::SingleSelection); + Window window; // Comment in the line below to test selection with keyboard (space) // tv.setEditTriggers(QAbstractItemView::NoEditTriggers); - SomeHandler handler(tv.horizontalHeader(), &tv); - tv.horizontalHeader()->setDefaultSectionSize(30); - tv.show(); - tv.horizontalHeader()->setSectionsMovable(true); - tv.verticalHeader()->setSectionsMovable(true); + QHeaderView *hHeader = window.tableView->horizontalHeader(); + QHeaderView *vHeader = window.tableView->verticalHeader(); + SomeHandler handler(hHeader, window.tableView); + hHeader->setDefaultSectionSize(30); + window.resize(600, 600); + window.show(); + hHeader->setSectionsMovable(true); + vHeader->setSectionsMovable(true); + window.updateControls(); app.exec(); } #include "qheaderviewtest1.moc" diff --git a/tests/manual/windowflags/controllerwindow.cpp b/tests/manual/windowflags/controllerwindow.cpp index 2fcc205ca7..9975bc9673 100644 --- a/tests/manual/windowflags/controllerwindow.cpp +++ b/tests/manual/windowflags/controllerwindow.cpp @@ -102,7 +102,7 @@ ControllerWindow::ControllerWindow() : previewWidget(0) updatePreview(); } -bool ControllerWindow::eventFilter(QObject *o, QEvent *e) +bool ControllerWindow::eventFilter(QObject *, QEvent *e) { if (e->type() == QEvent::WindowStateChange) updateStateControl(); diff --git a/tests/manual/windowtransparency/windowtransparency.cpp b/tests/manual/windowtransparency/windowtransparency.cpp index 3d5e607423..af9ccba707 100644 --- a/tests/manual/windowtransparency/windowtransparency.cpp +++ b/tests/manual/windowtransparency/windowtransparency.cpp @@ -85,9 +85,10 @@ public: "}"); prog.bind(); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, width(), height()); + QOpenGLFunctions *functions = gl->functions(); + functions->glClearColor(0, 0, 0, 0); + functions->glClear(GL_COLOR_BUFFER_BIT); + functions->glViewport(0, 0, width(), height()); prog.enableAttributeArray("a_Pos"); prog.enableAttributeArray("a_Color"); @@ -104,7 +105,7 @@ public: prog.setAttributeArray("a_Pos", GL_FLOAT, coords, 2, 0); prog.setAttributeArray("a_Color", GL_FLOAT, colors, 4, 0); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); prog.disableAttributeArray("a_Pos"); prog.disableAttributeArray("a_Color"); diff --git a/tests/manual/xcb_gl_integration/main.cpp b/tests/manual/xcb_gl_integration/main.cpp new file mode 100644 index 0000000000..5e819ef1ca --- /dev/null +++ b/tests/manual/xcb_gl_integration/main.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QGuiApplication> +#include <QtGui/QWindow> +#include <QtGui/QOpenGLContext> + +#include <QtGui/qpa/qplatformnativeinterface.h> + +#include <QtCore/QDebug> + +int main (int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + QWindow window; + window.setSurfaceType(QSurface::OpenGLSurface); + window.create(); + + QOpenGLContext context; + context.create(); + + QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); + + qDebug() << "EGLDisplay" << ni->nativeResourceForWindow(QByteArrayLiteral("egldisplay"), &window); + qDebug() << "EGLContext" << ni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), &context); + qDebug() << "EGLConfig" << ni->nativeResourceForContext(QByteArrayLiteral("eglconfig"), &context); + qDebug() << "GLXContext" << ni->nativeResourceForContext(QByteArrayLiteral("glxcontext"), &context); + qDebug() << "GLXConfig" << ni->nativeResourceForContext(QByteArrayLiteral("glxconfig"), &context); + + return 0; +} diff --git a/tests/manual/xcb_gl_integration/xcb_gl_integration.pro b/tests/manual/xcb_gl_integration/xcb_gl_integration.pro new file mode 100644 index 0000000000..0dd3df176f --- /dev/null +++ b/tests/manual/xcb_gl_integration/xcb_gl_integration.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +TARGET = xcb_gl_integration +INCLUDEPATH += . + +QT += gui-private + +# Input +SOURCES += main.cpp |