diff options
Diffstat (limited to 'tests')
62 files changed, 3159 insertions, 149 deletions
diff --git a/tests/auto/corelib.pro b/tests/auto/corelib.pro index 531fed2..d1d0940 100644 --- a/tests/auto/corelib.pro +++ b/tests/auto/corelib.pro @@ -75,6 +75,7 @@ SUBDIRS=\ qstringbuilder4 \ qstringlist \ qstringmatcher \ + qstringref \ qtconcurrentfilter \ qtconcurrentiteratekernel \ qtconcurrentmap \ diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index cfaa3fa..0fc99f3 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -57,6 +57,7 @@ SUBDIRS=\ qfontdialog \ qfontmetrics \ qformlayout \ + qglyphs \ qgraphicsanchorlayout \ qgraphicsanchorlayout1 \ qgraphicseffect \ diff --git a/tests/auto/macnativeevents/expectedeventlist.cpp b/tests/auto/macnativeevents/expectedeventlist.cpp index 0679dcb..82a594b 100644 --- a/tests/auto/macnativeevents/expectedeventlist.cpp +++ b/tests/auto/macnativeevents/expectedeventlist.cpp @@ -49,7 +49,9 @@ ExpectedEventList::ExpectedEventList(QObject *target) : QObject(target), eventCount(0) { target->installEventFilter(this); - debug = !qgetenv("NATIVEDEBUG").isEmpty(); + debug = qgetenv("NATIVEDEBUG").toInt(); + if (debug > 0) + qDebug() << "Debug level sat to:" << debug; } ExpectedEventList::~ExpectedEventList() @@ -104,14 +106,17 @@ void ExpectedEventList::compareMouseEvents(QEvent *received, QEvent *expected) && (e1->globalPos() == e2->globalPos()) && (e1->button() == e2->button()) && (e1->buttons() == e2->buttons()) - && (e1->modifiers() == e2->modifiers())) + && (e1->modifiers() == e2->modifiers())) { + if (debug > 0) + qDebug() << " Received (OK):" << e1 << e1->globalPos(); return; // equal + } // INVARIANT: The two events are not equal. So we fail. Depending // on whether debug mode is no or not, we let QTest fail. Otherwise // we let the test continue for debugging puposes. int eventListNr = eventCount - eventList.size(); - if (!debug) { + if (debug == 0) { qWarning() << "Expected event" << eventListNr << "differs from received event:"; QCOMPARE(e1->pos(), e2->pos()); QCOMPARE(e1->globalPos(), e2->globalPos()); @@ -135,14 +140,17 @@ void ExpectedEventList::compareKeyEvents(QEvent *received, QEvent *expected) if (e1->key() == e2->key() && (e1->modifiers() == e2->modifiers()) && (e1->count() == e2->count()) - && (e1->isAutoRepeat() == e2->isAutoRepeat())) + && (e1->isAutoRepeat() == e2->isAutoRepeat())) { + if (debug > 0) + qDebug() << " Received (OK):" << e1 << QKeySequence(e1->key()).toString(QKeySequence::NativeText); return; // equal + } // INVARIANT: The two events are not equal. So we fail. Depending // on whether debug mode is no or not, we let QTest fail. Otherwise // we let the test continue for debugging puposes. int eventListNr = eventCount - eventList.size(); - if (!debug) { + if (debug == 0) { qWarning() << "Expected event" << eventListNr << "differs from received event:"; QCOMPARE(e1->key(), e2->key()); QCOMPARE(e1->modifiers(), e2->modifiers()); @@ -150,18 +158,19 @@ void ExpectedEventList::compareKeyEvents(QEvent *received, QEvent *expected) QCOMPARE(e1->isAutoRepeat(), e2->isAutoRepeat()); } else { qWarning() << "*** FAIL *** : Expected event" << eventListNr << "differs from received event:"; - qWarning() << "Received:" << e1 << e1->key(); - qWarning() << "Expected:" << e2 << e2->key(); + qWarning() << "Received:" << e1 << QKeySequence(e1->key()).toString(QKeySequence::NativeText); + qWarning() << "Expected:" << e2 << QKeySequence(e2->key()).toString(QKeySequence::NativeText); } } bool ExpectedEventList::eventFilter(QObject *, QEvent *received) { - if (debug) + if (debug > 1) qDebug() << received; if (eventList.isEmpty()) return false; + bool eat = false; QEvent *expected = eventList.first(); if (expected->type() == received->type()) { eventList.removeFirst(); @@ -175,11 +184,13 @@ bool ExpectedEventList::eventFilter(QObject *, QEvent *received) case QEvent::NonClientAreaMouseButtonDblClick: case QEvent::NonClientAreaMouseMove: { compareMouseEvents(received, expected); + eat = true; break; } case QEvent::KeyPress: case QEvent::KeyRelease: { compareKeyEvents(received, expected); + eat = true; break; } case QEvent::Resize: { @@ -198,6 +209,6 @@ bool ExpectedEventList::eventFilter(QObject *, QEvent *received) QAbstractEventDispatcher::instance()->interrupt(); } - return false; + return eat; } diff --git a/tests/auto/macnativeevents/expectedeventlist.h b/tests/auto/macnativeevents/expectedeventlist.h index bd9f358..21eb193 100644 --- a/tests/auto/macnativeevents/expectedeventlist.h +++ b/tests/auto/macnativeevents/expectedeventlist.h @@ -51,7 +51,7 @@ class ExpectedEventList : public QObject { QList<QEvent *> eventList; QBasicTimer timer; - bool debug; + int debug; int eventCount; void timerEvent(QTimerEvent *); diff --git a/tests/auto/macnativeevents/nativeeventlist.cpp b/tests/auto/macnativeevents/nativeeventlist.cpp index 1a90ee0..f730377 100644 --- a/tests/auto/macnativeevents/nativeeventlist.cpp +++ b/tests/auto/macnativeevents/nativeeventlist.cpp @@ -47,7 +47,8 @@ NativeEventList::NativeEventList(int defaultWaitMs) , wait(false) , defaultWaitMs(defaultWaitMs) { - QString multiplier = qgetenv("NATIVEDEBUG"); + debug = qgetenv("NATIVEDEBUG").toInt(); + QString multiplier = qgetenv("NATIVEDEBUGSPEED"); if (!multiplier.isEmpty()) setTimeMultiplier(multiplier.toFloat()); } @@ -61,8 +62,11 @@ NativeEventList::~NativeEventList() void NativeEventList::sendNextEvent() { QNativeEvent *e = eventList.at(currIndex).second; - if (e) + if (e) { + if (debug > 0) + qDebug() << "Sending:" << *e; QNativeInput::sendNativeEvent(*e); + } waitNextEvent(); } diff --git a/tests/auto/macnativeevents/nativeeventlist.h b/tests/auto/macnativeevents/nativeeventlist.h index efcca43..9f9498d 100644 --- a/tests/auto/macnativeevents/nativeeventlist.h +++ b/tests/auto/macnativeevents/nativeeventlist.h @@ -76,6 +76,7 @@ private: int currIndex; bool wait; int defaultWaitMs; + int debug; }; #endif diff --git a/tests/auto/macnativeevents/qnativeevents_mac.cpp b/tests/auto/macnativeevents/qnativeevents_mac.cpp index 6c04bf3..cc12cc9 100644 --- a/tests/auto/macnativeevents/qnativeevents_mac.cpp +++ b/tests/auto/macnativeevents/qnativeevents_mac.cpp @@ -54,11 +54,11 @@ static Qt::KeyboardModifiers getModifiersFromQuartzEvent(CGEventRef inEvent) if (flags & kCGEventFlagMaskShift || flags & kCGEventFlagMaskAlphaShift) m |= Qt::ShiftModifier; if (flags & kCGEventFlagMaskControl) - m |= Qt::MetaModifier; + m |= Qt::ControlModifier; if (flags & kCGEventFlagMaskAlternate) m |= Qt::AltModifier; if (flags & kCGEventFlagMaskCommand) - m |= Qt::ControlModifier; + m |= Qt::MetaModifier; return m; } @@ -67,11 +67,11 @@ static void setModifiersFromQNativeEvent(CGEventRef inEvent, const QNativeEvent CGEventFlags flags = 0; if (event.modifiers.testFlag(Qt::ShiftModifier)) flags |= kCGEventFlagMaskShift; - if (event.modifiers.testFlag(Qt::MetaModifier)) + if (event.modifiers.testFlag(Qt::ControlModifier)) flags |= kCGEventFlagMaskControl; if (event.modifiers.testFlag(Qt::AltModifier)) flags |= kCGEventFlagMaskAlternate; - if (event.modifiers.testFlag(Qt::ControlModifier)) + if (event.modifiers.testFlag(Qt::MetaModifier)) flags |= kCGEventFlagMaskCommand; CGEventSetFlags(inEvent, flags); } diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp index ffd0596..16638ce 100644 --- a/tests/auto/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp @@ -48,6 +48,7 @@ #include "qnativeevents.h" #include "nativeeventlist.h" #include "expectedeventlist.h" +#include <Carbon/Carbon.h> #ifdef Q_OS_MAC @@ -68,6 +69,10 @@ private slots: void testMouseEnter(); void testChildDialogInFrontOfModalParent(); void testKeyPressOnToplevel(); + void testModifierShift(); + void testModifierAlt(); + void testModifierCtrl(); + void testModifierCtrlWithDontSwapCtrlAndMeta(); }; void tst_MacNativeEvents::testMouseMoveLocation() @@ -330,6 +335,108 @@ void tst_MacNativeEvents::testKeyPressOnToplevel() QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); } +void tst_MacNativeEvents::testModifierShift() +{ + QWidget w; + w.show(); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::ShiftModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::ShiftModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::ShiftModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Shift, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::ShiftModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Shift, Qt::ShiftModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testModifierAlt() +{ + QWidget w; + w.show(); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::AltModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::AltModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::AltModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Alt, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::AltModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::AltModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Alt, Qt::AltModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testModifierCtrl() +{ + // On Mac, we switch the Command and Control modifier by default, so that Command + // means Meta, and Control means Command. Lets check that this works: + QWidget w; + w.show(); + + QVERIFY(kControlUnicode == QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText)[0]); + QVERIFY(kCommandUnicode == QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText)[0]); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::ControlModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Meta, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::MetaModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::MetaModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Meta, Qt::MetaModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testModifierCtrlWithDontSwapCtrlAndMeta() +{ + // On Mac, we switch the Command and Control modifier by default, so that Command + // means Meta, and Control means Command. Lets check that the flag to swith off + // this behaviour works. While working on this test I realised that we actually + // don't (and never have) respected this flag for raw key events. Only for + // menus, through QKeySequence. I don't want to change this behaviour now, at + // least not until someone complains. So I choose to let the test just stop + // any unintended regressions instead. If we decide to resepect the the flag at one + // point, fix the test. + QCoreApplication::setAttribute(Qt::AA_MacDontSwapCtrlAndMeta); + QWidget w; + w.show(); + + QVERIFY(kCommandUnicode == QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText)[0]); + QVERIFY(kControlUnicode == QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText)[0]); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::ControlModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Meta, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::ControlModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ControlModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Meta, Qt::ControlModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); + QCoreApplication::setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, false); +} + #include "tst_macnativeevents.moc" QTEST_MAIN(tst_MacNativeEvents) diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index 752e368..ecbc08c 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -42,6 +42,8 @@ #include <QtTest/QtTest> #include <QtNetwork/QtNetwork> +#include <time.h> + #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir // Current path (C:\private\<UID>) contains only ascii chars @@ -72,14 +74,20 @@ private slots: // specific protocol tests void ftpServer(); + void ftpProxyServer(); void imapServer(); void httpServer(); + void httpServerFiles_data(); + void httpServerFiles(); + void httpServerCGI_data(); + void httpServerCGI(); void httpsServer(); void httpProxy(); void httpProxyBasicAuth(); void httpProxyNtlmAuth(); void socks5Proxy(); void socks5ProxyAuth(); + void smbServer(); // ssl supported test void supportsSsl(); @@ -158,7 +166,7 @@ static QString prettyByteArray(const QByteArray &array) static bool doSocketRead(QTcpSocket *socket, int minBytesAvailable, int timeout = 4000) { - QTime timer; + QElapsedTimer timer; timer.start(); forever { if (socket->bytesAvailable() >= minBytesAvailable) @@ -408,6 +416,8 @@ void tst_NetworkSelfTest::remotePortsOpen_data() QTest::newRow("http-proxy-auth-ntlm") << 3130; QTest::newRow("socks5-proxy") << 1080; QTest::newRow("socks5-proxy-auth") << 1081; + QTest::newRow("ftp-proxy") << 2121; + QTest::newRow("smb") << 139; } void tst_NetworkSelfTest::remotePortsOpen() @@ -455,16 +465,43 @@ void tst_NetworkSelfTest::fileLineEndingTest() QVERIFY2(!lineEndingType.compare("LF"), QString("Reference file %1 has %2 as line ending - Git checkout issue !?!").arg(referenceName, lineEndingType).toLocal8Bit()); } -static QList<Chat> ftpChat() +static QList<Chat> ftpChat(const QByteArray &userSuffix = QByteArray()) { return QList<Chat>() << Chat::expect("220") << Chat::discardUntil("\r\n") - << Chat::send("USER anonymous\r\n") + << Chat::send("USER anonymous" + userSuffix + "\r\n") << Chat::expect("331") << Chat::discardUntil("\r\n") << Chat::send("PASS user@hostname\r\n") << Chat::expect("230") << Chat::discardUntil("\r\n") + + << Chat::send("CWD pub\r\n") + << Chat::expect("250") + << Chat::discardUntil("\r\n") + << Chat::send("CWD dir-not-readable\r\n") + << Chat::expect("550") + << Chat::discardUntil("\r\n") + << Chat::send("PWD\r\n") + << Chat::expect("257 \"/pub\"\r\n") + << Chat::send("SIZE file-not-readable.txt\r\n") + << Chat::expect("213 41\r\n") + << Chat::send("CWD qxmlquery\r\n") + << Chat::expect("250") + << Chat::discardUntil("\r\n") + + << Chat::send("CWD /qtest\r\n") + << Chat::expect("250") + << Chat::discardUntil("\r\n") + << Chat::send("SIZE bigfile\r\n") + << Chat::expect("213 519240\r\n") + << Chat::send("SIZE rfc3252\r\n") + << Chat::expect("213 25962\r\n") + << Chat::send("SIZE rfc3252.txt\r\n") + << Chat::expect("213 25962\r\n") +// << Chat::send("SIZE nonASCII/german_\344\366\374\304\326\334\337\r\n") +// << Chat::expect("213 40\r\n") + << Chat::send("QUIT\r\n") << Chat::expect("221") << Chat::discardUntil("\r\n") @@ -476,6 +513,11 @@ void tst_NetworkSelfTest::ftpServer() netChat(21, ftpChat()); } +void tst_NetworkSelfTest::ftpProxyServer() +{ + netChat(2121, ftpChat("@" + QtNetworkSettings::serverName().toLatin1())); +} + void tst_NetworkSelfTest::imapServer() { netChat(143, QList<Chat>() @@ -493,6 +535,14 @@ void tst_NetworkSelfTest::imapServer() void tst_NetworkSelfTest::httpServer() { + QString uniqueExtension; + qsrand(time(0)); +#ifndef Q_OS_WINCE + uniqueExtension = QString("%1%2%3").arg((qulonglong)this).arg(qrand()).arg((qulonglong)time(0)); +#else + uniqueExtension = QString("%1%2").arg((qulonglong)this).arg(qrand()); +#endif + netChat(80, QList<Chat>() // HTTP/0.9 chat: << Chat::send("GET /\r\n") @@ -521,9 +571,185 @@ void tst_NetworkSelfTest::httpServer() << Chat::discardUntil(" ") << Chat::expect("200 ") << Chat::DiscardUntilDisconnect + + // HTTP protected area + << Chat::Reconnect + << Chat::send("GET /qtest/protected/rfc3252.txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("401 ") + << Chat::DiscardUntilDisconnect + + << Chat::Reconnect + << Chat::send("HEAD /qtest/protected/rfc3252.txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + + // DAV area + << Chat::Reconnect + << Chat::send("HEAD /dav/ HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + + // HTTP/1.0 PUT + << Chat::Reconnect + << Chat::send("PUT /dav/networkselftest-" + uniqueExtension.toLatin1() + ".txt HTTP/1.0\r\n" + "Content-Length: 5\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n" + "Hello") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("201 ") + << Chat::DiscardUntilDisconnect + + // check that the file did get uploaded + << Chat::Reconnect + << Chat::send("HEAD /dav/networkselftest-" + uniqueExtension.toLatin1() + ".txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::discardUntil("\r\nContent-Length: 5\r\n") + << Chat::DiscardUntilDisconnect + + // HTTP/1.0 DELETE + << Chat::Reconnect + << Chat::send("DELETE /dav/networkselftest-" + uniqueExtension.toLatin1() + ".txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("204 ") + << Chat::DiscardUntilDisconnect ); } +void tst_NetworkSelfTest::httpServerFiles_data() +{ + QTest::addColumn<QString>("uri"); + QTest::addColumn<int>("size"); + + QTest::newRow("fluke.gif") << "/qtest/fluke.gif" << -1; + QTest::newRow("bigfile") << "/qtest/bigfile" << 519240; + QTest::newRow("rfc3252.txt") << "/qtest/rfc3252.txt" << 25962; + QTest::newRow("protected/rfc3252.txt") << "/qtest/protected/rfc3252.txt" << 25962; + QTest::newRow("completelyEmptyQuery.xq") << "/qtest/qxmlquery/completelyEmptyQuery.xq" << -1; + QTest::newRow("notWellformedViaHttps.xml") << "/qtest/qxmlquery/notWellformedViaHttps.xml" << -1; + QTest::newRow("notWellformed.xml") << "/qtest/qxmlquery/notWellformed.xml" << -1; + QTest::newRow("viaHttp.xq") << "/qtest/qxmlquery/viaHttp.xq" << -1; + QTest::newRow("wellFormedViaHttps.xml") << "/qtest/qxmlquery/wellFormedViaHttps.xml" << -1; + QTest::newRow("wellFormed.xml") << "/qtest/qxmlquery/wellFormed.xml" << -1; +} + +void tst_NetworkSelfTest::httpServerFiles() +{ + QFETCH(QString, uri); + QFETCH(int, size); + + QList<Chat> chat; + chat << Chat::send("HEAD " + QUrl::toPercentEncoding(uri, "/") + " HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::skipBytes(1) // HTTP/1.0 or 1.1 reply + << Chat::expect(" 200 "); + if (size != -1) + chat << Chat::discardUntil("\r\nContent-Length: " + QByteArray::number(size) + "\r\n"); + chat << Chat::DiscardUntilDisconnect; + netChat(80, chat); +} + +void tst_NetworkSelfTest::httpServerCGI_data() +{ + QTest::addColumn<QByteArray>("request"); + QTest::addColumn<QByteArray>("result"); + QTest::addColumn<QByteArray>("additionalHeader"); + + QTest::newRow("echo.cgi") + << QByteArray("GET /qtest/cgi-bin/echo.cgi?Hello+World HTTP/1.0\r\n" + "Connection: close\r\n" + "\r\n") + << QByteArray("Hello+World") + << QByteArray(); + + QTest::newRow("echo.cgi(POST)") + << QByteArray("POST /qtest/cgi-bin/echo.cgi?Hello+World HTTP/1.0\r\n" + "Connection: close\r\n" + "Content-Length: 15\r\n" + "\r\n" + "Hello, World!\r\n") + << QByteArray("Hello, World!\r\n") + << QByteArray(); + + QTest::newRow("md5sum.cgi") + << QByteArray("POST /qtest/cgi-bin/md5sum.cgi HTTP/1.0\r\n" + "Connection: close\r\n" + "Content-Length: 15\r\n" + "\r\n" + "Hello, World!\r\n") + << QByteArray("29b933a8d9a0fcef0af75f1713f4940e\n") + << QByteArray(); + + QTest::newRow("protected/md5sum.cgi") + << QByteArray("POST /qtest/protected/cgi-bin/md5sum.cgi HTTP/1.0\r\n" + "Connection: close\r\n" + "Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" + "Content-Length: 15\r\n" + "\r\n" + "Hello, World!\r\n") + << QByteArray("29b933a8d9a0fcef0af75f1713f4940e\n") + << QByteArray(); + + QTest::newRow("set-cookie.cgi") + << QByteArray("POST /qtest/cgi-bin/set-cookie.cgi HTTP/1.0\r\n" + "Connection: close\r\n" + "Content-Length: 8\r\n" + "\r\n" + "foo=bar\n") + << QByteArray("Success\n") + << QByteArray("\r\nSet-Cookie: foo=bar\r\n"); +} + +void tst_NetworkSelfTest::httpServerCGI() +{ + QFETCH(QByteArray, request); + QFETCH(QByteArray, result); + QFETCH(QByteArray, additionalHeader); + QList<Chat> chat; + chat << Chat::send(request) + << Chat::expect("HTTP/1.") << Chat::skipBytes(1) + << Chat::expect(" 200 "); + + if (!additionalHeader.isEmpty()) + chat << Chat::discardUntil(additionalHeader); + + chat << Chat::discardUntil("\r\n\r\n") + << Chat::expect(result) + << Chat::RemoteDisconnect; + netChat(80, chat); +} + void tst_NetworkSelfTest::httpsServer() { #ifndef QT_NO_OPENSSL @@ -725,7 +951,63 @@ void tst_NetworkSelfTest::supportsSsl() #ifdef QT_NO_OPENSSL QFAIL("SSL not compiled in"); #else - QVERIFY(QSslSocket::supportsSsl()); + QVERIFY2(QSslSocket::supportsSsl(), "Could not load SSL libraries"); +#endif +} + +void tst_NetworkSelfTest::smbServer() +{ + static const char contents[] = "This is 34 bytes. Do not change..."; +#ifdef Q_OS_WIN + // use Windows's native UNC support to try and open a file on the server + QString filepath = QString("\\\\%1\\testshare\\test.pri").arg(QtNetworkSettings::winServerName()); + FILE *f = fopen(filepath.toLatin1(), "rb"); + QVERIFY2(f, qt_error_string().toLocal8Bit()); + + char buf[128]; + size_t ret = fread(buf, sizeof buf, 1, f); + fclose(f); + + QCOMPARE(ret, strlen(contents)); + QVERIFY(memcmp(buf, contents, strlen(contents)) == 0); +#else + // try to use Samba + QString progname = "smbclient"; + QProcess smbclient; + smbclient.start(progname, QIODevice::ReadOnly); + if (!smbclient.waitForStarted(2000)) + QSKIP("Could not find smbclient (from Samba), cannot continue testing", SkipAll); + if (!smbclient.waitForFinished(2000) || smbclient.exitStatus() != QProcess::NormalExit) + QSKIP("smbclient isn't working, cannot continue testing", SkipAll); + smbclient.close(); + + // try listing the server + smbclient.start(progname, QStringList() << "-g" << "-N" << "-L" << QtNetworkSettings::winServerName(), QIODevice::ReadOnly); + QVERIFY(smbclient.waitForFinished(5000)); + if (smbclient.exitStatus() != QProcess::NormalExit) + QSKIP("smbclient crashed", SkipAll); + QVERIFY2(smbclient.exitCode() == 0, "Test server not found"); + + QByteArray output = smbclient.readAll(); + QVERIFY(output.contains("Disk|testshare|")); + QVERIFY(output.contains("Disk|testsharewritable|")); + QVERIFY(output.contains("Disk|testsharelargefile|")); + qDebug() << "Test server found and shares are correct"; + + // try getting a file + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("PAGER", "/bin/cat"); // just in case + smbclient.setProcessEnvironment(env); + smbclient.start(progname, QStringList() << "-N" << "-c" << "more test.pri" + << QString("\\\\%1\\testshare").arg(QtNetworkSettings::winServerName()), QIODevice::ReadOnly); + QVERIFY(smbclient.waitForFinished(5000)); + if (smbclient.exitStatus() != QProcess::NormalExit) + QSKIP("smbclient crashed", SkipAll); + QVERIFY2(smbclient.exitCode() == 0, "File //qt-test-server/testshare/test.pri not found"); + + output = smbclient.readAll(); + QCOMPARE(output.constData(), contents); + qDebug() << "Test file is correct"; #endif } diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index cea259c..713ad08 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -4073,7 +4073,8 @@ void tst_QAccessibility::accelerators() window->show(); QAccessibleInterface *accLineEdit = QAccessible::queryAccessibleInterface(le); - QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString() + QLatin1String("L")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("L")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("L")); label->setText(tr("Q &")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); label->setText(tr("Q &&")); @@ -4081,11 +4082,11 @@ void tst_QAccessibility::accelerators() label->setText(tr("Q && A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); label->setText(tr("Q &&&A")); - QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString() + QLatin1String("A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); label->setText(tr("Q &&A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); label->setText(tr("Q &A&B")); - QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString() + QLatin1String("A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); #if defined(Q_WS_X11) qt_x11_wait_for_window_manager(window); diff --git a/tests/auto/qcheckbox/tst_qcheckbox.cpp b/tests/auto/qcheckbox/tst_qcheckbox.cpp index d16370c..24d78fe 100644 --- a/tests/auto/qcheckbox/tst_qcheckbox.cpp +++ b/tests/auto/qcheckbox/tst_qcheckbox.cpp @@ -92,6 +92,7 @@ private slots: void setAccel(); void group(); void foregroundRole(); + void minimumSizeHint(); protected slots: void onClicked(); @@ -425,5 +426,11 @@ void tst_QCheckBox::foregroundRole() QVERIFY(testWidget->foregroundRole() == QPalette::WindowText); } +void tst_QCheckBox::minimumSizeHint() +{ + QCheckBox box(tr("CheckBox's sizeHint is the same as it's minimumSizeHint")); + QCOMPARE(box.sizeHint(), box.minimumSizeHint()); +} + QTEST_MAIN(tst_QCheckBox) #include "tst_qcheckbox.moc" diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 1fcea9e..f00f3ef 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -157,6 +157,7 @@ private slots: void keyBoardNavigationWithMouse(); void task_QTBUG_1071_changingFocusEmitsActivated(); void maxVisibleItems(); + void task_QTBUG_10491_currentIndexAndModelColumn(); protected slots: void onEditTextChanged( const QString &newString ); @@ -2553,11 +2554,33 @@ void tst_QComboBox::maxVisibleItems() QAbstractItemView *v = comboBox.view(); int itemHeight = v->visualRect(v->model()->index(0,0)).height(); - if (v->style()->styleHint(QStyle::SH_ComboBox_Popup)) + QListView *lv = qobject_cast<QListView*>(v); + if (lv) + itemHeight += lv->spacing(); + QStyleOptionComboBox opt; + opt.initFrom(&comboBox); + if (!comboBox.style()->styleHint(QStyle::SH_ComboBox_Popup, &opt)) QCOMPARE(v->viewport()->height(), itemHeight * comboBox.maxVisibleItems()); - // QCombobox without a popup does not work, see QTBUG-760 } +void tst_QComboBox::task_QTBUG_10491_currentIndexAndModelColumn() +{ + QComboBox comboBox; + + QStandardItemModel model(4, 4, &comboBox); + for (int i = 0; i < 4; i++){ + model.setItem(i, 0, new QStandardItem(QString("Employee Nr %1").arg(i))); + model.setItem(i, 1, new QStandardItem(QString("Street Nr %1").arg(i))); + model.setItem(i, 2, new QStandardItem(QString("Town Nr %1").arg(i))); + model.setItem(i, 3, new QStandardItem(QString("Phone Nr %1").arg(i))); + } + comboBox.setModel(&model); + comboBox.setModelColumn(0); + + QComboBoxPrivate *d = static_cast<QComboBoxPrivate *>(QComboBoxPrivate::get(&comboBox)); + d->setCurrentIndex(model.index(2, 2)); + QCOMPARE(QModelIndex(d->currentIndex), model.index(2, comboBox.modelColumn())); +} QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index c8c835f..661a4c7 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -49,6 +49,11 @@ #include <qregexp.h> #include <qstringlist.h> #include "../network-settings.h" + +#if defined(Q_OS_WIN) +#define _WIN32_WINNT 0x500 +#endif + #include "../../shared/filesystem.h" #if defined(Q_OS_SYMBIAN) @@ -167,6 +172,11 @@ private slots: void longFileName(); void updateFileLists(); + +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + void isRoot_data(); + void isRoot(); +#endif }; // Testing get/set functions @@ -800,6 +810,16 @@ void tst_QDir::canonicalPath_data() QTest::newRow("absPath") << appPath + "\\testData\\..\\testData" << appPath + "/testData"; #endif QTest::newRow("nonexistant") << "testd" << QString(); + +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QTest::newRow("drive:/") << QDir::rootPath() << QDir::rootPath(); + QTest::newRow("drive:\\") << QDir::toNativeSeparators(QDir::rootPath()) << QDir::rootPath(); + QTest::newRow("drive:/./") << QDir::rootPath().append("./") << QDir::rootPath(); + QTest::newRow("drive:/../.. ") << QDir::rootPath().append("../..") << QDir::rootPath(); + QTest::newRow("drive:\\.\\") << QDir::toNativeSeparators(QDir::rootPath().append("./")) << QDir::rootPath(); + QTest::newRow("drive:\\..\\..") << QDir::toNativeSeparators(QDir::rootPath().append("../..")) << QDir::rootPath(); + QTest::newRow("drive:") << QDir().canonicalPath().left(2) << QDir().canonicalPath(); +#endif } void tst_QDir::canonicalPath() @@ -1541,6 +1561,32 @@ void tst_QDir::updateFileLists() QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt"); } +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +void tst_QDir::isRoot_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isRoot"); + + QString test = QDir::rootPath(); + QTest::newRow(QString("rootPath " + test).toLatin1()) << test << true; + test = QDir::rootPath().append("./"); + QTest::newRow(QString("./ appended " + test).toLatin1()) << test << false; + test = QDir(QDir::rootPath().append("./")).canonicalPath(); + QTest::newRow(QString("canonicalPath " + test).toLatin1()) << test << true; + test = QDir::rootPath().left(2); + QTest::newRow(QString("drive relative " + test).toLatin1()) << test << false; +} + +void tst_QDir::isRoot() +{ + QFETCH(QString, path); + QFETCH(bool, isRoot); + + QDir dir(path); + QCOMPARE(dir.isRoot(),isRoot); +} +#endif + QTEST_MAIN(tst_QDir) #include "tst_qdir.moc" diff --git a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp index eee495f..9a96130 100644 --- a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp @@ -547,7 +547,7 @@ void tst_QFileDialog2::task226366_lowerCaseHardDriveWindows() QTest::qWait(200); QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); QTest::qWait(200); - QCOMPARE(edit->text(), QString("C:")); + QCOMPARE(edit->text(), QString("C:/")); QTest::qWait(2000); //i clear my previous selection in the completer QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); @@ -555,7 +555,7 @@ void tst_QFileDialog2::task226366_lowerCaseHardDriveWindows() QTest::keyClick(edit, (char)(Qt::Key_C | Qt::SHIFT)); QTest::qWait(200); QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); - QCOMPARE(edit->text(), QString("C:")); + QCOMPARE(edit->text(), QString("C:/")); } #endif diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 4c651bf..4387553 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -46,6 +46,7 @@ #include <qfile.h> #include <qdir.h> #include <qcoreapplication.h> +#include <qlibrary.h> #include <qtemporaryfile.h> #include <qdir.h> #include <qfileinfo.h> @@ -55,7 +56,9 @@ #include <sys/stat.h> #endif #ifdef Q_OS_WIN +#define _WIN32_WINNT 0x500 #include <qt_windows.h> +#include <qlibrary.h> #endif #include <qplatformdefs.h> #include <qdebug.h> @@ -65,6 +68,7 @@ #endif #include "../network-settings.h" #include <private/qfileinfo_p.h> +#include "../../shared/filesystem.h" #if defined(Q_OS_SYMBIAN) # define SRCDIR "" @@ -151,6 +155,9 @@ private slots: void isHidden_data(); void isHidden(); +#if defined(Q_OS_MAC) + void isHiddenFromFinder(); +#endif void isBundle_data(); void isBundle(); @@ -161,6 +168,8 @@ private slots: void refresh(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + void ntfsJunctionPointsAndSymlinks_data(); + void ntfsJunctionPointsAndSymlinks(); void brokenShortcut(); #endif @@ -184,6 +193,8 @@ tst_QFileInfo::~tst_QFileInfo() QFile::remove("link.lnk"); QFile::remove("file1"); QFile::remove("dummyfile"); + QFile::remove("simplefile.txt"); + QFile::remove("longFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileName.txt"); #ifdef Q_OS_SYMBIAN QFile::remove("hidden.txt"); QFile::remove("nothidden.txt"); @@ -193,9 +204,17 @@ tst_QFileInfo::~tst_QFileInfo() #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) QDir().rmdir("./.hidden-directory"); + QFile::remove("link_to_tst_qfileinfo"); #endif -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QDir().rmdir("./hidden-directory"); + QDir().rmdir("abs_symlink"); + QDir().rmdir("rel_symlink"); + QDir().rmdir("junction_pwd"); + QDir().rmdir("junction_root"); + QDir().rmdir("mountpoint"); + QFile::remove("abs_symlink.cpp"); + QFile::remove("rel_symlink.cpp"); #endif } @@ -577,6 +596,25 @@ void tst_QFileInfo::canonicalFilePath() } # endif #endif + +#ifdef Q_OS_WIN + typedef BOOL (WINAPI *PtrCreateSymbolicLink)(LPTSTR, LPTSTR, DWORD); + PtrCreateSymbolicLink ptrCreateSymbolicLink = + (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLink"); + + if (!ptrCreateSymbolicLink || + ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1) == 0) { + QSKIP("Symbolic links aren't supported by FS", SkipAll); + } + + QString currentPath = QDir::currentPath(); + QCOMPARE(QDir::setCurrent("res"), true); + + QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1"); + + QCOMPARE(QDir::setCurrent(currentPath), true); + QFile::remove("res"); +#endif } void tst_QFileInfo::fileName_data() @@ -1082,7 +1120,7 @@ void tst_QFileInfo::isHidden_data() #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QVERIFY(QDir("./hidden-directory").exists() || QDir().mkdir("./hidden-directory")); - QVERIFY(SetFileAttributesW(QString("./hidden-directory").utf16(),FILE_ATTRIBUTE_HIDDEN)); + QVERIFY(SetFileAttributesW((wchar_t*)QString("./hidden-directory").utf16(),FILE_ATTRIBUTE_HIDDEN)); QTest::newRow("C:/path/to/hidden-directory") << QDir::currentPath() + QString::fromLatin1("/hidden-directory") << true; QTest::newRow("C:/path/to/hidden-directory/.") << QDir::currentPath() + QString::fromLatin1("/hidden-directory/.") << true; #endif @@ -1145,6 +1183,27 @@ void tst_QFileInfo::isHidden() QCOMPARE(fi.isHidden(), isHidden); } +#if defined(Q_OS_MAC) +void tst_QFileInfo::isHiddenFromFinder() +{ + const char *filename = "test_foobar.txt"; + + QFile testFile(filename); + testFile.open(QIODevice::WriteOnly | QIODevice::Append); + testFile.write(QByteArray("world")); + testFile.close(); + + struct stat buf; + stat(filename, &buf); + chflags(filename, buf.st_flags | UF_HIDDEN); + + QFileInfo fi(filename); + QCOMPARE(fi.isHidden(), true); + + testFile.remove(); +} +#endif + void tst_QFileInfo::isBundle_data() { QTest::addColumn<QString>("path"); @@ -1236,6 +1295,115 @@ void tst_QFileInfo::refresh() } #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isSymLink"); + QTest::addColumn<QString>("linkTarget"); + QTest::addColumn<QString>("canonicalFilePath"); + + QDir pwd; + pwd.mkdir("target"); + + QLibrary kernel32("kernel32"); + typedef BOOLEAN (WINAPI *PtrCreateSymbolicLink)(LPCWSTR, LPCWSTR, DWORD); + PtrCreateSymbolicLink createSymbolicLinkW = 0; + createSymbolicLinkW = (PtrCreateSymbolicLink) kernel32.resolve("CreateSymbolicLinkW"); + if (!createSymbolicLinkW) { + //we need at least one data set for the test not to fail when skipping _data function + QDir target("target"); + QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath(); + QSKIP("symbolic links not supported by operating system",SkipSingle); + } + { + //Directory symlinks + QDir target("target"); + QVERIFY(target.exists()); + + QString absTarget = QDir::toNativeSeparators(target.absolutePath()); + QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink"); + QString relTarget = "target"; + QString relSymlink = "rel_symlink"; + QString fileInTarget(absTarget); + fileInTarget.append("\\file"); + QString fileInSymlink(absSymlink); + fileInSymlink.append("\\file"); + QFile file(fileInTarget); + file.open(QIODevice::ReadWrite); + file.close(); + + QVERIFY(pwd.exists("abs_symlink") || createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1)); + QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1)); + QVERIFY(file.exists()); + + QTest::newRow("absolute dir symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath(); + QTest::newRow("relative dir symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalPath(); + QTest::newRow("file in symlink dir") << fileInSymlink << false << "" << target.canonicalPath().append("/file"); + } + { + //File symlinks + QFileInfo target(SRCDIR "tst_qfileinfo.cpp"); + QString absTarget = QDir::toNativeSeparators(target.absoluteFilePath()); + QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink.cpp"); + QString relTarget = QDir::toNativeSeparators(pwd.relativeFilePath(target.absoluteFilePath())); + QString relSymlink = "rel_symlink.cpp"; + QVERIFY(pwd.exists("abs_symlink.cpp") || createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0)); + QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0)); + + QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath(); + QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalFilePath(); + } + + //Junctions + QString target = "target"; + QString junction = "junction_pwd"; + FileSystem::createNtfsJunction(target, junction); + QFileInfo targetInfo(target); + QTest::newRow("junction_pwd") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath(); + + QFileInfo fileInJunction(targetInfo.absoluteFilePath().append("/file")); + QFile file(fileInJunction.absoluteFilePath()); + file.open(QIODevice::ReadWrite); + file.close(); + QVERIFY(file.exists()); + QTest::newRow("file in junction") << fileInJunction.absoluteFilePath() << false << "" << fileInJunction.canonicalFilePath(); + + target = QDir::rootPath(); + junction = "junction_root"; + FileSystem::createNtfsJunction(target, junction); + targetInfo.setFile(target); + QTest::newRow("junction_root") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath(); + + //Mountpoint + typedef BOOLEAN (WINAPI *PtrGetVolumeNameForVolumeMountPointW)(LPCWSTR, LPWSTR, DWORD); + PtrGetVolumeNameForVolumeMountPointW getVolumeNameForVolumeMountPointW = 0; + getVolumeNameForVolumeMountPointW = (PtrGetVolumeNameForVolumeMountPointW) kernel32.resolve("GetVolumeNameForVolumeMountPointW"); + if(getVolumeNameForVolumeMountPointW) + { + wchar_t buffer[MAX_PATH]; + QString rootPath = QDir::toNativeSeparators(QDir::rootPath()); + QVERIFY(getVolumeNameForVolumeMountPointW((wchar_t*)rootPath.utf16(), buffer, MAX_PATH)); + QString rootVolume = QString::fromWCharArray(buffer); + junction = "mountpoint"; + rootVolume.replace("\\\\?\\","\\??\\"); + FileSystem::createNtfsJunction(rootVolume, junction); + QTest::newRow("mountpoint") << junction << true << QDir::fromNativeSeparators(rootPath) << QDir::rootPath(); + } +} + +void tst_QFileInfo::ntfsJunctionPointsAndSymlinks() +{ + QFETCH(QString, path); + QFETCH(bool, isSymLink); + QFETCH(QString, linkTarget); + QFETCH(QString, canonicalFilePath); + + QFileInfo fi(path); + QCOMPARE(fi.isSymLink(), isSymLink); + QCOMPARE(fi.symLinkTarget(), linkTarget); + QCOMPARE(fi.canonicalFilePath(), canonicalFilePath); +} + void tst_QFileInfo::brokenShortcut() { QString linkName("borkenlink.lnk"); diff --git a/tests/auto/qglyphs/qglyphs.pro b/tests/auto/qglyphs/qglyphs.pro new file mode 100644 index 0000000..5084cf9 --- /dev/null +++ b/tests/auto/qglyphs/qglyphs.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +QT = core gui + +SOURCES += \ + tst_qglyphs.cpp + +wince*|symbian*: { + DEFINES += SRCDIR=\\\"\\\" +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +}
\ No newline at end of file diff --git a/tests/auto/qglyphs/test.ttf b/tests/auto/qglyphs/test.ttf Binary files differnew file mode 100644 index 0000000..9043a57 --- /dev/null +++ b/tests/auto/qglyphs/test.ttf diff --git a/tests/auto/qglyphs/tst_qglyphs.cpp b/tests/auto/qglyphs/tst_qglyphs.cpp new file mode 100644 index 0000000..54a69dc --- /dev/null +++ b/tests/auto/qglyphs/tst_qglyphs.cpp @@ -0,0 +1,406 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <qglyphs.h> +#include <qpainter.h> +#include <qtextlayout.h> +#include <qfontdatabase.h> + +// #define DEBUG_SAVE_IMAGE + +class tst_QGlyphs: public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void constructionAndDestruction(); + void copyConstructor(); + void assignment(); + void equalsOperator_data(); + void equalsOperator(); + void textLayoutGlyphIndexes(); + void drawExistingGlyphs(); + void drawNonExistentGlyphs(); + void drawMultiScriptText1(); + void drawMultiScriptText2(); + void detach(); + +private: + int m_testFontId; + QFont m_testFont; +}; + +Q_DECLARE_METATYPE(QGlyphs); + +void tst_QGlyphs::initTestCase() +{ + m_testFontId = QFontDatabase::addApplicationFont(SRCDIR "test.ttf"); + QVERIFY(m_testFontId >= 0); + + m_testFont = QFont("QtsSpecialTestFont"); + + QCOMPARE(QFontInfo(m_testFont).family(), QString::fromLatin1("QtsSpecialTestFont")); +} + +void tst_QGlyphs::cleanupTestCase() +{ + QFontDatabase::removeApplicationFont(m_testFontId); +} + +void tst_QGlyphs::constructionAndDestruction() +{ + QGlyphs glyphIndexes; +} + +static QGlyphs make_dummy_indexes() +{ + QGlyphs glyphs; + + QVector<quint32> glyphIndexes; + QVector<QPointF> positions; + QFont font; + font.setPointSize(18); + + glyphIndexes.append(1); + glyphIndexes.append(2); + glyphIndexes.append(3); + + positions.append(QPointF(1, 2)); + positions.append(QPointF(3, 4)); + positions.append(QPointF(5, 6)); + + glyphs.setFont(font); + glyphs.setGlyphIndexes(glyphIndexes); + glyphs.setPositions(positions); + + return glyphs; +} + +void tst_QGlyphs::copyConstructor() +{ + QGlyphs glyphs; + + { + QVector<quint32> glyphIndexes; + QVector<QPointF> positions; + QFont font; + font.setPointSize(18); + + glyphIndexes.append(1); + glyphIndexes.append(2); + glyphIndexes.append(3); + + positions.append(QPointF(1, 2)); + positions.append(QPointF(3, 4)); + positions.append(QPointF(5, 6)); + + glyphs.setFont(font); + glyphs.setGlyphIndexes(glyphIndexes); + glyphs.setPositions(positions); + } + + QGlyphs otherGlyphs(glyphs); + QCOMPARE(otherGlyphs.font(), glyphs.font()); + QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes()); + QCOMPARE(glyphs.positions(), otherGlyphs.positions()); +} + +void tst_QGlyphs::assignment() +{ + QGlyphs glyphs(make_dummy_indexes()); + + QGlyphs otherGlyphs = glyphs; + QCOMPARE(otherGlyphs.font(), glyphs.font()); + QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes()); + QCOMPARE(glyphs.positions(), otherGlyphs.positions()); +} + +void tst_QGlyphs::equalsOperator_data() +{ + QTest::addColumn<QGlyphs>("one"); + QTest::addColumn<QGlyphs>("two"); + QTest::addColumn<bool>("equals"); + + QGlyphs one(make_dummy_indexes()); + QGlyphs two(make_dummy_indexes()); + + QTest::newRow("Identical") << one << two << true; + + { + QGlyphs busted(two); + + QVector<QPointF> positions = busted.positions(); + positions[2] += QPointF(1, 1); + busted.setPositions(positions); + + QTest::newRow("Different positions") << one << busted << false; + } + + { + QGlyphs busted(two); + QFont font = busted.font(); + font.setPointSize(font.pointSize() * 2); + busted.setFont(font); + + QTest::newRow("Different fonts") << one << busted << false; + } + + { + QGlyphs busted(two); + + QVector<quint32> glyphIndexes = busted.glyphIndexes(); + glyphIndexes[2] += 1; + busted.setGlyphIndexes(glyphIndexes); + + QTest::newRow("Different glyph indexes") << one << busted << false; + } + +} + +void tst_QGlyphs::equalsOperator() +{ + QFETCH(QGlyphs, one); + QFETCH(QGlyphs, two); + QFETCH(bool, equals); + + QCOMPARE(one == two, equals); + QCOMPARE(one != two, !equals); +} + + +void tst_QGlyphs::textLayoutGlyphIndexes() +{ + QString s; + s.append(QLatin1Char('A')); + s.append(QChar(0xe000)); + + QTextLayout layout(s); + layout.setFont(m_testFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphs> listOfGlyphs = layout.glyphs(); + QCOMPARE(listOfGlyphs.size(), 1); + + QGlyphs glyphs = listOfGlyphs.at(0); + + QCOMPARE(glyphs.glyphIndexes().size(), 2); + QCOMPARE(glyphs.glyphIndexes().at(0), quint32(2)); + QCOMPARE(glyphs.glyphIndexes().at(1), quint32(1)); +} + +void tst_QGlyphs::drawExistingGlyphs() +{ + QPixmap textLayoutDraw(1000, 1000); + QPixmap drawGlyphs(1000, 1000); + + textLayoutDraw.fill(Qt::white); + drawGlyphs.fill(Qt::white); + + QString s; + s.append(QLatin1Char('A')); + s.append(QChar(0xe000)); + + QTextLayout layout(s); + layout.setFont(m_testFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QPainter p(&textLayoutDraw); + layout.draw(&p, QPointF(50, 50)); + } + + QGlyphs glyphs = layout.glyphs().size() > 0 + ? layout.glyphs().at(0) + : QGlyphs(); + + { + QPainter p(&drawGlyphs); + p.drawGlyphs(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawExistingGlyphs_textLayoutDraw.png"); + drawGlyphs.save("drawExistingGlyphs_drawGlyphIndexes.png"); +#endif + + QCOMPARE(textLayoutDraw, drawGlyphs); +} + +void tst_QGlyphs::drawNonExistentGlyphs() +{ + QVector<quint32> glyphIndexes; + glyphIndexes.append(3); + + QVector<QPointF> glyphPositions; + glyphPositions.append(QPointF(0, 0)); + + QGlyphs glyphs; + glyphs.setGlyphIndexes(glyphIndexes); + glyphs.setPositions(glyphPositions); + glyphs.setFont(m_testFont); + + QPixmap image(1000, 1000); + image.fill(Qt::white); + + QPixmap imageBefore = image; + { + QPainter p(&image); + p.drawGlyphs(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + image.save("drawNonExistentGlyphs.png"); +#endif + + QCOMPARE(image, imageBefore); // Should be unchanged +} + +void tst_QGlyphs::drawMultiScriptText1() +{ + QString text; + text += QChar(0x03D0); // Greek, beta + + QTextLayout textLayout(text); + textLayout.beginLayout(); + textLayout.createLine(); + textLayout.endLayout(); + + QPixmap textLayoutDraw(1000, 1000); + textLayoutDraw.fill(Qt::white); + + QPixmap drawGlyphs(1000, 1000); + drawGlyphs.fill(Qt::white); + + QList<QGlyphs> glyphsList = textLayout.glyphs(); + QCOMPARE(glyphsList.size(), 1); + + { + QPainter p(&textLayoutDraw); + textLayout.draw(&p, QPointF(50, 50)); + } + + { + QPainter p(&drawGlyphs); + foreach (QGlyphs glyphs, glyphsList) + p.drawGlyphs(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawMultiScriptText1_textLayoutDraw.png"); + drawGlyphs.save("drawMultiScriptText1_drawGlyphIndexes.png"); +#endif + + QCOMPARE(drawGlyphs, textLayoutDraw); +} + + +void tst_QGlyphs::drawMultiScriptText2() +{ +#if defined(Q_WS_MAC) + QSKIP("Unstable because of QTBUG-11145", SkipAll); +#endif + + QString text; + text += QChar(0x0621); // Arabic, Hamza + text += QChar(0x03D0); // Greek, beta + + QTextLayout textLayout(text); + textLayout.beginLayout(); + textLayout.createLine(); + textLayout.endLayout(); + + QPixmap textLayoutDraw(1000, 1000); + textLayoutDraw.fill(Qt::white); + + QPixmap drawGlyphs(1000, 1000); + drawGlyphs.fill(Qt::white); + + QList<QGlyphs> glyphsList = textLayout.glyphs(); + QCOMPARE(glyphsList.size(), 2); + + { + QPainter p(&textLayoutDraw); + textLayout.draw(&p, QPointF(50, 50)); + } + + { + QPainter p(&drawGlyphs); + foreach (QGlyphs glyphs, glyphsList) + p.drawGlyphs(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawMultiScriptText2_textLayoutDraw.png"); + drawGlyphs.save("drawMultiScriptText2_drawGlyphIndexes.png"); +#endif + + QCOMPARE(drawGlyphs, textLayoutDraw); +} + +void tst_QGlyphs::detach() +{ + QGlyphs glyphs; + + glyphs.setGlyphIndexes(QVector<quint32>() << 1 << 2 << 3); + + QGlyphs otherGlyphs; + otherGlyphs = glyphs; + + QCOMPARE(otherGlyphs.glyphIndexes(), glyphs.glyphIndexes()); + + otherGlyphs.setGlyphIndexes(QVector<quint32>() << 4 << 5 << 6); + + QCOMPARE(otherGlyphs.glyphIndexes(), QVector<quint32>() << 4 << 5 << 6); + QCOMPARE(glyphs.glyphIndexes(), QVector<quint32>() << 1 << 2 << 3); +} + +QTEST_MAIN(tst_QGlyphs) +#include "tst_qglyphs.moc" + diff --git a/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro b/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro index 4c065f4..8768425 100644 --- a/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro +++ b/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicsanchorlayout.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro b/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro index 27f48e0..90b7878 100644 --- a/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro +++ b/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicsanchorlayout1.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicseffect/qgraphicseffect.pro b/tests/auto/qgraphicseffect/qgraphicseffect.pro index 7effaca..94b3ce6 100644 --- a/tests/auto/qgraphicseffect/qgraphicseffect.pro +++ b/tests/auto/qgraphicseffect/qgraphicseffect.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicseffect.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro b/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro index d506c6d..5658ad7 100644 --- a/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro +++ b/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicseffectsource.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro b/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro index 97e68bc..d66d639 100644 --- a/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro +++ b/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicsgridlayout.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro b/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro index 6be3bfe..01875c7 100644 --- a/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro +++ b/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro @@ -1,5 +1,5 @@ load(qttest_p4) SOURCES += tst_qgraphicsitemanimation.cpp DEFINES += QT_NO_CAST_TO_ASCII - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicslayout/qgraphicslayout.pro b/tests/auto/qgraphicslayout/qgraphicslayout.pro index 1dc916a..eafd213 100644 --- a/tests/auto/qgraphicslayout/qgraphicslayout.pro +++ b/tests/auto/qgraphicslayout/qgraphicslayout.pro @@ -5,4 +5,4 @@ load(qttest_p4) SOURCES += tst_qgraphicslayout.cpp DEFINES += QT_USE_USING_NAMESPACE - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro b/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro index 6c8bf0c..816224b 100644 --- a/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro +++ b/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicslayoutitem.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro b/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro index 114e5e9..df5a827 100644 --- a/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro +++ b/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicslinearlayout.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsobject/qgraphicsobject.pro b/tests/auto/qgraphicsobject/qgraphicsobject.pro index 965b319..2418845 100644 --- a/tests/auto/qgraphicsobject/qgraphicsobject.pro +++ b/tests/auto/qgraphicsobject/qgraphicsobject.pro @@ -1,2 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicsobject.cpp +CONFIG += parallel_test
\ No newline at end of file diff --git a/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro b/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro index f6d6c8f..6b4db95 100644 --- a/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro +++ b/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicspixmapitem.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro b/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro index d54b78b..4da949b 100644 --- a/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro +++ b/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicspolygonitem.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro index d1bf3cc..1fdd176 100644 --- a/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro +++ b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro @@ -1,4 +1,4 @@ load(qttest_p4) requires(contains(QT_CONFIG,private_tests)) SOURCES += tst_qgraphicssceneindex.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicstransform/qgraphicstransform.pro b/tests/auto/qgraphicstransform/qgraphicstransform.pro index 709cff6..67c939e 100644 --- a/tests/auto/qgraphicstransform/qgraphicstransform.pro +++ b/tests/auto/qgraphicstransform/qgraphicstransform.pro @@ -1,2 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicstransform.cpp +CONFIG += parallel_test diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index 16deb03..2164b05 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -1426,11 +1426,6 @@ static inline int rand8() return int(256. * (qrand() / (RAND_MAX + 1.0))); } -static inline bool compare(int a, int b, int tolerance) -{ - return qAbs(a - b) <= tolerance; -} - // compares img.scale against the bilinear filtering used by QPainter void tst_QImage::smoothScale3() { @@ -1458,6 +1453,7 @@ void tst_QImage::smoothScale3() p.scale(scales[i], scales[i]); p.drawImage(0, 0, img); p.end(); + int err = 0; for (int y = 0; y < a.height(); ++y) { for (int x = 0; x < a.width(); ++x) { @@ -1465,11 +1461,15 @@ void tst_QImage::smoothScale3() QRgb cb = b.pixel(x, y); // tolerate a little bit of rounding errors - QVERIFY(compare(qRed(ca), qRed(cb), 3)); - QVERIFY(compare(qGreen(ca), qGreen(cb), 3)); - QVERIFY(compare(qBlue(ca), qBlue(cb), 3)); + bool r = true; + r &= qAbs(qRed(ca) - qRed(cb)) <= 18; + r &= qAbs(qGreen(ca) - qGreen(cb)) <= 18; + r &= qAbs(qBlue(ca) - qBlue(cb)) <= 18; + if (!r) + err++; } } + QCOMPARE(err, 0); } } diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index 3b2a716..bfe306d 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -94,6 +94,7 @@ private slots: void task260134_layoutChangedWithAllSelected(); void QTBUG5671_layoutChangedWithAllSelected(); void QTBUG2804_layoutChangedTreeSelection(); + void deselectRemovedMiddleRange(); private: QAbstractItemModel *model; @@ -2353,6 +2354,53 @@ void tst_QItemSelectionModel::QTBUG2804_layoutChangedTreeSelection() QCOMPARE(selModel.selectedIndexes().count(), 4); } +class RemovalObserver : public QObject +{ + Q_OBJECT + QItemSelectionModel *m_itemSelectionModel; +public: + RemovalObserver(QItemSelectionModel *selectionModel) + : m_itemSelectionModel(selectionModel) + { + connect(m_itemSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection))); + } + +public slots: + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) + { + foreach(const QModelIndex &index, deselected.indexes()) { + QVERIFY(!m_itemSelectionModel->selection().contains(index)); + } + QVERIFY(m_itemSelectionModel->selection().size() == 2); + } + +}; + +void tst_QItemSelectionModel::deselectRemovedMiddleRange() +{ + QStandardItemModel model(8, 0); + + for (int row = 0; row < 8; ++row) { + static const int column = 0; + QStandardItem *item = new QStandardItem(QString::number(row)); + model.setItem(row, column, item); + } + + QItemSelectionModel selModel(&model); + + selModel.select(QItemSelection(model.index(3, 0), model.index(6, 0)), QItemSelectionModel::Select); + + QVERIFY(selModel.selection().size() == 1); + + RemovalObserver ro(&selModel); + + QSignalSpy spy(&selModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection))); + bool ok = model.removeRows(4, 2); + + QVERIFY(ok); + QVERIFY(spy.size() == 1); +} + QTEST_MAIN(tst_QItemSelectionModel) #include "tst_qitemselectionmodel.moc" diff --git a/tests/auto/qlibrary/tst_qlibrary.cpp b/tests/auto/qlibrary/tst_qlibrary.cpp index d4884db..99e6de3 100644 --- a/tests/auto/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/qlibrary/tst_qlibrary.cpp @@ -53,6 +53,7 @@ #define a_VALID false #define so_VALID false #define dll_VALID false +#define DLL_VALID false #if defined(Q_OS_DARWIN) # undef bundle_VALID @@ -88,6 +89,8 @@ #elif defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) # undef dll_VALID # define dll_VALID true +# undef DLL_VALID +# define DLL_VALID true # define SUFFIX ".dll" # define PREFIX "" @@ -200,6 +203,7 @@ void tst_QLibrary::version() VersionFunction fnVersion = (VersionFunction)library.resolve("mylibversion"); QVERIFY(fnVersion); QCOMPARE(fnVersion(), resultversion); + QVERIFY(library.unload()); #else Q_UNUSED(lib); Q_UNUSED(loadversion); @@ -246,6 +250,7 @@ void tst_QLibrary::load() bool ok = library.load(); if ( result ) { QVERIFY( ok ); + QVERIFY(library.unload()); } else { QVERIFY( !ok ); } @@ -335,6 +340,7 @@ void tst_QLibrary::resolve() } else { QVERIFY( func == 0 ); } + library.unload(); } void tst_QLibrary::library_data() @@ -352,6 +358,7 @@ void tst_QLibrary::isLibrary_data() QTest::newRow(".a") << QString("mylib.a") << a_VALID; QTest::newRow(".bundle") << QString("mylib.bundle") << bundle_VALID; QTest::newRow(".dll") << QString("mylib.dll") << dll_VALID; + QTest::newRow(".DLL") << QString("MYLIB.DLL") << DLL_VALID; QTest::newRow(".dl2" ) << QString("mylib.dl2") << false; QTest::newRow(".dylib") << QString("mylib.dylib") << dylib_VALID; QTest::newRow(".sl") << QString("mylib.sl") << sl_VALID; @@ -465,7 +472,9 @@ void tst_QLibrary::errorString() break; } QRegExp re(errorString); - QVERIFY2(re.exactMatch(lib.errorString()), qPrintable(lib.errorString())); + QString libErrorString = lib.errorString(); + QVERIFY(!lib.isLoaded() || lib.unload()); + QVERIFY2(re.exactMatch(libErrorString), qPrintable(libErrorString)); QCOMPARE(ok, success); } @@ -521,6 +530,7 @@ void tst_QLibrary::loadHints() bool ok = library.load(); if ( result ) { QVERIFY( ok ); + QVERIFY(library.unload()); } else { QVERIFY( !ok ); } @@ -556,7 +566,12 @@ void tst_QLibrary::fileName() } QVERIFY(ok); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QCOMPARE(lib.fileName().toLower(), expectedFilename.toLower()); +#else QCOMPARE(lib.fileName(), expectedFilename); +#endif + QVERIFY(lib.unload()); } @@ -568,29 +583,42 @@ void tst_QLibrary::multipleInstancesForOneLibrary() QString lib = QDir::currentPath() + "/mylib"; #endif - QLibrary lib1(lib); - QLibrary lib2(lib); - QCOMPARE(lib1.isLoaded(), false); - QCOMPARE(lib2.isLoaded(), false); - lib1.load(); - QCOMPARE(lib1.isLoaded(), true); - QCOMPARE(lib2.isLoaded(), true); - QCOMPARE(lib1.unload(), true); - QCOMPARE(lib1.isLoaded(), false); - QCOMPARE(lib2.isLoaded(), false); - lib1.load(); - lib2.load(); - QCOMPARE(lib1.isLoaded(), true); - QCOMPARE(lib2.isLoaded(), true); - QCOMPARE(lib1.unload(), false); - QCOMPARE(lib1.isLoaded(), true); - QCOMPARE(lib2.isLoaded(), true); - QCOMPARE(lib2.unload(), true); - QCOMPARE(lib1.isLoaded(), false); - QCOMPARE(lib2.isLoaded(), false); + { + QLibrary lib1(lib); + QLibrary lib2(lib); + QCOMPARE(lib1.isLoaded(), false); + QCOMPARE(lib2.isLoaded(), false); + lib1.load(); + QCOMPARE(lib1.isLoaded(), true); + QCOMPARE(lib2.isLoaded(), true); + QCOMPARE(lib1.unload(), true); + QCOMPARE(lib1.isLoaded(), false); + QCOMPARE(lib2.isLoaded(), false); + lib1.load(); + lib2.load(); + QCOMPARE(lib1.isLoaded(), true); + QCOMPARE(lib2.isLoaded(), true); + QCOMPARE(lib1.unload(), false); + QCOMPARE(lib1.isLoaded(), true); + QCOMPARE(lib2.isLoaded(), true); + QCOMPARE(lib2.unload(), true); + QCOMPARE(lib1.isLoaded(), false); + QCOMPARE(lib2.isLoaded(), false); + + // Finally; unload on that is already unloaded + QCOMPARE(lib1.unload(), false); + } - // Finally; unload on that is already unloaded - QCOMPARE(lib1.unload(), false); + //now let's try with a 3rd one that will go out of scope + { + QLibrary lib1(lib); + QCOMPARE(lib1.isLoaded(), false); + lib1.load(); + QCOMPARE(lib1.isLoaded(), true); + } + QLibrary lib2(lib); + //lib2 should be loaded because lib1 was loaded and never unloaded + QCOMPARE(lib2.isLoaded(), true); /* lib1.setLoadHints(QLibrary::ResolveAllSymbolsHint); diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index b6d4558..f1dde48 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -155,6 +155,7 @@ private slots: void connectSlotsByName(); void invokeMetaMember(); void invokeQueuedMetaMember(); + void invokeBlockingQueuedMetaMember(); void invokeCustomTypes(); void invokeMetaConstructor(); void invokeTypedefTypes(); @@ -336,6 +337,9 @@ public slots: void testLongLong(qint64 ll1, quint64 ll2); + void moveToThread(QThread *t) + { QObject::moveToThread(t); } + signals: void sig0(); QString sig1(QString s1); @@ -583,6 +587,138 @@ void tst_QMetaObject::invokeQueuedMetaMember() QCOMPARE(obj.slotResult, QString("testLongLong:-1,0")); } +void tst_QMetaObject::invokeBlockingQueuedMetaMember() +{ + QThread t; + t.start(); + QtTestObject obj; + obj.moveToThread(&t); + + 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"); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, Q_ARG(QString, t1))); + QCOMPARE(obj.slotResult, QString("sl1:1")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl2", Qt::BlockingQueuedConnection, Q_ARG(const QString, t1), Q_ARG(QString, t2))); + QCOMPARE(obj.slotResult, QString("sl2:12")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl3", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3))); + QCOMPARE(obj.slotResult, QString("sl3:123")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl4", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4))); + QCOMPARE(obj.slotResult, QString("sl4:1234")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl5", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, "5"))); + QCOMPARE(obj.slotResult, QString("sl5:12345")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl6", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6))); + QCOMPARE(obj.slotResult, QString("sl6:123456")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl7", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), + Q_ARG(QString, t7))); + QCOMPARE(obj.slotResult, QString("sl7:1234567")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl8", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), + Q_ARG(QString, t7), Q_ARG(QString, t8))); + QCOMPARE(obj.slotResult, QString("sl8:12345678")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl9", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), + Q_ARG(QString, t7), Q_ARG(QString, t8), Q_ARG(QString, t9))); + QCOMPARE(obj.slotResult, QString("sl9:123456789")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection)); + QCOMPARE(obj.slotResult, QString("sl11")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "testSender", Qt::BlockingQueuedConnection)); + QCOMPARE(obj.slotResult, QString("0x0")); + + QString refStr("whatever"); + QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", Qt::BlockingQueuedConnection, QGenericArgument("QString&", &refStr))); + QCOMPARE(obj.slotResult, QString("testReference:whatever")); + QCOMPARE(refStr, QString("gotcha")); + + qint64 ll1 = -1; + quint64 ll2 = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, + "testLongLong", + Qt::BlockingQueuedConnection, + Q_ARG(qint64, ll1), + Q_ARG(quint64, ll2))); + QCOMPARE(obj.slotResult, QString("testLongLong:-1,0")); + + QString exp; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, exp), Q_ARG(QString, "bubu"))); + QCOMPARE(exp, QString("yessir")); + QCOMPARE(obj.slotResult, QString("sl1:bubu")); + + QObject *ptr = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject*,ptr))); + QCOMPARE(ptr, (QObject *)&obj); + QCOMPARE(obj.slotResult, QString("sl11")); + // try again with a space: + ptr = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject * , ptr))); + QCOMPARE(ptr, (QObject *)&obj); + QCOMPARE(obj.slotResult, QString("sl11")); + + const char *ptr2 = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Qt::BlockingQueuedConnection, Q_RETURN_ARG(const char*, ptr2))); + QVERIFY(ptr2 != 0); + QCOMPARE(obj.slotResult, QString("sl12")); + // try again with a space: + ptr2 = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Qt::BlockingQueuedConnection, Q_RETURN_ARG(char const * , ptr2))); + QVERIFY(ptr2 != 0); + QCOMPARE(obj.slotResult, QString("sl12")); + + // test w/ template args + QList<QString> returnValue, argument; + argument << QString("one") << QString("two") << QString("three"); + QVERIFY(QMetaObject::invokeMethod(&obj, "sl13", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(QList<QString>, returnValue), + Q_ARG(QList<QString>, argument))); + QCOMPARE(returnValue, argument); + QCOMPARE(obj.slotResult, QString("sl13")); + + //test signals + QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::BlockingQueuedConnection)); + QCOMPARE(obj.slotResult, QString("sl0")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::BlockingQueuedConnection, Q_ARG(QString, "baba"))); + QCOMPARE(obj.slotResult, QString("sl1:baba")); + + exp.clear(); + QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, exp), Q_ARG(QString, "hehe"))); + QCOMPARE(exp, QString("yessir")); + QCOMPARE(obj.slotResult, QString("sl1:hehe")); + + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist", Qt::BlockingQueuedConnection)); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"))); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"))); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"), Q_ARG(QString, "arg"), Q_ARG(QString, "arg"))); + + //should not have changed since last test. + QCOMPARE(exp, QString("yessir")); + QCOMPARE(obj.slotResult, QString("sl1:hehe")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "moveToThread", Qt::BlockingQueuedConnection, Q_ARG(QThread*, QThread::currentThread()))); + t.quit(); + QVERIFY(t.wait()); + +} + + void tst_QMetaObject::qtMetaObjectInheritance() { diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 01d7783..5af8034 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -1171,6 +1171,12 @@ void tst_QNetworkReply::getErrors_data() QTest::addColumn<int>("httpStatusCode"); QTest::addColumn<bool>("dataIsEmpty"); + // empties + QTest::newRow("empty-url") << QString() << int(QNetworkReply::ProtocolUnknownError) << 0 << true; + QTest::newRow("empty-scheme-host") << SRCDIR "/rfc3252.txt" << int(QNetworkReply::ProtocolUnknownError) << 0 << true; + QTest::newRow("empty-scheme") << "//" + QtNetworkSettings::winServerName() + "/testshare/test.pri" + << int(QNetworkReply::ProtocolUnknownError) << 0 << true; + // file: errors QTest::newRow("file-host") << "file://this-host-doesnt-exist.troll.no/foo.txt" #if !defined Q_OS_WIN diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 08b7c19..5caac15 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -129,6 +129,12 @@ private slots: void qMetaObjectConnect(); void qMetaObjectDisconnectOne(); void sameName(); + void connectByMetaMethods(); + void connectByMetaMethodSlotInsteadOfSignal(); + void connectConstructorByMetaMethod(); + void disconnectByMetaMethod(); + void disconnectNotSignalMetaMethod(); + protected: }; @@ -727,6 +733,24 @@ void tst_QObject::connectDisconnectNotify() // Test disconnectNotify for a complete disconnect ((SenderObject*)s)->disconnect((ReceiverObject*)r); + // Obtaining meta methods + int signalIndx = ((SenderObject*)s)->metaObject()->indexOfSignal( + QMetaObject::normalizedSignature(a_signal.toLatin1().constData()+1).constData()); + int methodIndx = ((ReceiverObject*)r)->metaObject()->indexOfMethod( + QMetaObject::normalizedSignature(a_slot.toLatin1().constData()+1).constData()); + QMetaMethod signal = ((SenderObject*)s)->metaObject()->method(signalIndx); + QMetaMethod method = ((ReceiverObject*)r)->metaObject()->method(methodIndx); + + // Test connectNotify when connecting by QMetaMethod + connect( (SenderObject*)s, signal, (ReceiverObject*)r, method ); + QCOMPARE( s->org_signal, s->nw_signal ); + QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); + + // Test disconnectNotify when disconnecting by QMetaMethod + QObject::disconnect( (SenderObject*)s, signal, (ReceiverObject*)r, method ); + QCOMPARE( s->org_signal, s->nw_signal ); + QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); + delete s; delete r; } @@ -3610,5 +3634,200 @@ void tst_QObject::sameName() QCOMPARE(c1.s, 4); } +void tst_QObject::connectByMetaMethods() +{ + SenderObject s; + ReceiverObject r; + const QMetaObject *smeta = s.metaObject(); + const QMetaObject *rmeta = r.metaObject(); + int sigIndx = smeta->indexOfSignal(QMetaObject::normalizedSignature("signal1()")); + int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); + QVERIFY( sigIndx != -1 ); + QVERIFY( slotIndx != -1 ); + QMetaMethod signal = smeta->method(sigIndx); + QMetaMethod slot = rmeta->method(slotIndx); + + QVERIFY(connect(&s,signal, &r,slot)); + + QVERIFY(!r.called(1)); + s.emitSignal1(); + QVERIFY(r.called(1)); +} + +void tst_QObject::connectByMetaMethodSlotInsteadOfSignal() +{ + SenderObject s; + ReceiverObject r; + const QMetaObject *smeta = s.metaObject(); + const QMetaObject *rmeta = r.metaObject(); + int badIndx = smeta->indexOfSlot(QMetaObject::normalizedSignature("aPublicSlot()")); + int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); + QVERIFY( badIndx != -1 ); + QVERIFY( slotIndx != -1 ); + QMetaMethod badMethod = smeta->method(badIndx); + QMetaMethod slot = rmeta->method(slotIndx); + + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect SenderObject::aPublicSlot() to ReceiverObject::slot1()"); + QVERIFY(!connect(&s,badMethod, &r,slot)); +} + +class Constructable: public QObject +{ + Q_OBJECT + +public: + Q_INVOKABLE Constructable(){} + +}; + +void tst_QObject::connectConstructorByMetaMethod() +{ + Constructable sc; + Constructable rc; + SenderObject s; + ReceiverObject r; + + const QMetaObject cmeta = Constructable::staticMetaObject; + const QMetaObject *smeta = s.metaObject(); + const QMetaObject *rmeta = r.metaObject(); + int constructorIndx = cmeta.indexOfConstructor(QMetaObject::normalizedSignature("Constructable()")); + int sigIndx = smeta->indexOfSignal(QMetaObject::normalizedSignature("signal1()")); + int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); + QVERIFY( constructorIndx != -1 ); + QVERIFY( sigIndx != -1 ); + QVERIFY( slotIndx != -1 ); + + QMetaMethod constructor = cmeta.constructor(constructorIndx); + QMetaMethod signal = smeta->method(sigIndx); + QMetaMethod slot = rmeta->method(slotIndx); + + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect Constructable::Constructable() to ReceiverObject::slot1()"); + QVERIFY(!connect(&sc,constructor, &r,slot)); + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect SenderObject::signal1() to Constructable::Constructable()"); + QVERIFY(!connect(&s,signal, &rc,constructor)); + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect Constructable::Constructable() to Constructable::Constructable()"); + QVERIFY(!connect(&sc,constructor, &rc,constructor)); +} + +void tst_QObject::disconnectByMetaMethod() +{ + SenderObject *s = new SenderObject; + ReceiverObject *r1 = new ReceiverObject; + ReceiverObject *r2 = new ReceiverObject; + + QMetaMethod signal1 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal1()")); + QMetaMethod signal2 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal2()")); + QMetaMethod signal3 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal3()")); + QMetaMethod signal4 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal4()")); + + QMetaMethod slot1 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot1()")); + QMetaMethod slot2 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot2()")); + QMetaMethod slot3 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot3()")); + QMetaMethod slot4 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot4()")); + + connect(s, signal1, r1, slot1); + + s->emitSignal1(); + + QVERIFY(r1->called(1)); + r1->reset(); + + // usual disconnect with all parameters given + bool ret = QObject::disconnect(s, signal1, r1, slot1); + + s->emitSignal1(); + + QVERIFY(!r1->called(1)); + r1->reset(); + + QVERIFY(ret); + ret = QObject::disconnect(s, signal1, r1, slot1); + QVERIFY(!ret); + + r1->reset(); + + connect( s, signal1, r1, slot1 ); + connect( s, signal1, r1, slot2 ); + connect( s, signal1, r1, slot3 ); + connect( s, signal2, r1, slot4 ); + + // disconnect s's signal1() from all slots of r1 + QObject::disconnect(s, signal1, r1, QMetaMethod()); + + s->emitSignal1(); + s->emitSignal2(); + + QVERIFY(!r1->called(1)); + QVERIFY(!r1->called(2)); + QVERIFY(!r1->called(3)); + QVERIFY(r1->called(4)); + r1->reset(); + // make sure all is disconnected again + QObject::disconnect(s, 0, r1, 0); + + connect(s, signal1, r1, slot1); + connect(s, signal1, r2, slot1); + connect(s, signal2, r1, slot2); + connect(s, signal2, r2, slot2); + connect(s, signal3, r1, slot3); + connect(s, signal3, r2, slot3); + + // disconnect signal1() from all receivers + QObject::disconnect(s, signal1, 0, QMetaMethod()); + s->emitSignal1(); + s->emitSignal2(); + s->emitSignal3(); + + QVERIFY(!r1->called(1)); + QVERIFY(!r2->called(1)); + QVERIFY(r1->called(2)); + QVERIFY(r2->called(2)); + QVERIFY(r1->called(2)); + QVERIFY(r2->called(2)); + + r1->reset(); + r2->reset(); + + // disconnect all signals of s from all receivers + QObject::disconnect( s, 0, 0, 0 ); + + connect( s, signal1, r1, slot1 ); + connect( s, signal1, r2, slot1 ); + + // disconnect all signals from slot1 of r1 + QObject::disconnect(s, QMetaMethod(), r1, slot1); + + s->emitSignal1(); + + QVERIFY(!r1->called(1)); + QVERIFY(r2->called(1)); + + delete r2; + delete r1; + delete s; +} + +void tst_QObject::disconnectNotSignalMetaMethod() +{ + SenderObject s; + ReceiverObject r; + + connect(&s, SIGNAL(signal1()), &r, SLOT(slot1())); + + QMetaMethod slot = s.metaObject()->method( + s.metaObject()->indexOfMethod("aPublicSlot()")); + + QTest::ignoreMessage(QtWarningMsg,"Object::disconnect: Attempt to unbind non-signal SenderObject::aPublicSlot()"); + QVERIFY(!QObject::disconnect(&s, slot, &r, QMetaMethod())); +} + QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp index 705e600..61d59a1 100644 --- a/tests/auto/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp @@ -287,12 +287,14 @@ void tst_QPluginLoader::deleteinstanceOnUnload() QSignalSpy spy1(loader1.instance(), SIGNAL(destroyed())); QSignalSpy spy2(loader2.instance(), SIGNAL(destroyed())); - QCOMPARE(loader1.unload(), false); // refcount not reached 0, not really unloaded - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 0); + if (pass == 0) { + QCOMPARE(loader2.unload(), false); // refcount not reached 0, not really unloaded + QCOMPARE(spy1.count(), 0); + QCOMPARE(spy2.count(), 0); + } QCOMPARE(instance1->pluginName(), QLatin1String("Plugin ok")); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); - QCOMPARE(loader2.unload(), true); // refcount reached 0, did really unload + QVERIFY(loader1.unload()); // refcount reached 0, did really unload QCOMPARE(spy1.count(), 1); QCOMPARE(spy2.count(), 1); } diff --git a/tests/auto/qradiobutton/tst_qradiobutton.cpp b/tests/auto/qradiobutton/tst_qradiobutton.cpp index c074496..531ebab 100644 --- a/tests/auto/qradiobutton/tst_qradiobutton.cpp +++ b/tests/auto/qradiobutton/tst_qradiobutton.cpp @@ -58,6 +58,7 @@ public: private slots: void task190739_focus(); + void minimumSizeHint(); private: }; @@ -96,6 +97,11 @@ void tst_QRadioButton::task190739_focus() } +void tst_QRadioButton::minimumSizeHint() +{ + QRadioButton button(tr("QRadioButtons sizeHint is the same as it's minimumSizeHint")); + QCOMPARE(button.sizeHint(), button.minimumSizeHint()); +} QTEST_MAIN(tst_QRadioButton) diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index 6885adf..6ebe0aa 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -2091,6 +2091,38 @@ void tst_QScriptEngine::valueConversion() QVERIFY(!val.isVariant()); QVERIFY(val.isUndefined()); } + // Checking nested QVariants + { + QVariant tmp1; + QVariant tmp2(QMetaType::QVariant, &tmp1); + QVERIFY(QMetaType::Type(tmp2.type()) == QMetaType::QVariant); + + QScriptValue val1 = qScriptValueFromValue(&eng, tmp1); + QScriptValue val2 = qScriptValueFromValue(&eng, tmp2); + QVERIFY(val1.isValid()); + QVERIFY(val2.isValid()); + QVERIFY(val1.isUndefined()); + QVERIFY(!val2.isUndefined()); + QVERIFY(!val1.isVariant()); + QVERIFY(val2.isVariant()); + } + { + QVariant tmp1(123); + QVariant tmp2(QMetaType::QVariant, &tmp1); + QVariant tmp3(QMetaType::QVariant, &tmp2); + QVERIFY(QMetaType::Type(tmp1.type()) == QMetaType::Int); + QVERIFY(QMetaType::Type(tmp2.type()) == QMetaType::QVariant); + QVERIFY(QMetaType::Type(tmp3.type()) == QMetaType::QVariant); + + QScriptValue val1 = qScriptValueFromValue(&eng, tmp2); + QScriptValue val2 = qScriptValueFromValue(&eng, tmp3); + QVERIFY(val1.isValid()); + QVERIFY(val2.isValid()); + QVERIFY(val1.isVariant()); + QVERIFY(val2.isVariant()); + QVERIFY(val1.toVariant().toInt() == 123); + QVERIFY(qScriptValueFromValue(&eng, val2.toVariant()).toVariant().toInt() == 123); + } { QScriptValue val = qScriptValueFromValue(&eng, QVariant(true)); QVERIFY(!val.isVariant()); diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp index 11813d8..0d57f0c 100644 --- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp +++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp @@ -1670,6 +1670,7 @@ void tst_QScriptExtQObject::connectAndDisconnect() m_myObject->emitMySignalWithVariantArg(123); QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); + QVERIFY(m_engine->evaluate("signalArgs[0]").isNumber()); QCOMPARE(m_engine->evaluate("signalArgs[0]").toNumber(), 123.0); QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); @@ -1685,16 +1686,29 @@ void tst_QScriptExtQObject::connectAndDisconnect() QVERIFY(m_engine->evaluate("signalArgs[0]").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignalWithScriptEngineArg.disconnect(myHandler)").isUndefined()); - // signal with QVariant arg: argument conversion should work + // signal with QVariant arg: QVariant should be unwrapped only once m_myObject->clearConnectedSignal(); QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.connect(myHandler)").isUndefined()); QCOMPARE(m_myObject->connectedSignal().constData(), SIGNAL(mySignalWithVariantArg(QVariant))); m_engine->evaluate("gotSignal = false"); - m_myObject->emitMySignalWithVariantArg(123); + QVariant tmp(123); + QVariant signalArg(QMetaType::QVariant, &tmp); + m_myObject->emitMySignalWithVariantArg(signalArg); QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); - QVERIFY(m_engine->evaluate("signalArgs[0]").isNumber()); - QCOMPARE(m_engine->evaluate("signalArgs[0]").toNumber(), 123.0); + QVERIFY(m_engine->evaluate("signalArgs[0]").isVariant()); + QCOMPARE(m_engine->evaluate("signalArgs[0]").toVariant().toDouble(), 123.0); + QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); + + // signal with QVariant arg: with an invalid QVariant + m_myObject->clearConnectedSignal(); + QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.connect(myHandler)").isUndefined()); + QCOMPARE(m_myObject->connectedSignal().constData(), SIGNAL(mySignalWithVariantArg(QVariant))); + m_engine->evaluate("gotSignal = false"); + m_myObject->emitMySignalWithVariantArg(QVariant()); + QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); + QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); + QVERIFY(m_engine->evaluate("signalArgs[0]").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); // signal with argument type that's unknown to the meta-type system diff --git a/tests/auto/qscriptvalue/testgen/testgenerator.cpp b/tests/auto/qscriptvalue/testgen/testgenerator.cpp index a291110..9d7d33d 100644 --- a/tests/auto/qscriptvalue/testgen/testgenerator.cpp +++ b/tests/auto/qscriptvalue/testgen/testgenerator.cpp @@ -162,7 +162,7 @@ static QString generateIsXXXDef(const QString& name, const QList<QString>& list) " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_array [] = {%2};\n\n"\ + "static QString %1_array[] = {%2};\n\n"\ "void tst_QScriptValue::%1_makeData(const char* expr)\n"\ "{\n"\ " static QSet<QString> %1;\n"\ @@ -193,9 +193,11 @@ static QString generateIsXXXDef(const QString& name, const QList<QString>& list) QStringList set; set.reserve(3 * list.count()); foreach(const QString& t, list) { + if (!set.isEmpty()) + set.append("\","); set.append("\n \""); set.append(escape(t)); - set.append("\","); + set.append("\""); } return result.arg(name, set.join(QString()), QString::number(list.count())); @@ -211,8 +213,8 @@ static QString generateToXXXDef(const QString& name, const QList<QPair<QString, " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_tagArray [] = {%4};\n\n"\ - "static %2 %1_valueArray [] = {%5};\n\n"\ + "static QString %1_tagArray[] = {%4};\n\n"\ + "static %2 %1_valueArray[] = {%5};\n\n"\ "void tst_QScriptValue::%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %2> %1;\n"\ @@ -236,19 +238,23 @@ static QString generateToXXXDef(const QString& name, const QList<QPair<QString, typename QList<QPair<QString, T> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, T> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%2)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%2)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<T>(t.second)); - valueSet.append(QString::fromAscii(", ")); } return result.arg(name, typeName<T>(), @@ -268,8 +274,8 @@ QString generateToXXXDef<qsreal>(const QString& name, const QList<QPair<QString, " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_tagArray [] = {%3};\n"\ - "static %2 %1_valueArray [] = {%4};\n"\ + "static QString %1_tagArray[] = {%3};\n"\ + "static %2 %1_valueArray[] = {%4};\n"\ "void tst_QScriptValue::%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %2> %1;\n"\ @@ -299,20 +305,25 @@ QString generateToXXXDef<qsreal>(const QString& name, const QList<QPair<QString, QList<QPair<QString, qsreal> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, qsreal> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%10)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%10)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<qsreal>(t.second)); - valueSet.append(QString::fromAscii(", ")); } + // toInteger shouldn't return NaN, so it would be nice to catch the case. QString hook; if (name == "toNumber") { @@ -340,8 +351,8 @@ static QString generateCastDef(const QList<QPair<QString, T> >& list) " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString qscriptvalue_cast%1_tagArray [] = {%2};\n"\ - "static %1 qscriptvalue_cast%1_valueArray [] = {%3};\n"\ + "static QString qscriptvalue_cast%1_tagArray[] = {%2};\n"\ + "static %1 qscriptvalue_cast%1_valueArray[] = {%3};\n"\ "void tst_QScriptValue::qscriptvalue_cast%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %1> value;\n"\ @@ -365,19 +376,23 @@ static QString generateCastDef(const QList<QPair<QString, T> >& list) typename QList<QPair<QString, T> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, T> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%2)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%2)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<T>(t.second)); - valueSet.append(QString::fromAscii(", ")); } return result.arg(typeName<T>(), tagSet.join(QString()), valueSet.join(QString()), QString::number(list.count())); } @@ -392,8 +407,8 @@ QString generateCastDef<qsreal>(const QList<QPair<QString, qsreal> >& list) " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString qscriptvalue_cast%1_tagArray [] = {%2};\n"\ - "static %1 qscriptvalue_cast%1_valueArray [] = {%3};\n"\ + "static QString qscriptvalue_cast%1_tagArray[] = {%2};\n"\ + "static %1 qscriptvalue_cast%1_valueArray[] = {%3};\n"\ "void tst_QScriptValue::qscriptvalue_cast%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %1> value;\n"\ @@ -427,19 +442,23 @@ QString generateCastDef<qsreal>(const QList<QPair<QString, qsreal> >& list) QList<QPair<QString, qsreal> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, qsreal> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%10)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%10)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<qsreal>(t.second)); - valueSet.append(QString::fromAscii(", ")); } return result.arg(typeName<qsreal>(), tagSet.join(QString()), @@ -457,7 +476,7 @@ static QString generateCompareDef(const QString& comparisionType, const QList<QS " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_array [] = {%2};\n\n"\ + "static QString %1_array[] = {%2};\n\n"\ "void tst_QScriptValue::%1_makeData(const char *expr)\n"\ "{\n"\ " static QSet<QString> equals;\n"\ @@ -488,9 +507,13 @@ static QString generateCompareDef(const QString& comparisionType, const QList<QS QString result = templ; QStringList set; - set.reserve(tags.count()); + set.reserve(4 * tags.count()); foreach(const QString& tmp, tags) { - set.append("\n \"" + escape(tmp) + "\","); + if (!set.isEmpty()) + set.append(","); + set.append("\n \""); + set.append(escape(tmp)); + set.append("\""); } return result.arg(comparisionType, set.join(""), QString::number(tags.count())); } @@ -500,7 +523,7 @@ static QString generateInitDef(const QVector<QString>& allDataTags) static const QString templ = "void tst_QScriptValue::initScriptValues()\n"\ "{\n"\ " m_values.clear();\n"\ - " if (engine) \n"\ + " if (engine)\n"\ " delete engine;\n"\ " engine = new QScriptEngine;\n"\ "%1\n}\n\n"; diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index c887936..9d8c0b2 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -57,6 +57,10 @@ Q_DECLARE_METATYPE(qlonglong) //TESTED_CLASS= //TESTED_FILES= +#define CREATE_REF(string) \ + const QString padded = QString::fromLatin1(" %1 ").arg(string); \ + QStringRef ref = padded.midRef(1, padded.size() - 2); + class tst_QString : public QObject { Q_OBJECT @@ -135,6 +139,7 @@ private slots: void leftRef(); void stringRef(); void contains(); + void count(); void lastIndexOf_data(); void lastIndexOf(); void indexOf_data(); @@ -1064,12 +1069,14 @@ void tst_QString::indexOf() QFETCH( int, startpos ); QFETCH( bool, bcs ); QFETCH( int, resultpos ); + CREATE_REF(needle); Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive; bool needleIsLatin = (QString::fromLatin1(needle.toLatin1()) == needle); QCOMPARE( haystack.indexOf(needle, startpos, cs), resultpos ); + QCOMPARE( haystack.indexOf(ref, startpos, cs), resultpos ); if (needleIsLatin) { QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos, cs), resultpos ); QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos, cs), resultpos ); @@ -1097,12 +1104,14 @@ void tst_QString::indexOf() if (cs == Qt::CaseSensitive) { QCOMPARE( haystack.indexOf(needle, startpos), resultpos ); + QCOMPARE( haystack.indexOf(ref, startpos), resultpos ); if (needleIsLatin) { QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos), resultpos ); QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos), resultpos ); } if (startpos == 0) { QCOMPARE( haystack.indexOf(needle), resultpos ); + QCOMPARE( haystack.indexOf(ref), resultpos ); if (needleIsLatin) { QCOMPARE( haystack.indexOf(needle.toLatin1()), resultpos ); QCOMPARE( haystack.indexOf(needle.toLatin1().data()), resultpos ); @@ -1111,6 +1120,7 @@ void tst_QString::indexOf() } if (needle.size() == 1) { QCOMPARE(haystack.indexOf(needle.at(0), startpos, cs), resultpos); + QCOMPARE(haystack.indexOf(ref.at(0), startpos, cs), resultpos); } } @@ -1171,14 +1181,17 @@ void tst_QString::indexOf2() QFETCH( QString, haystack ); QFETCH( QString, needle ); QFETCH( int, resultpos ); + CREATE_REF(needle); QByteArray chaystack = haystack.toLatin1(); QByteArray cneedle = needle.toLatin1(); int got; QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseSensitive), resultpos ); + QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseSensitive), resultpos ); QCOMPARE( QStringMatcher(needle, Qt::CaseSensitive).indexIn(haystack, 0), resultpos ); QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseInsensitive), resultpos ); + QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseInsensitive), resultpos ); QCOMPARE( QStringMatcher(needle, Qt::CaseInsensitive).indexIn(haystack, 0), resultpos ); if ( needle.length() > 0 ) { got = haystack.lastIndexOf( needle, -1, Qt::CaseSensitive ); @@ -1245,10 +1258,12 @@ void tst_QString::lastIndexOf() QFETCH(int, from); QFETCH(int, expected); QFETCH(bool, caseSensitive); + CREATE_REF(needle); Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); QCOMPARE(haystack.lastIndexOf(needle, from, cs), expected); + QCOMPARE(haystack.lastIndexOf(ref, from, cs), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from, cs), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from, cs), expected); @@ -1278,20 +1293,23 @@ void tst_QString::lastIndexOf() if (cs == Qt::CaseSensitive) { QCOMPARE(haystack.lastIndexOf(needle, from), expected); + QCOMPARE(haystack.lastIndexOf(ref, from), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from), expected); if (from == -1) { QCOMPARE(haystack.lastIndexOf(needle), expected); + QCOMPARE(haystack.lastIndexOf(ref), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1()), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data()), expected); } } if (needle.size() == 1) { QCOMPARE(haystack.lastIndexOf(needle.at(0), from), expected); + QCOMPARE(haystack.lastIndexOf(ref.at(0), from), expected); } } -void tst_QString::contains() +void tst_QString::count() { QString a; a="ABCDEFGHIEfGEFG"; // 15 chars @@ -1306,8 +1324,42 @@ void tst_QString::contains() QCOMPARE(a.count( "", Qt::CaseInsensitive), 16); QCOMPARE(a.count(QRegExp("[FG][HI]")),1); QCOMPARE(a.count(QRegExp("[G][HE]")),2); + + CREATE_REF(QLatin1String("FG")); + QCOMPARE(a.count(ref),2); + QCOMPARE(a.count(ref,Qt::CaseInsensitive),3); + QCOMPARE(a.count( QStringRef(), Qt::CaseInsensitive), 16); + QStringRef emptyRef(&a, 0, 0); + QCOMPARE(a.count( emptyRef, Qt::CaseInsensitive), 16); + } +void tst_QString::contains() +{ + QString a; + a="ABCDEFGHIEfGEFG"; // 15 chars + QVERIFY(a.contains('A')); + QVERIFY(!a.contains('Z')); + QVERIFY(a.contains('E')); + QVERIFY(a.contains('F')); + QVERIFY(a.contains('F',Qt::CaseInsensitive)); + QVERIFY(a.contains("FG")); + QVERIFY(a.contains("FG",Qt::CaseInsensitive)); + QVERIFY(a.contains( QString(), Qt::CaseInsensitive)); + QVERIFY(a.contains( "", Qt::CaseInsensitive)); + QVERIFY(a.contains(QRegExp("[FG][HI]"))); + QVERIFY(a.contains(QRegExp("[G][HE]"))); + + CREATE_REF(QLatin1String("FG")); + QVERIFY(a.contains(ref)); + QVERIFY(a.contains(ref, Qt::CaseInsensitive)); + QVERIFY(a.contains( QStringRef(), Qt::CaseInsensitive)); + QStringRef emptyRef(&a, 0, 0); + QVERIFY(a.contains(emptyRef, Qt::CaseInsensitive)); + +} + + void tst_QString::left() { QString a; @@ -2828,6 +2880,14 @@ void tst_QString::startsWith() QVERIFY( !a.startsWith(QChar(), Qt::CaseSensitive) ); QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseSensitive) ); +#define TEST_REF_STARTS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.startsWith(ref), yes); } + + TEST_REF_STARTS_WITH("A", true); + TEST_REF_STARTS_WITH("AB", true); + TEST_REF_STARTS_WITH("C", false); + TEST_REF_STARTS_WITH("ABCDEF", false); +#undef TEST_REF_STARTS_WITH + a = ""; QVERIFY( a.startsWith("") ); QVERIFY( a.startsWith(QString::null) ); @@ -2853,6 +2913,7 @@ void tst_QString::startsWith() QVERIFY( !a.startsWith(QLatin1Char(0)) ); QVERIFY( !a.startsWith(QLatin1Char('x')) ); QVERIFY( !a.startsWith(QChar()) ); + } void tst_QString::endsWith() @@ -2920,6 +2981,17 @@ void tst_QString::endsWith() QVERIFY( !a.endsWith(QChar(), Qt::CaseSensitive) ); QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseSensitive) ); + +#define TEST_REF_ENDS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.endsWith(ref), yes); } + TEST_REF_ENDS_WITH(QLatin1String("B"), true); + TEST_REF_ENDS_WITH(QLatin1String("AB"), true); + TEST_REF_ENDS_WITH(QLatin1String("C"), false); + TEST_REF_ENDS_WITH(QLatin1String("ABCDEF"), false); + TEST_REF_ENDS_WITH(QLatin1String(""), true); + TEST_REF_ENDS_WITH(QLatin1String(0), true); + +#undef TEST_REF_STARTS_WITH + a = ""; QVERIFY( a.endsWith("") ); QVERIFY( a.endsWith(QString::null) ); diff --git a/tests/auto/qstringref/qstringref.pro b/tests/auto/qstringref/qstringref.pro new file mode 100644 index 0000000..48e7ddf --- /dev/null +++ b/tests/auto/qstringref/qstringref.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +SOURCES += tst_qstringref.cpp + +QT = core diff --git a/tests/auto/qstringref/tst_qstringref.cpp b/tests/auto/qstringref/tst_qstringref.cpp new file mode 100644 index 0000000..585e14e --- /dev/null +++ b/tests/auto/qstringref/tst_qstringref.cpp @@ -0,0 +1,881 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <qstringlist.h> +#include <qvariant.h> + +#include <qlocale.h> +#include <locale.h> + +Q_DECLARE_METATYPE(qlonglong) + +//TESTED_CLASS= +//TESTED_FILES= + + +class tst_QStringRef : public QObject +{ + Q_OBJECT + +public: + tst_QStringRef(); + virtual ~tst_QStringRef(); + + +public slots: + void init(); + void cleanup(); +private slots: + void endsWith(); + void startsWith(); + void contains(); + void count(); + void lastIndexOf_data(); + void lastIndexOf(); + void indexOf_data(); + void indexOf(); + void indexOf2_data(); + void indexOf2(); + void length_data(); + void length(); + void isEmpty(); + void compare_data(); + void compare(); + void operator_eqeq_nullstring(); +}; + +static QStringRef emptyRef() +{ + static const QString empty(""); + return empty.midRef(0); +} + +#define CREATE_REF(string) \ + const QString padded = QString::fromLatin1(" %1 ").arg(string); \ + QStringRef ref = padded.midRef(1, padded.size() - 2); + +typedef QList<int> IntList; + +Q_DECLARE_METATYPE(QList<QVariant>) +Q_DECLARE_METATYPE(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_WS_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_QStringRef::tst_QStringRef() +{ +} + +tst_QStringRef::~tst_QStringRef() +{ +} + +void tst_QStringRef::init() +{ +} + +void tst_QStringRef::cleanup() +{ + QLocale::setDefault(QString(QLatin1Char('C'))); +} + +void tst_QStringRef::length_data() +{ + QTest::addColumn<QString>("s1"); + QTest::addColumn<int>("res"); + + QTest::newRow("data0") << QString("Test") << 4; + QTest::newRow("data1") << QString("The quick brown fox jumps over the lazy dog") << 43; + QTest::newRow("data2") << QString() << 0; + QTest::newRow("data3") << QString("A") << 1; + QTest::newRow("data4") << QString("AB") << 2; + QTest::newRow("data5") << QString("AB\n") << 3; + QTest::newRow("data6") << QString("AB\nC") << 4; + QTest::newRow("data7") << QString("\n") << 1; + QTest::newRow("data8") << QString("\nA") << 2; + QTest::newRow("data9") << QString("\nAB") << 3; + QTest::newRow("data10") << QString("\nAB\nCDE") << 7; + QTest::newRow("data11") << QString("shdnftrheid fhgnt gjvnfmd chfugkh bnfhg thgjf vnghturkf chfnguh bjgnfhvygh hnbhgutjfv dhdnjds dcjs d") << 100; + QTest::newRow("data12") << QString("") << 0; +} + + +void tst_QStringRef::length() +{ + QFETCH(QString, s1); + CREATE_REF(s1); + QTEST(ref.length(), "res"); +} + + +void tst_QStringRef::isEmpty() +{ + QStringRef a; + QVERIFY(a.isEmpty()); + QVERIFY(emptyRef().isEmpty()); + CREATE_REF("Not empty"); + QVERIFY(!ref.isEmpty()); +} + +void tst_QStringRef::indexOf_data() +{ + QTest::addColumn<QString>("haystack"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<int>("startpos"); + QTest::addColumn<bool>("bcs"); + QTest::addColumn<int>("resultpos"); + + QTest::newRow("data0") << QString("abc") << QString("a") << 0 << true << 0; + QTest::newRow("data1") << QString("abc") << QString("a") << 0 << false << 0; + QTest::newRow("data2") << QString("abc") << QString("A") << 0 << true << -1; + QTest::newRow("data3") << QString("abc") << QString("A") << 0 << false << 0; + QTest::newRow("data4") << QString("abc") << QString("a") << 1 << true << -1; + QTest::newRow("data5") << QString("abc") << QString("a") << 1 << false << -1; + QTest::newRow("data6") << QString("abc") << QString("A") << 1 << true << -1; + QTest::newRow("data7") << QString("abc") << QString("A") << 1 << false << -1; + QTest::newRow("data8") << QString("abc") << QString("b") << 0 << true << 1; + QTest::newRow("data9") << QString("abc") << QString("b") << 0 << false << 1; + QTest::newRow("data10") << QString("abc") << QString("B") << 0 << true << -1; + QTest::newRow("data11") << QString("abc") << QString("B") << 0 << false << 1; + QTest::newRow("data12") << QString("abc") << QString("b") << 1 << true << 1; + QTest::newRow("data13") << QString("abc") << QString("b") << 1 << false << 1; + QTest::newRow("data14") << QString("abc") << QString("B") << 1 << true << -1; + QTest::newRow("data15") << QString("abc") << QString("B") << 1 << false << 1; + QTest::newRow("data16") << QString("abc") << QString("b") << 2 << true << -1; + QTest::newRow("data17") << QString("abc") << QString("b") << 2 << false << -1; + + QTest::newRow("data20") << QString("ABC") << QString("A") << 0 << true << 0; + QTest::newRow("data21") << QString("ABC") << QString("A") << 0 << false << 0; + QTest::newRow("data22") << QString("ABC") << QString("a") << 0 << true << -1; + QTest::newRow("data23") << QString("ABC") << QString("a") << 0 << false << 0; + QTest::newRow("data24") << QString("ABC") << QString("A") << 1 << true << -1; + QTest::newRow("data25") << QString("ABC") << QString("A") << 1 << false << -1; + QTest::newRow("data26") << QString("ABC") << QString("a") << 1 << true << -1; + QTest::newRow("data27") << QString("ABC") << QString("a") << 1 << false << -1; + QTest::newRow("data28") << QString("ABC") << QString("B") << 0 << true << 1; + QTest::newRow("data29") << QString("ABC") << QString("B") << 0 << false << 1; + QTest::newRow("data30") << QString("ABC") << QString("b") << 0 << true << -1; + QTest::newRow("data31") << QString("ABC") << QString("b") << 0 << false << 1; + QTest::newRow("data32") << QString("ABC") << QString("B") << 1 << true << 1; + QTest::newRow("data33") << QString("ABC") << QString("B") << 1 << false << 1; + QTest::newRow("data34") << QString("ABC") << QString("b") << 1 << true << -1; + QTest::newRow("data35") << QString("ABC") << QString("b") << 1 << false << 1; + QTest::newRow("data36") << QString("ABC") << QString("B") << 2 << true << -1; + QTest::newRow("data37") << QString("ABC") << QString("B") << 2 << false << -1; + + QTest::newRow("data40") << QString("aBc") << QString("bc") << 0 << true << -1; + QTest::newRow("data41") << QString("aBc") << QString("Bc") << 0 << true << 1; + QTest::newRow("data42") << QString("aBc") << QString("bC") << 0 << true << -1; + QTest::newRow("data43") << QString("aBc") << QString("BC") << 0 << true << -1; + QTest::newRow("data44") << QString("aBc") << QString("bc") << 0 << false << 1; + QTest::newRow("data45") << QString("aBc") << QString("Bc") << 0 << false << 1; + QTest::newRow("data46") << QString("aBc") << QString("bC") << 0 << false << 1; + QTest::newRow("data47") << QString("aBc") << QString("BC") << 0 << false << 1; + QTest::newRow("data48") << QString("AbC") << QString("bc") << 0 << true << -1; + QTest::newRow("data49") << QString("AbC") << QString("Bc") << 0 << true << -1; + QTest::newRow("data50") << QString("AbC") << QString("bC") << 0 << true << 1; + QTest::newRow("data51") << QString("AbC") << QString("BC") << 0 << true << -1; + QTest::newRow("data52") << QString("AbC") << QString("bc") << 0 << false << 1; + QTest::newRow("data53") << QString("AbC") << QString("Bc") << 0 << false << 1; + + QTest::newRow("data54") << QString("AbC") << QString("bC") << 0 << false << 1; + QTest::newRow("data55") << QString("AbC") << QString("BC") << 0 << false << 1; + QTest::newRow("data56") << QString("AbC") << QString("BC") << 1 << false << 1; + QTest::newRow("data57") << QString("AbC") << QString("BC") << 2 << false << -1; +#if 0 + QTest::newRow("null-in-null") << QString() << QString() << 0 << false << 0; + QTest::newRow("empty-in-null") << QString() << QString("") << 0 << false << 0; + QTest::newRow("null-in-empty") << QString("") << QString() << 0 << false << 0; + QTest::newRow("empty-in-empty") << QString("") << QString("") << 0 << false << 0; +#endif + + + QString s1 = "abc"; + s1 += QChar(0xb5); + QString s2; + s2 += QChar(0x3bc); + QTest::newRow("data58") << QString(s1) << QString(s2) << 0 << false << 3; + s2.prepend("C"); + QTest::newRow("data59") << QString(s1) << QString(s2) << 0 << false << 2; + + QString veryBigHaystack(500, 'a'); + veryBigHaystack += 'B'; + QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << true << 0; + QTest::newRow("BoyerMooreStressTest2") << veryBigHaystack + 'c' << veryBigHaystack << 0 << true << 0; + QTest::newRow("BoyerMooreStressTest3") << 'c' + veryBigHaystack << veryBigHaystack << 0 << true << 1; + QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << veryBigHaystack + 'c' << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest6") << 'd' + veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest6") << veryBigHaystack + 'c' << 'c' + veryBigHaystack << 0 << true << -1; + + QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0; + +} + +void tst_QStringRef::indexOf() +{ + QFETCH(QString, haystack); + QFETCH(QString, needle); + QFETCH(int, startpos); + QFETCH(bool, bcs); + QFETCH(int, resultpos); + + const QString haystackPadded = QString::fromLatin1(" %1 ").arg(haystack); + const QString needlePadded = QString::fromLatin1(" %1 ").arg(needle); + const QStringRef haystackRef(&haystackPadded, 1, haystack.size()); + const QStringRef needleRef(&needlePadded, 1, needle.size()); + + Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive; + + QCOMPARE(haystack.indexOf(needle, startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needle, startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, startpos, cs), resultpos); + QCOMPARE(haystack.indexOf(needleRef, startpos, cs), resultpos); + + if (cs == Qt::CaseSensitive) { + QCOMPARE(haystack.indexOf(needle, startpos), resultpos); + QCOMPARE(haystackRef.indexOf(needle, startpos), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, startpos), resultpos); + QCOMPARE(haystack.indexOf(needleRef, startpos), resultpos); + if (startpos == 0) { + QCOMPARE(haystack.indexOf(needle), resultpos); + QCOMPARE(haystackRef.indexOf(needle), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef), resultpos); + QCOMPARE(haystack.indexOf(needleRef), resultpos); + } + } + if (needle.size() == 1) { + QCOMPARE(needle.at(0), needleRef.at(0)); + QCOMPARE(haystack.indexOf(needleRef.at(0), startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needle.at(0), startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef.at(0), startpos, cs), resultpos); + QCOMPARE(haystack.indexOf(needleRef.at(0), startpos ,cs), resultpos); + } +} + +void tst_QStringRef::indexOf2_data() +{ + QTest::addColumn<QString>("haystack"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<int>("resultpos"); + + QTest::newRow("data0") << QString() << QString() << 0; + QTest::newRow("data1") << QString() << QString("") << 0; + QTest::newRow("data2") << QString("") << QString() << 0; + QTest::newRow("data3") << QString("") << QString("") << 0; + QTest::newRow("data4") << QString() << QString("a") << -1; + QTest::newRow("data5") << QString() << QString("abcdefg") << -1; + QTest::newRow("data6") << QString("") << QString("a") << -1; + QTest::newRow("data7") << QString("") << QString("abcdefg") << -1; + + QTest::newRow("data8") << QString("a") << QString() << 0; + QTest::newRow("data9") << QString("a") << QString("") << 0; + QTest::newRow("data10") << QString("a") << QString("a") << 0; + QTest::newRow("data11") << QString("a") << QString("b") << -1; + QTest::newRow("data12") << QString("a") << QString("abcdefg") << -1; + QTest::newRow("data13") << QString("ab") << QString() << 0; + QTest::newRow("data14") << QString("ab") << QString("") << 0; + QTest::newRow("data15") << QString("ab") << QString("a") << 0; + QTest::newRow("data16") << QString("ab") << QString("b") << 1; + QTest::newRow("data17") << QString("ab") << QString("ab") << 0; + QTest::newRow("data18") << QString("ab") << QString("bc") << -1; + QTest::newRow("data19") << QString("ab") << QString("abcdefg") << -1; + + QTest::newRow("data30") << QString("abc") << QString("a") << 0; + QTest::newRow("data31") << QString("abc") << QString("b") << 1; + QTest::newRow("data32") << QString("abc") << QString("c") << 2; + QTest::newRow("data33") << QString("abc") << QString("d") << -1; + QTest::newRow("data34") << QString("abc") << QString("ab") << 0; + QTest::newRow("data35") << QString("abc") << QString("bc") << 1; + QTest::newRow("data36") << QString("abc") << QString("cd") << -1; + QTest::newRow("data37") << QString("abc") << QString("ac") << -1; + + // sizeof(whale) > 32 + QString whale = "a5zby6cx7dw8evf9ug0th1si2rj3qkp4lomn"; + QString minnow = "zby"; + QTest::newRow("data40") << whale << minnow << 2; + QTest::newRow("data41") << (whale + whale) << minnow << 2; + QTest::newRow("data42") << (minnow + whale) << minnow << 0; + QTest::newRow("data43") << whale << whale << 0; + QTest::newRow("data44") << (whale + whale) << whale << 0; + QTest::newRow("data45") << whale << (whale + whale) << -1; + QTest::newRow("data46") << (whale + whale) << (whale + whale) << 0; + QTest::newRow("data47") << (whale + whale) << (whale + minnow) << -1; + QTest::newRow("data48") << (minnow + whale) << whale << (int)minnow.length(); +} + +void tst_QStringRef::indexOf2() +{ + QFETCH(QString, haystack); + QFETCH(QString, needle); + QFETCH(int, resultpos); + + const QString haystackPadded = QString::fromLatin1(" %1 ").arg(haystack); + const QString needlePadded = QString::fromLatin1(" %1 ").arg(needle); + const QStringRef haystackRef(&haystackPadded, 1, haystack.size()); + const QStringRef needleRef(&needlePadded, 1, needle.size()); + + + int got; + + QCOMPARE(haystack.indexOf(needleRef, 0, Qt::CaseSensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needle, 0, Qt::CaseSensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, 0, Qt::CaseSensitive), resultpos); + QCOMPARE(haystack.indexOf(needleRef, 0, Qt::CaseInsensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needle, 0, Qt::CaseInsensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, 0, Qt::CaseInsensitive), resultpos); + if (needle.length() > 0) { + got = haystackRef.lastIndexOf(needle, -1, Qt::CaseSensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + got = haystackRef.lastIndexOf(needle, -1, Qt::CaseInsensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + + got = haystack.lastIndexOf(needleRef, -1, Qt::CaseSensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + got = haystack.lastIndexOf(needleRef, -1, Qt::CaseInsensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + + got = haystackRef.lastIndexOf(needleRef, -1, Qt::CaseSensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + got = haystackRef.lastIndexOf(needleRef, -1, Qt::CaseInsensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + } +} + +void tst_QStringRef::lastIndexOf_data() +{ + QTest::addColumn<QString>("haystack"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<int>("from"); + QTest::addColumn<int>("expected"); + QTest::addColumn<bool>("caseSensitive"); + + QString a = "ABCDEFGHIEfGEFG"; + + QTest::newRow("-1") << a << "G" << a.size() - 1 << 14 << true; + QTest::newRow("1") << a << "G" << - 1 << 14 << true; + QTest::newRow("2") << a << "G" << -3 << 11 << true; + QTest::newRow("3") << a << "G" << -5 << 6 << true; + QTest::newRow("4") << a << "G" << 14 << 14 << true; + QTest::newRow("5") << a << "G" << 13 << 11 << true; + QTest::newRow("6") << a << "B" << a.size() - 1 << 1 << true; + QTest::newRow("6") << a << "B" << - 1 << 1 << true; + QTest::newRow("7") << a << "B" << 1 << 1 << true; + QTest::newRow("8") << a << "B" << 0 << -1 << true; + + QTest::newRow("9") << a << "G" << -1 << a.size()-1 << true; + QTest::newRow("10") << a << "G" << a.size()-1 << a.size()-1 << true; + QTest::newRow("11") << a << "G" << a.size() << -1 << true; + QTest::newRow("12") << a << "A" << 0 << 0 << true; + QTest::newRow("13") << a << "A" << -1*a.size() << 0 << true; + + QTest::newRow("15") << a << "efg" << 0 << -1 << false; + QTest::newRow("16") << a << "efg" << a.size() << -1 << false; + QTest::newRow("17") << a << "efg" << -1 * a.size() << -1 << false; + QTest::newRow("19") << a << "efg" << a.size() - 1 << 12 << false; + QTest::newRow("20") << a << "efg" << 12 << 12 << false; + QTest::newRow("21") << a << "efg" << -12 << -1 << false; + QTest::newRow("22") << a << "efg" << 11 << 9 << false; + + QTest::newRow("24") << "" << "asdf" << -1 << -1 << false; + QTest::newRow("25") << "asd" << "asdf" << -1 << -1 << false; + QTest::newRow("26") << "" << QString() << -1 << -1 << false; + + QTest::newRow("27") << a << "" << a.size() << a.size() << false; + QTest::newRow("28") << a << "" << a.size() + 10 << -1 << false; +} + +void tst_QStringRef::lastIndexOf() +{ + QFETCH(QString, haystack); + QFETCH(QString, needle); + QFETCH(int, from); + QFETCH(int, expected); + QFETCH(bool, caseSensitive); + + const QString haystackPadded = QString::fromLatin1(" %1 ").arg(haystack); + const QString needlePadded = QString::fromLatin1(" %1 ").arg(needle); + const QStringRef haystackRef(&haystackPadded, 1, haystack.size()); + const QStringRef needleRef(&needlePadded, 1, needle.size()); + + Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); + + QCOMPARE(haystack.lastIndexOf(needleRef, from, cs), expected); + QCOMPARE(haystackRef.lastIndexOf(needle, from, cs), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef, from, cs), expected); + + + if (cs == Qt::CaseSensitive) { + QCOMPARE(haystack.lastIndexOf(needleRef, from), expected); + QCOMPARE(haystackRef.lastIndexOf(needle, from), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef, from), expected); + + if (from == -1) { + QCOMPARE(haystack.lastIndexOf(needleRef), expected); + QCOMPARE(haystackRef.lastIndexOf(needle), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef), expected); + + } + } + if (needle.size() == 1) { + QCOMPARE(haystack.lastIndexOf(needleRef.at(0), from), expected); + QCOMPARE(haystackRef.lastIndexOf(needle.at(0), from), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef.at(0), from), expected); + } +} + +void tst_QStringRef::count() +{ + const QString a = QString::fromLatin1("ABCDEFGHIEfGEFG"); // 15 chars + CREATE_REF(a); + QCOMPARE(ref.count('A'),1); + QCOMPARE(ref.count('Z'),0); + QCOMPARE(ref.count('E'),3); + QCOMPARE(ref.count('F'),2); + QCOMPARE(ref.count('F',Qt::CaseInsensitive),3); + QCOMPARE(ref.count("FG"),2); + QCOMPARE(ref.count("FG",Qt::CaseInsensitive),3); + QCOMPARE(ref.count(QString(), Qt::CaseInsensitive), 16); + QCOMPARE(ref.count("", Qt::CaseInsensitive), 16); +} + +void tst_QStringRef::contains() +{ + const QString a = QString::fromLatin1("ABCDEFGHIEfGEFG"); // 15 chars + CREATE_REF(a); + QVERIFY(ref.contains('A')); + QVERIFY(!ref.contains('Z')); + QVERIFY(ref.contains('E')); + QVERIFY(ref.contains('F')); + QVERIFY(ref.contains('F',Qt::CaseInsensitive)); + QVERIFY(ref.contains("FG")); + QVERIFY(ref.contains(QString("FG").midRef(0))); + const QString ref2 = QString::fromLatin1(" FG "); + QVERIFY(ref.contains(ref2.midRef(1, 2),Qt::CaseInsensitive)); + QVERIFY(ref.contains(QString(), Qt::CaseInsensitive)); + QVERIFY(ref.contains("", Qt::CaseInsensitive)); // apparently +} + +void tst_QStringRef::startsWith() +{ + { + const QString a = QString::fromLatin1("AB"); + CREATE_REF(a); + QVERIFY(ref.startsWith("A")); + QVERIFY(ref.startsWith("AB")); + QVERIFY(!ref.startsWith("C")); + QVERIFY(!ref.startsWith("ABCDEF")); + QVERIFY(ref.startsWith("")); + QVERIFY(ref.startsWith(QString::null)); + QVERIFY(ref.startsWith('A')); + QVERIFY(ref.startsWith(QLatin1Char('A'))); + QVERIFY(ref.startsWith(QChar('A'))); + QVERIFY(!ref.startsWith('C')); + QVERIFY(!ref.startsWith(QChar())); + QVERIFY(!ref.startsWith(QLatin1Char(0))); + + QVERIFY(ref.startsWith(QLatin1String("A"))); + QVERIFY(ref.startsWith(QLatin1String("AB"))); + QVERIFY(!ref.startsWith(QLatin1String("C"))); + QVERIFY(!ref.startsWith(QLatin1String("ABCDEF"))); + QVERIFY(ref.startsWith(QLatin1String(""))); + QVERIFY(ref.startsWith(QLatin1String(0))); + + QVERIFY(ref.startsWith("A", Qt::CaseSensitive)); + QVERIFY(ref.startsWith("A", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("a", Qt::CaseSensitive)); + QVERIFY(ref.startsWith("a", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("aB", Qt::CaseSensitive)); + QVERIFY(ref.startsWith("aB", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("C", Qt::CaseSensitive)); + QVERIFY(!ref.startsWith("C", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("c", Qt::CaseSensitive)); + QVERIFY(!ref.startsWith("c", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("abcdef", Qt::CaseInsensitive)); + QVERIFY(ref.startsWith("", Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QString::null, Qt::CaseInsensitive)); + QVERIFY(ref.startsWith('a', Qt::CaseInsensitive)); + QVERIFY(ref.startsWith('A', Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QLatin1Char('a'), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QChar('a'), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith('c', Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QChar(), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1Char(0), Qt::CaseInsensitive)); + + QVERIFY(ref.startsWith(QLatin1String("A"), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1String("A"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("a"), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1String("a"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("aB"), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1String("aB"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("C"), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QLatin1String("C"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("c"), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QLatin1String("c"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("abcdef"), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QLatin1String(""), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QLatin1String(0), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith('A', Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1Char('A'), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QChar('A'), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith('a', Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QChar(), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QLatin1Char(0), Qt::CaseSensitive)); + } + { + const QString a = QString::fromLatin1(""); + CREATE_REF(a); + QVERIFY(ref.startsWith("")); + QVERIFY(ref.startsWith(QString::null)); + QVERIFY(!ref.startsWith("ABC")); + + QVERIFY(ref.startsWith(QLatin1String(""))); + QVERIFY(ref.startsWith(QLatin1String(0))); + QVERIFY(!ref.startsWith(QLatin1String("ABC"))); + + QVERIFY(!ref.startsWith(QLatin1Char(0))); + QVERIFY(!ref.startsWith(QLatin1Char('x'))); + QVERIFY(!ref.startsWith(QChar())); + } + { + const QStringRef ref; + QVERIFY(!ref.startsWith("")); + QVERIFY(ref.startsWith(QString::null)); + QVERIFY(!ref.startsWith("ABC")); + + QVERIFY(!ref.startsWith(QLatin1String(""))); + QVERIFY(ref.startsWith(QLatin1String(0))); + QVERIFY(!ref.startsWith(QLatin1String("ABC"))); + + QVERIFY(!ref.startsWith(QLatin1Char(0))); + QVERIFY(!ref.startsWith(QLatin1Char('x'))); + QVERIFY(!ref.startsWith(QChar())); + } +} + +void tst_QStringRef::endsWith() +{ + { + const QString a = QString::fromLatin1("AB"); + CREATE_REF(a); + QVERIFY(ref.endsWith("B")); + QVERIFY(ref.endsWith("AB")); + QVERIFY(!ref.endsWith("C")); + QVERIFY(!ref.endsWith("ABCDEF")); + QVERIFY(ref.endsWith("")); + QVERIFY(ref.endsWith(QString::null)); + QVERIFY(ref.endsWith('B')); + QVERIFY(ref.endsWith(QLatin1Char('B'))); + QVERIFY(ref.endsWith(QChar('B'))); + QVERIFY(!ref.endsWith('C')); + QVERIFY(!ref.endsWith(QChar())); + QVERIFY(!ref.endsWith(QLatin1Char(0))); + + QVERIFY(ref.endsWith(QLatin1String("B"))); + QVERIFY(ref.endsWith(QLatin1String("AB"))); + QVERIFY(!ref.endsWith(QLatin1String("C"))); + QVERIFY(!ref.endsWith(QLatin1String("ABCDEF"))); + QVERIFY(ref.endsWith(QLatin1String(""))); + QVERIFY(ref.endsWith(QLatin1String(0))); + + QVERIFY(ref.endsWith("B", Qt::CaseSensitive)); + QVERIFY(ref.endsWith("B", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("b", Qt::CaseSensitive)); + QVERIFY(ref.endsWith("b", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("aB", Qt::CaseSensitive)); + QVERIFY(ref.endsWith("aB", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("C", Qt::CaseSensitive)); + QVERIFY(!ref.endsWith("C", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("c", Qt::CaseSensitive)); + QVERIFY(!ref.endsWith("c", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("abcdef", Qt::CaseInsensitive)); + QVERIFY(ref.endsWith("", Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QString::null, Qt::CaseInsensitive)); + QVERIFY(ref.endsWith('b', Qt::CaseInsensitive)); + QVERIFY(ref.endsWith('B', Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QLatin1Char('b'), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QChar('b'), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith('c', Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QChar(), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1Char(0), Qt::CaseInsensitive)); + + QVERIFY(ref.endsWith(QLatin1String("B"), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1String("B"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("b"), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1String("b"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("aB"), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1String("aB"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("C"), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QLatin1String("C"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("c"), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QLatin1String("c"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("abcdef"), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QLatin1String(""), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QLatin1String(0), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith('B', Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1Char('B'), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QChar('B'), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith('b', Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QChar(), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QLatin1Char(0), Qt::CaseSensitive)); + + } + { + const QString a = QString::fromLatin1(""); + CREATE_REF(a); + QVERIFY(ref.endsWith("")); + QVERIFY(ref.endsWith(QString::null)); + QVERIFY(!ref.endsWith("ABC")); + QVERIFY(!ref.endsWith(QLatin1Char(0))); + QVERIFY(!ref.endsWith(QLatin1Char('x'))); + QVERIFY(!ref.endsWith(QChar())); + + QVERIFY(ref.endsWith(QLatin1String(""))); + QVERIFY(ref.endsWith(QLatin1String(0))); + QVERIFY(!ref.endsWith(QLatin1String("ABC"))); + } + + { + QStringRef ref; + QVERIFY(!ref.endsWith("")); + QVERIFY(ref.endsWith(QString::null)); + QVERIFY(!ref.endsWith("ABC")); + + QVERIFY(!ref.endsWith(QLatin1String(""))); + QVERIFY(ref.endsWith(QLatin1String(0))); + QVERIFY(!ref.endsWith(QLatin1String("ABC"))); + + QVERIFY(!ref.endsWith(QLatin1Char(0))); + QVERIFY(!ref.endsWith(QLatin1Char('x'))); + QVERIFY(!ref.endsWith(QChar())); + } +} + +void tst_QStringRef::operator_eqeq_nullstring() +{ + /* Some of these might not be all that logical but it's the behaviour we've had since 3.0.0 + so we should probably stick with it. */ + + QVERIFY(QStringRef() == ""); + QVERIFY("" == QStringRef()); + + QVERIFY(QString("") == ""); + QVERIFY("" == QString("")); + + QVERIFY(QStringRef().size() == 0); + + QVERIFY(QString("").size() == 0); + + QVERIFY(QStringRef() == QString("")); + QVERIFY(QString("") == QString()); +} + +static inline int sign(int x) +{ + return x == 0 ? 0 : (x < 0 ? -1 : 1); +} + +void tst_QStringRef::compare_data() +{ + QTest::addColumn<QString>("s1"); + QTest::addColumn<QString>("s2"); + QTest::addColumn<int>("csr"); // case sensitive result + QTest::addColumn<int>("cir"); // case insensitive result + + + // null strings + QTest::newRow("data0") << QString("") << QString("") << 0 << 0; + QTest::newRow("data1") << QString("a") << QString("") << 1 << 1; + QTest::newRow("data2") << QString("") << QString("a") << -1 << -1; + + // equal length + QTest::newRow("data3") << QString("abc") << QString("abc") << 0 << 0; + QTest::newRow("data4") << QString("abC") << QString("abc") << -1 << 0; + QTest::newRow("data5") << QString("abc") << QString("abC") << 1 << 0; + + // different length + QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1; + QTest::newRow("data6") << QString("abCdef") << QString("abc") << -1 << 1; + QTest::newRow("data7") << QString("abc") << QString("abcdef") << -1 << -1; + + QString upper; + upper += QChar(QChar::highSurrogate(0x10400)); + upper += QChar(QChar::lowSurrogate(0x10400)); + QString lower; + lower += QChar(QChar::highSurrogate(0x10428)); + lower += QChar(QChar::lowSurrogate(0x10428)); + QTest::newRow("data8") << upper << lower << -1 << 0; + + // embedded nulls + // These dont work as of now. Its OK that these dont work since \0 is not a valid unicode + /*QTest::newRow("data9") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0; + QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString("") << 1 << 1; + QTest::newRow("data11") << QString("") << QString(QByteArray("\0", 1)) << -1 << -1; + QTest::newRow("data12") << QString("ab\0c") << QString(QByteArray("ab\0c", 4)) << 0 << 0; + QTest::newRow("data13") << QString(QByteArray("ab\0c", 4)) << QString("abc") << -1 << -1; + QTest::newRow("data14") << QString("abc") << QString(QByteArray("ab\0c", 4)) << 1 << 1;*/ +} + +static bool isLatin(const QString &s) +{ + for (int i = 0; i < s.length(); ++i) + if (s.at(i).unicode() > 0xff) + return false; + return true; +} + +void tst_QStringRef::compare() +{ + QFETCH(QString, s1); + QFETCH(QString, s2); + QFETCH(int, csr); + QFETCH(int, cir); + + QStringRef r1(&s1, 0, s1.length()); + QStringRef r2(&s2, 0, s2.length()); + + QCOMPARE(sign(QString::compare(s1, s2)), csr); + QCOMPARE(sign(QStringRef::compare(r1, r2)), csr); + QCOMPARE(sign(s1.compare(s2)), csr); + QCOMPARE(sign(s1.compare(r2)), csr); + QCOMPARE(sign(r1.compare(r2)), csr); + + QCOMPARE(sign(s1.compare(s2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(s1.compare(s2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(s1.compare(r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(s1.compare(r2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir); + + QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir); + + if (!cir) { + QCOMPARE(s1.toCaseFolded(), s2.toCaseFolded()); + } + + if (isLatin(s2)) { + QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()))), csr); + QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir); + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()))), csr); + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir); + } + + if (isLatin(s1)) { + QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2)), csr); + QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2, Qt::CaseInsensitive)), cir); + } +} + +QTEST_APPLESS_MAIN(tst_QStringRef) + +#include "tst_qstringref.moc" diff --git a/tests/auto/qtabbar/tst_qtabbar.cpp b/tests/auto/qtabbar/tst_qtabbar.cpp index ac3de20..84a6991 100644 --- a/tests/auto/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/qtabbar/tst_qtabbar.cpp @@ -76,6 +76,7 @@ private slots: void setElideMode_data(); void setElideMode(); + void sizeHints(); void setUsesScrollButtons_data(); void setUsesScrollButtons(); @@ -280,6 +281,46 @@ void tst_QTabBar::setElideMode() QTEST(int(tabBar.elideMode()), "expectedMode"); } +void tst_QTabBar::sizeHints() +{ + QTabBar tabBar; + QSKIP("To be fixed on Mac (font size below not large enough) and Linux QWS (probably too large for the screen).", SkipSingle); + tabBar.setFont(QFont("Arial", 10)); + tabBar.addTab("tab 01"); + tabBar.addTab("tab 02"); + tabBar.addTab("tab 03"); + tabBar.addTab("tab 04"); + tabBar.addTab("tab 05"); + tabBar.addTab("tab 06"); + tabBar.addTab("This is tab7"); + tabBar.addTab("This is tab8"); + tabBar.addTab("This is tab9 with a very long title"); + + // No eliding and no scrolling -> tabbar becomes very wide + tabBar.setUsesScrollButtons(false); + tabBar.setElideMode(Qt::ElideNone); +// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); + QVERIFY(tabBar.minimumSizeHint().width() > 700); + QVERIFY(tabBar.sizeHint().width() > 700); + + // Scrolling enabled -> no reason to become very wide + tabBar.setUsesScrollButtons(true); + // qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); + QVERIFY(tabBar.minimumSizeHint().width() < 200); + QVERIFY(tabBar.sizeHint().width() > 700); // unchanged + + // Eliding enabled -> no reason to become very wide + tabBar.setUsesScrollButtons(false); + tabBar.setElideMode(Qt::ElideRight); +// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); + QVERIFY(tabBar.minimumSizeHint().width() < 500); + QVERIFY(tabBar.sizeHint().width() > 700); // unchanged + + tabBar.addTab("This is tab10 with a very long title"); + QVERIFY(tabBar.minimumSizeHint().width() < 600); + QVERIFY(tabBar.sizeHint().width() > 700); // unchanged +} + void tst_QTabBar::setUsesScrollButtons_data() { QTest::addColumn<int>("usesArrows"); diff --git a/tests/auto/qtabwidget/tst_qtabwidget.cpp b/tests/auto/qtabwidget/tst_qtabwidget.cpp index 504579f..27581b0 100644 --- a/tests/auto/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/qtabwidget/tst_qtabwidget.cpp @@ -45,6 +45,7 @@ #include <qdebug.h> #include <qapplication.h> #include <qlabel.h> +#include <QtGui/qboxlayout.h> //TESTED_CLASS= //TESTED_FILES= @@ -120,6 +121,9 @@ class tst_QTabWidget:public QObject { void clear(); void keyboardNavigation(); void paintEventCount(); + void minimumSizeHint(); + void heightForWidth_data(); + void heightForWidth(); private: int addPage(); @@ -624,6 +628,74 @@ void tst_QTabWidget::paintEventCount() QCOMPARE(tab2->count, 1); } +void tst_QTabWidget::minimumSizeHint() +{ + QTabWidget tw; + QWidget *page = new QWidget; + QVBoxLayout *lay = new QVBoxLayout; + + QLabel *label = new QLabel(QLatin1String("XXgypq lorem ipsum must be long, must be long. lorem ipsumMMMW")); + lay->addWidget(label); + + page->setLayout(lay); + + tw.addTab(page, QLatin1String("page1")); + + tw.show(); + QTest::qWaitForWindowShown(&tw); + tw.resize(tw.minimumSizeHint()); + + QSize minSize = label->minimumSizeHint(); + QSize actSize = label->geometry().size(); + QVERIFY(minSize.width() <= actSize.width()); + QVERIFY(minSize.height() <= actSize.height()); +} + +void tst_QTabWidget::heightForWidth_data() +{ + QTest::addColumn<int>("tabPosition"); + QTest::newRow("West") << int(QTabWidget::West); + QTest::newRow("North") << int(QTabWidget::North); + QTest::newRow("East") << int(QTabWidget::East); + QTest::newRow("South") << int(QTabWidget::South); +} + +void tst_QTabWidget::heightForWidth() +{ + QFETCH(int, tabPosition); + + QWidget *window = new QWidget; + QVBoxLayout *lay = new QVBoxLayout(window); + lay->setMargin(0); + lay->setSpacing(0); + QTabWidget *tabWid = new QTabWidget(window); + QWidget *w = new QWidget; + tabWid->addTab(w, QLatin1String("HFW page")); + tabWid->setTabPosition(QTabWidget::TabPosition(tabPosition)); + QVBoxLayout *lay2 = new QVBoxLayout(w); + QLabel *label = new QLabel("Label with wordwrap turned on makes it trade height for width." + " Make it a really long text so that it spans on several lines" + " when the label is on its narrowest." + " I don't like to repeat myself." + " I don't like to repeat myself." + " I don't like to repeat myself." + " I don't like to repeat myself." + ); + label->setWordWrap(true); + lay2->addWidget(label); + lay2->setMargin(0); + + lay->addWidget(tabWid); + int h = window->heightForWidth(160); + window->resize(160, h); + window->show(); + + QTest::qWaitForWindowShown(window); + QVERIFY(label->height() >= label->heightForWidth(label->width())); + + delete window; +} + QTEST_MAIN(tst_QTabWidget) #include "tst_qtabwidget.moc" diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index f798faf..079e69f 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -85,6 +85,7 @@ private slots: void cursorToXForSetColumns(); void defaultWordSeparators_data(); void defaultWordSeparators(); + void cursorMovementFromInvalidPositions(); void cursorMovementInsideSpaces(); void charWordStopOnLineSeparator(); void xToCursorAtEndOfLine(); @@ -543,6 +544,10 @@ void tst_QTextLayout::defaultWordSeparators_data() QTest::newRow("lineseparator") << QString::fromLatin1("abcd") + QString(QChar::LineSeparator) + QString::fromLatin1("efgh") << 0 << 5; + + QTest::newRow("empty") + << QString() + << 0 << 0; } void tst_QTextLayout::defaultWordSeparators() @@ -556,12 +561,31 @@ void tst_QTextLayout::defaultWordSeparators() QCOMPARE(layout.previousCursorPosition(endPos, QTextLayout::SkipWords), startPos); } +void tst_QTextLayout::cursorMovementFromInvalidPositions() +{ + int badpos = 10000; + + QTextLayout layout("ABC", testFont); + + QCOMPARE(layout.previousCursorPosition(-badpos, QTextLayout::SkipCharacters), -badpos); + QCOMPARE(layout.nextCursorPosition(-badpos, QTextLayout::SkipCharacters), -badpos); + + QCOMPARE(layout.previousCursorPosition(badpos, QTextLayout::SkipCharacters), badpos); + QCOMPARE(layout.nextCursorPosition(badpos, QTextLayout::SkipCharacters), badpos); +} + void tst_QTextLayout::cursorMovementInsideSpaces() { QTextLayout layout("ABC DEF", testFont); QCOMPARE(layout.previousCursorPosition(6, QTextLayout::SkipWords), 0); QCOMPARE(layout.nextCursorPosition(6, QTextLayout::SkipWords), 15); + + + QTextLayout layout2("ABC\t\t\t\t\t\t\t\t\t\t\t\tDEF", testFont); + + QCOMPARE(layout2.previousCursorPosition(6, QTextLayout::SkipWords), 0); + QCOMPARE(layout2.nextCursorPosition(6, QTextLayout::SkipWords), 15); } void tst_QTextLayout::charWordStopOnLineSeparator() diff --git a/tests/auto/qthreadpool/tst_qthreadpool.cpp b/tests/auto/qthreadpool/tst_qthreadpool.cpp index 7c8b410..cd6070f 100644 --- a/tests/auto/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/qthreadpool/tst_qthreadpool.cpp @@ -89,6 +89,7 @@ private slots: void tryStartPeakThreadCount(); void tryStartCount(); void waitForDone(); + void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); void stressTest(); }; @@ -774,6 +775,32 @@ void tst_QThreadPool::waitForDone() } } +void tst_QThreadPool::waitForDoneTimeout() +{ + class BlockedTask : public QRunnable + { + public: + QMutex mutex; + BlockedTask() { setAutoDelete(false); } + + void run() + { + mutex.lock(); + mutex.unlock(); + QTest::qSleep(50); + } + }; + + QThreadPool threadPool; + + BlockedTask *task = new BlockedTask; + task->mutex.lock(); + threadPool.start(task); + QVERIFY(!threadPool.waitForDone(100)); + task->mutex.unlock(); + QVERIFY(threadPool.waitForDone(400)); +} + void tst_QThreadPool::destroyingWaitsForTasksToFinish() { QTime total, pass; diff --git a/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp index 1f65ae7..dc071ab 100644 --- a/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp +++ b/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp @@ -225,11 +225,17 @@ void tst_QSharedMemory::key_data() { QTest::addColumn<QString>("constructorKey"); QTest::addColumn<QString>("setKey"); - - QTest::newRow("null, null") << QString() << QString(); - QTest::newRow("null, one") << QString() << QString("one"); - QTest::newRow("one, two") << QString("one") << QString("two"); - QTest::newRow("invalid") << QString("o/e") << QString("t/o"); + QTest::addColumn<QString>("setNativeKey"); + + QTest::newRow("null, null, null") << QString() << QString() << QString(); + QTest::newRow("one, null, null") << QString("one") << QString() << QString(); + QTest::newRow("null, one, null") << QString() << QString("one") << QString(); + QTest::newRow("null, null, one") << QString() << QString() << QString("one"); + QTest::newRow("one, two, null") << QString("one") << QString("two") << QString(); + QTest::newRow("one, null, two") << QString("one") << QString() << QString("two"); + QTest::newRow("null, one, two") << QString() << QString("one") << QString("two"); + QTest::newRow("one, two, three") << QString("one") << QString("two") << QString("three"); + QTest::newRow("invalid") << QString("o/e") << QString("t/o") << QString("|x"); } /*! @@ -239,11 +245,17 @@ void tst_QSharedMemory::key() { QFETCH(QString, constructorKey); QFETCH(QString, setKey); + QFETCH(QString, setNativeKey); QSharedMemory sm(constructorKey); QCOMPARE(sm.key(), constructorKey); + QCOMPARE(sm.nativeKey().isEmpty(), constructorKey.isEmpty()); sm.setKey(setKey); QCOMPARE(sm.key(), setKey); + QCOMPARE(sm.nativeKey().isEmpty(), setKey.isEmpty()); + sm.setNativeKey(setNativeKey); + QVERIFY(sm.key().isNull()); + QCOMPARE(sm.nativeKey(), setNativeKey); QCOMPARE(sm.isAttached(), false); QCOMPARE(sm.error(), QSharedMemory::NoError); @@ -262,7 +274,7 @@ void tst_QSharedMemory::create_data() QTest::addColumn<QSharedMemory::SharedMemoryError>("error"); QTest::newRow("null key") << QString() << 1024 - << false << QSharedMemory::LockError; + << false << QSharedMemory::KeyError; QTest::newRow("-1 size") << QString("negsize") << -1 << false << QSharedMemory::InvalidSize; QTest::newRow("nor size") << QString("norsize") << 1024 @@ -302,7 +314,7 @@ void tst_QSharedMemory::attach_data() QTest::addColumn<bool>("exists"); QTest::addColumn<QSharedMemory::SharedMemoryError>("error"); - QTest::newRow("null key") << QString() << false << QSharedMemory::LockError; + QTest::newRow("null key") << QString() << false << QSharedMemory::KeyError; QTest::newRow("doesn't exists") << QString("doesntexists") << false << QSharedMemory::NotFound; QTest::newRow("already exists") << QString(EXISTING_SHARE) << true << QSharedMemory::NoError; } diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index 820e32d..b2b28bd 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -161,6 +161,8 @@ private slots: void idna_testsuite(); void nameprep_testsuite_data(); void nameprep_testsuite(); + void nameprep_highcodes_data(); + void nameprep_highcodes(); void ace_testsuite_data(); void ace_testsuite(); void std3violations_data(); @@ -314,6 +316,7 @@ void tst_QUrl::constructing() QUrl buildUNC; + buildUNC.setScheme(QString::fromLatin1("file")); buildUNC.setHost(QString::fromLatin1("somehost")); buildUNC.setPath(QString::fromLatin1("somepath")); QCOMPARE(buildUNC.toLocalFile(), QString::fromLatin1("//somehost/somepath")); @@ -1757,7 +1760,15 @@ void tst_QUrl::toLocalFile_data() QTest::newRow("data7") << QString::fromLatin1("file://somehost/") << QString::fromLatin1("//somehost/"); QTest::newRow("data8") << QString::fromLatin1("file://somehost") << QString::fromLatin1("//somehost"); QTest::newRow("data9") << QString::fromLatin1("file:////somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile"); + QTest::newRow("data10") << QString::fromLatin1("FILE:/a.txt") << QString::fromLatin1("/a.txt"); + // and some that result in empty (i.e., not local) + QTest::newRow("xdata0") << QString::fromLatin1("/a.txt") << QString(); + QTest::newRow("xdata1") << QString::fromLatin1("//a.txt") << QString(); + QTest::newRow("xdata2") << QString::fromLatin1("///a.txt") << QString(); + QTest::newRow("xdata3") << QString::fromLatin1("foo:/a.txt") << QString(); + QTest::newRow("xdata4") << QString::fromLatin1("foo://a.txt") << QString(); + QTest::newRow("xdata5") << QString::fromLatin1("foo:///a.txt") << QString(); } void tst_QUrl::toLocalFile() @@ -2903,7 +2914,6 @@ void tst_QUrl::nameprep_testsuite_data() << QString() << 0 << 0; QTest::newRow("Case folding 8bit U+00DF (german sharp s)") -// << QString::fromUtf8("\xC3\xDF") ### typo in the original testsuite << QString::fromUtf8("\xC3\x9F") << QString("ss") << QString() << 0 << 0; @@ -2934,7 +2944,8 @@ void tst_QUrl::nameprep_testsuite_data() << QString() << 0 << 0; QTest::newRow("Self-reverting case folding U+01F0 and normalization") - << QString::fromUtf8("\xC7\xF0") +// << QString::fromUtf8("\xC7\xF0") ### typo in the original testsuite + << QString::fromUtf8("\xC7\xB0") << QString::fromUtf8("\xC7\xB0") << QString() << 0 << 0; @@ -3109,13 +3120,13 @@ void tst_QUrl::nameprep_testsuite_data() << QString("Nameprep") << STRINGPREP_NO_UNASSIGNED << STRINGPREP_CONTAINS_UNASSIGNED; QTest::newRow("Larger test (shrinking)") - << QString::fromUtf8("X\xC2\xAD\xC3\xDF\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" + << QString::fromUtf8("X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" "\xaa\xce\xb0\xe2\x80\x80") << QString::fromUtf8("xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ") << QString("Nameprep") << 0 << 0; QTest::newRow("Larger test (expanding)") - << QString::fromUtf8("X\xC3\xDF\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80") + << QString::fromUtf8("X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80") << QString::fromUtf8("xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88" "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91" "\xe3\x83\xbc\xe3\x83\x88") @@ -3136,20 +3147,58 @@ void tst_QUrl::nameprep_testsuite() QFETCH(QString, out); QFETCH(QString, profile); - QEXPECT_FAIL("Case folding U+2121 U+33C6 U+1D7BB", - ">0xffff unicode points are not supported", Continue); - QEXPECT_FAIL("Self-reverting case folding U+01F0 and normalization", - "Investigate further", Continue); QEXPECT_FAIL("Left-to-right mark U+200E", "Investigate further", Continue); QEXPECT_FAIL("Deprecated U+202A", "Investigate further", Continue); QEXPECT_FAIL("Language tagging character U+E0001", "Investigate further", Continue); - QEXPECT_FAIL("Larger test (shrinking)", - "Investigate further", Continue); - QEXPECT_FAIL("Larger test (expanding)", - "Investigate further", Continue); + qt_nameprep(&in, 0); + QCOMPARE(in, out); +#endif +} + +void tst_QUrl::nameprep_highcodes_data() +{ + QTest::addColumn<QString>("in"); + QTest::addColumn<QString>("out"); + QTest::addColumn<QString>("profile"); + QTest::addColumn<int>("flags"); + QTest::addColumn<int>("rc"); + + { + QChar st[] = { '-', 0xd801, 0xdc1d, 'a' }; + QChar se[] = { '-', 0xd801, 0xdc45, 'a' }; + QTest::newRow("highcodes (U+1041D)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } + { + QChar st[] = { 0x011C, 0xd835, 0xdf6e, 0x0110 }; + QChar se[] = { 0x011D, 0x03C9, 0x0111 }; + QTest::newRow("highcodes (U+1D76E)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } + { + QChar st[] = { 'D', 0xdb40, 0xdc20, 'o', 0xd834, 0xdd7a, '\'', 0x2060, 'h' }; + QChar se[] = { 'd', 'o', '\'', 'h' }; + QTest::newRow("highcodes (D, U+E0020, o, U+1D17A, ', U+2060, h)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } +} + +void tst_QUrl::nameprep_highcodes() +{ +#ifdef QT_BUILD_INTERNAL + QFETCH(QString, in); + QFETCH(QString, out); + QFETCH(QString, profile); + qt_nameprep(&in, 0); QCOMPARE(in, out); #endif diff --git a/tests/auto/selftests/expected_cmptest.txt b/tests/auto/selftests/expected_cmptest.txt index fd5b486..0beb46b 100644 --- a/tests/auto/selftests/expected_cmptest.txt +++ b/tests/auto/selftests/expected_cmptest.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Cmptest ********* -Config: Using QTest library 4.7.0, Qt 4.7.0 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_Cmptest::initTestCase() PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() diff --git a/tests/auto/selftests/expected_crashes_3.txt b/tests/auto/selftests/expected_crashes_3.txt index 3aced25..b7f462a 100644 --- a/tests/auto/selftests/expected_crashes_3.txt +++ b/tests/auto/selftests/expected_crashes_3.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Crashes ********* -Config: Using QTest library 4.7.0, Qt 4.7.0 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_Crashes::initTestCase() QFATAL : tst_Crashes::crash() Received signal 11 FAIL! : tst_Crashes::crash() Received a fatal error. diff --git a/tests/auto/selftests/expected_longstring.txt b/tests/auto/selftests/expected_longstring.txt index 1461bc6..99809a8 100644 --- a/tests/auto/selftests/expected_longstring.txt +++ b/tests/auto/selftests/expected_longstring.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_LongString ********* -Config: Using QTest library 4.7.0, Qt 4.7.0 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_LongString::initTestCase() FAIL! : tst_LongString::failWithLongString() Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. diff --git a/tests/auto/selftests/expected_maxwarnings.txt b/tests/auto/selftests/expected_maxwarnings.txt index 908bd5d..165bdda 100644 --- a/tests/auto/selftests/expected_maxwarnings.txt +++ b/tests/auto/selftests/expected_maxwarnings.txt @@ -1,5 +1,5 @@ ********* Start testing of MaxWarnings ********* -Config: Using QTest library 4.7.0, Qt 4.7.0 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : MaxWarnings::initTestCase() QWARN : MaxWarnings::warn() 0 QWARN : MaxWarnings::warn() 1 diff --git a/tests/auto/selftests/expected_skip.txt b/tests/auto/selftests/expected_skip.txt index e5bf1ff..4b53a43 100644 --- a/tests/auto/selftests/expected_skip.txt +++ b/tests/auto/selftests/expected_skip.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Skip ********* -Config: Using QTest library 4.7.0, Qt 4.7.0 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_Skip::initTestCase() SKIP : tst_Skip::test() skipping all Loc: [/home/user/depot/qt-git/mainline/tests/auto/selftests/skip/tst_skip.cpp(68)] diff --git a/tests/auto/utf8/tst_utf8.cpp b/tests/auto/utf8/tst_utf8.cpp index 7bbbfab..9b6b8c1 100644 --- a/tests/auto/utf8/tst_utf8.cpp +++ b/tests/auto/utf8/tst_utf8.cpp @@ -210,7 +210,9 @@ void tst_Utf8::invalidUtf8_data() QTest::addColumn<QByteArray>("utf8"); QTest::newRow("1char") << QByteArray("\x80"); - QTest::newRow("2chars") << QByteArray("\xC2\xC0"); + QTest::newRow("2chars-1") << QByteArray("\xC2\xC0"); + QTest::newRow("2chars-2") << QByteArray("\xC3\xDF"); + QTest::newRow("2chars-3") << QByteArray("\xC7\xF0"); QTest::newRow("3chars-1") << QByteArray("\xE0\xA0\xC0"); QTest::newRow("3chars-2") << QByteArray("\xE0\xC0\xA0"); QTest::newRow("4chars-1") << QByteArray("\xF0\x90\x80\xC0"); diff --git a/tests/benchmarks/corelib/io/qfileinfo/main.cpp b/tests/benchmarks/corelib/io/qfileinfo/main.cpp index 025787f..b272bda 100644 --- a/tests/benchmarks/corelib/io/qfileinfo/main.cpp +++ b/tests/benchmarks/corelib/io/qfileinfo/main.cpp @@ -43,15 +43,20 @@ #include <QtTest/QtTest> #include <QtCore/QCoreApplication> #include <QtCore/QFileInfo> +#include <QtCore/QFile> #include "private/qfsfileengine_p.h" +#include "../../../../shared/filesystem.h" class qfileinfo : public QObject { Q_OBJECT private slots: void canonicalFileNamePerformance(); - +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + void symLinkTargetPerformanceLNK(); + void symLinkTargetPerformanceMounpoint(); +#endif void initTestCase(); void cleanupTestCase(); public: @@ -78,6 +83,43 @@ void qfileinfo::canonicalFileNamePerformance() } } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +void qfileinfo::symLinkTargetPerformanceLNK() +{ + QVERIFY(QFile::link("file","link.lnk")); + QFileInfo info("link.lnk"); + info.setCaching(false); + QVERIFY(info.isSymLink()); + QString linkTarget; + QBENCHMARK { + for(int i=0; i<100; i++) + linkTarget = info.readLink(); + } + QVERIFY(QFile::remove("link.lnk")); +} + +void qfileinfo::symLinkTargetPerformanceMounpoint() +{ + wchar_t buffer[MAX_PATH]; + QString rootPath = QDir::toNativeSeparators(QDir::rootPath()); + QVERIFY(GetVolumeNameForVolumeMountPointW(rootPath.utf16(), buffer, MAX_PATH)); + QString rootVolume = QString::fromWCharArray(buffer); + QString mountpoint = "mountpoint"; + rootVolume.replace("\\\\?\\","\\??\\"); + FileSystem::createNtfsJunction(rootVolume, mountpoint); + + QFileInfo info(mountpoint); + info.setCaching(false); + QVERIFY(info.isSymLink()); + QString linkTarget; + QBENCHMARK { + for(int i=0; i<100; i++) + linkTarget = info.readLink(); + } + QVERIFY(QDir().rmdir(mountpoint)); +} +#endif + QTEST_MAIN(qfileinfo) #include "main.moc" diff --git a/tests/benchmarks/corelib/thread/qmutex/qmutex.pro b/tests/benchmarks/corelib/thread/qmutex/qmutex.pro new file mode 100644 index 0000000..eda2f11 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qmutex/qmutex.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_bench_qmutex + +SOURCES += tst_qmutex.cpp + diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp new file mode 100644 index 0000000..fded508 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtCore> + +#include <math.h> + +//TESTED_FILES= + + +class tst_QMutex : public QObject +{ + Q_OBJECT + +public: + tst_QMutex(); + virtual ~tst_QMutex(); + +private slots: + void noThread_data(); + void noThread(); +}; + +tst_QMutex::tst_QMutex() +{ +} + +tst_QMutex::~tst_QMutex() +{ +} + +void tst_QMutex::noThread_data() +{ + QTest::addColumn<int>("t"); + + QTest::newRow("noLock") << 1; + QTest::newRow("QMutexInline") << 2; + QTest::newRow("QMutex") << 3; + QTest::newRow("QMutexLocker") << 4; +} + +void tst_QMutex::noThread() +{ + volatile int count = 0; + const int N = 5000000; + QMutex mtx; + + QFETCH(int, t); + switch(t) { + case 1: + QBENCHMARK { + count = 0; + for (int i = 0; i < N; i++) { + count++; + } + } + break; + case 2: + QBENCHMARK { + count = 0; + for (int i = 0; i < N; i++) { + mtx.lockInline(); + count++; + mtx.unlockInline(); + } + } + break; + case 3: + QBENCHMARK { + count = 0; + for (int i = 0; i < N; i++) { + mtx.lock(); + count++; + mtx.unlock(); + } + } + break; + case 4: + QBENCHMARK { + count = 0; + for (int i = 0; i < N; i++) { + QMutexLocker locker(&mtx); + count++; + } + } + break; + } + QCOMPARE(int(count), N); +} + +QTEST_MAIN(tst_QMutex) +#include "tst_qmutex.moc" diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h index 2d46c0d..079a6dc 100644 --- a/tests/shared/filesystem.h +++ b/tests/shared/filesystem.h @@ -48,6 +48,15 @@ #include <QDir> #include <QFile> +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#include <windows.h> +#include <winioctl.h> +#ifndef IO_REPARSE_TAG_MOUNT_POINT +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) +#endif +#define REPARSE_MOUNTPOINT_HEADER_SIZE 8 +#endif + struct FileSystem { ~FileSystem() @@ -86,6 +95,59 @@ struct FileSystem } return false; } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + static void createNtfsJunction(QString target, QString linkName) + { + typedef struct { + DWORD ReparseTag; + DWORD ReparseDataLength; + WORD Reserved; + WORD ReparseTargetLength; + WORD ReparseTargetMaximumLength; + WORD Reserved1; + WCHAR ReparseTarget[1]; + } REPARSE_MOUNTPOINT_DATA_BUFFER, *PREPARSE_MOUNTPOINT_DATA_BUFFER; + + char reparseBuffer[MAX_PATH*3]; + HANDLE hFile; + DWORD returnedLength; + wchar_t fileSystem[MAX_PATH] = L""; + PREPARSE_MOUNTPOINT_DATA_BUFFER reparseInfo = (PREPARSE_MOUNTPOINT_DATA_BUFFER) reparseBuffer; + + QFileInfo junctionInfo(linkName); + linkName = QDir::toNativeSeparators(junctionInfo.absoluteFilePath()); + + GetVolumeInformationW( (wchar_t*)linkName.left(3).utf16(), NULL, 0, NULL, NULL, NULL, + fileSystem, sizeof(fileSystem)/sizeof(WCHAR)); + if(QString().fromWCharArray(fileSystem) != "NTFS") + QSKIP("This seems not to be an NTFS volume. Junctions are not allowed.",SkipSingle); + + if (!target.startsWith("\\??\\") && !target.startsWith("\\\\?\\")) { + QFileInfo targetInfo(target); + target = QDir::toNativeSeparators(targetInfo.absoluteFilePath()); + target.prepend("\\??\\"); + if(target.endsWith('\\') && target.at(target.length()-2) != ':') + target.chop(1); + } + QDir().mkdir(linkName); + hFile = CreateFileW( (wchar_t*)linkName.utf16(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL ); + QVERIFY(hFile != INVALID_HANDLE_VALUE ); + + memset( reparseInfo, 0, sizeof( *reparseInfo )); + reparseInfo->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + reparseInfo->ReparseTargetLength = target.size() * sizeof(wchar_t); + reparseInfo->ReparseTargetMaximumLength = reparseInfo->ReparseTargetLength + sizeof(wchar_t); + target.toWCharArray(reparseInfo->ReparseTarget); + reparseInfo->ReparseDataLength = reparseInfo->ReparseTargetLength + 12; + + bool ioc = DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, reparseInfo, + reparseInfo->ReparseDataLength + REPARSE_MOUNTPOINT_HEADER_SIZE, + NULL, 0, &returnedLength, NULL); + CloseHandle( hFile ); + QVERIFY(ioc); + } +#endif private: QDir currentDir; |