summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/collections/tst_collections.cpp11
-rw-r--r--tests/auto/corelib.pro1
-rw-r--r--tests/auto/gui.pro1
-rw-r--r--tests/auto/macnativeevents/expectedeventlist.cpp29
-rw-r--r--tests/auto/macnativeevents/expectedeventlist.h2
-rw-r--r--tests/auto/macnativeevents/nativeeventlist.cpp8
-rw-r--r--tests/auto/macnativeevents/nativeeventlist.h1
-rw-r--r--tests/auto/macnativeevents/qnativeevents_mac.cpp8
-rw-r--r--tests/auto/macnativeevents/tst_macnativeevents.cpp107
-rw-r--r--tests/auto/networkselftest/tst_networkselftest.cpp290
-rw-r--r--tests/auto/qaccessibility/tst_qaccessibility.cpp7
-rw-r--r--tests/auto/qcheckbox/tst_qcheckbox.cpp7
-rw-r--r--tests/auto/qcombobox/tst_qcombobox.cpp27
-rw-r--r--tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp16
-rw-r--r--tests/auto/qdir/tst_qdir.cpp46
-rw-r--r--tests/auto/qfiledialog2/tst_qfiledialog2.cpp4
-rw-r--r--tests/auto/qfileinfo/tst_qfileinfo.cpp170
-rw-r--r--tests/auto/qfontmetrics/qfontmetrics.pro2
-rw-r--r--tests/auto/qfontmetrics/testfont.qrc5
-rw-r--r--tests/auto/qfontmetrics/tst_qfontmetrics.cpp22
-rw-r--r--tests/auto/qfontmetrics/ucs4font.ttfbin0 -> 3076 bytes
-rw-r--r--tests/auto/qgl/tst_qgl.cpp26
-rw-r--r--tests/auto/qglyphs/qglyphs.pro11
-rw-r--r--tests/auto/qglyphs/test.ttfbin0 -> 3712 bytes
-rw-r--r--tests/auto/qglyphs/tst_qglyphs.cpp581
-rw-r--r--tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro2
-rw-r--r--tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro2
-rw-r--r--tests/auto/qgraphicseffect/qgraphicseffect.pro2
-rw-r--r--tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro2
-rw-r--r--tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro2
-rw-r--r--tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp27
-rw-r--r--tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro2
-rw-r--r--tests/auto/qgraphicslayout/qgraphicslayout.pro2
-rw-r--r--tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro2
-rw-r--r--tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro2
-rw-r--r--tests/auto/qgraphicsobject/qgraphicsobject.pro1
-rw-r--r--tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro2
-rw-r--r--tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro2
-rw-r--r--tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro2
-rw-r--r--tests/auto/qgraphicstransform/qgraphicstransform.pro1
-rw-r--r--tests/auto/qimage/tst_qimage.cpp128
-rw-r--r--tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp207
-rw-r--r--tests/auto/qlibrary/tst_qlibrary.cpp74
-rw-r--r--tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp6
-rw-r--r--tests/auto/qmetaobject/tst_qmetaobject.cpp136
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp6
-rw-r--r--tests/auto/qobject/tst_qobject.cpp221
-rw-r--r--tests/auto/qpainter/tst_qpainter.cpp37
-rw-r--r--tests/auto/qpluginloader/tst_qpluginloader.cpp10
-rw-r--r--tests/auto/qradiobutton/tst_qradiobutton.cpp6
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp34
-rw-r--r--tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp22
-rw-r--r--tests/auto/qscriptvalue/testgen/testgenerator.cpp107
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp43
-rw-r--r--tests/auto/qsharedpointer/tst_qsharedpointer.cpp8
-rw-r--r--tests/auto/qstring/tst_qstring.cpp74
-rw-r--r--tests/auto/qstringref/qstringref.pro4
-rw-r--r--tests/auto/qstringref/tst_qstringref.cpp881
-rw-r--r--tests/auto/qtabbar/tst_qtabbar.cpp41
-rw-r--r--tests/auto/qtabwidget/tst_qtabwidget.cpp72
-rw-r--r--tests/auto/qtextlayout/tst_qtextlayout.cpp24
-rw-r--r--tests/auto/qthreadpool/tst_qthreadpool.cpp27
-rw-r--r--tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp26
-rw-r--r--tests/auto/qurl/tst_qurl.cpp73
-rw-r--r--tests/auto/qwidget/tst_qwidget.cpp28
-rw-r--r--tests/auto/selftests/expected_cmptest.txt2
-rw-r--r--tests/auto/selftests/expected_crashes_3.txt2
-rw-r--r--tests/auto/selftests/expected_longstring.txt2
-rw-r--r--tests/auto/selftests/expected_maxwarnings.txt2
-rw-r--r--tests/auto/selftests/expected_skip.txt2
-rw-r--r--tests/auto/utf8/tst_utf8.cpp4
-rw-r--r--tests/benchmarks/corelib/io/qfileinfo/main.cpp44
-rw-r--r--tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp52
-rw-r--r--tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp47
-rw-r--r--tests/benchmarks/corelib/thread/qmutex/qmutex.pro6
-rw-r--r--tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp131
-rw-r--r--tests/benchmarks/gui/kernel/qguimetatype/qguimetatype.pro6
-rw-r--r--tests/benchmarks/gui/kernel/qguimetatype/tst_qguimetatype.cpp113
-rw-r--r--tests/benchmarks/gui/kernel/qguivariant/qguivariant.pro6
-rw-r--r--tests/benchmarks/gui/kernel/qguivariant/tst_qguivariant.cpp111
-rw-r--r--tests/benchmarks/script/qscriptqobject/qscriptqobject.pro7
-rw-r--r--tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp1237
-rw-r--r--tests/shared/filesystem.h62
83 files changed, 5333 insertions, 233 deletions
diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp
index d092c34..4ecd392 100644
--- a/tests/auto/collections/tst_collections.cpp
+++ b/tests/auto/collections/tst_collections.cpp
@@ -3447,27 +3447,16 @@ void tst_Collections::containerTypedefs()
testSetContainerTypedefs(QSet<int>());
}
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
-class Key1
-{};
-class T1
-{};
-class T2
-{};
-#else
class Key1;
class T1;
class T2;
-#endif
void tst_Collections::forwardDeclared()
{
{ typedef QHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
{ typedef QMultiHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
-#if !defined(Q_CC_MSVC_NET) || _MSC_VER >= 1310
{ typedef QMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
{ typedef QMultiMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
-#endif
#if !defined(Q_CC_RVCT)
// RVCT can't handle forward declared template parameters if those are used to declare
// class members inside templated class.
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 2d9ea93..c94272c 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/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
index 3125258..50b0e0a 100644
--- a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
+++ b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
@@ -273,6 +273,9 @@ private slots:
void task196924();
void focusNextPrevChild();
+
+ void taskQTBUG_12384_timeSpecShowTimeOnly();
+
private:
EditorDateEdit* testWidget;
QWidget *testFocusWidget;
@@ -3420,7 +3423,20 @@ void tst_QDateTimeEdit::focusNextPrevChild()
QCOMPARE(edit.currentSection(), QDateTimeEdit::MonthSection);
}
+void tst_QDateTimeEdit::taskQTBUG_12384_timeSpecShowTimeOnly()
+{
+ QDateTime time = QDateTime::fromString("20100723 04:02:40", "yyyyMMdd hh:mm:ss");
+ time.setTimeSpec(Qt::UTC);
+
+ EditorDateEdit edit;
+ edit.setDisplayFormat("hh:mm:ss");
+ edit.setTimeSpec(Qt::UTC);
+ edit.setDateTime(time);
+ QCOMPARE(edit.minimumTime(), QTime(0, 0, 0, 0));
+ QCOMPARE(edit.maximumTime(), QTime(23, 59, 59, 999));
+ QCOMPARE(edit.time(), time.time());
+}
QTEST_MAIN(tst_QDateTimeEdit)
#include "tst_qdatetimeedit.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 6299c24..ed4ecb4 100644
--- a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp
+++ b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp
@@ -548,7 +548,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);
@@ -556,7 +556,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 93b1891..a074f4b 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()
@@ -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/qfontmetrics/qfontmetrics.pro b/tests/auto/qfontmetrics/qfontmetrics.pro
index 51a7057..c0dc1ab 100644
--- a/tests/auto/qfontmetrics/qfontmetrics.pro
+++ b/tests/auto/qfontmetrics/qfontmetrics.pro
@@ -1,4 +1,4 @@
load(qttest_p4)
SOURCES += tst_qfontmetrics.cpp
-
+RESOURCES += testfont.qrc
diff --git a/tests/auto/qfontmetrics/testfont.qrc b/tests/auto/qfontmetrics/testfont.qrc
new file mode 100644
index 0000000..bc0c0b0
--- /dev/null
+++ b/tests/auto/qfontmetrics/testfont.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/fonts">
+ <file>ucs4font.ttf</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp
index a22d624..4250415 100644
--- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp
+++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp
@@ -74,6 +74,7 @@ private slots:
void bypassShaping();
void elidedMultiLength();
void elidedMultiLengthF();
+ void inFontUcs4();
};
tst_QFontMetrics::tst_QFontMetrics()
@@ -266,5 +267,26 @@ void tst_QFontMetrics::elidedMultiLengthF()
elidedMultiLength_helper<QFontMetricsF>();
}
+void tst_QFontMetrics::inFontUcs4()
+{
+ int id = QFontDatabase::addApplicationFont(":/fonts/ucs4font.ttf");
+ QVERIFY(id >= 0);
+
+ QFont font("QtTestUcs4");
+ {
+ QFontMetrics fm(font);
+
+ QVERIFY(fm.inFontUcs4(0x1D7FF));
+ }
+
+ {
+ QFontMetricsF fm(font);
+
+ QVERIFY(fm.inFontUcs4(0x1D7FF));
+ }
+
+ QFontDatabase::removeApplicationFont(id);
+}
+
QTEST_MAIN(tst_QFontMetrics)
#include "tst_qfontmetrics.moc"
diff --git a/tests/auto/qfontmetrics/ucs4font.ttf b/tests/auto/qfontmetrics/ucs4font.ttf
new file mode 100644
index 0000000..31b6997
--- /dev/null
+++ b/tests/auto/qfontmetrics/ucs4font.ttf
Binary files differ
diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp
index 7fe461c..5fe453b 100644
--- a/tests/auto/qgl/tst_qgl.cpp
+++ b/tests/auto/qgl/tst_qgl.cpp
@@ -1871,11 +1871,10 @@ void tst_QGL::destroyFBOAfterContext()
#ifdef QT_BUILD_INTERNAL
-class tst_QGLResource : public QObject
+class tst_QGLResource
{
- Q_OBJECT
public:
- tst_QGLResource(QObject *parent = 0) : QObject(parent) {}
+ tst_QGLResource(const QGLContext * = 0) {}
~tst_QGLResource() { ++deletions; }
static int deletions;
@@ -1883,12 +1882,7 @@ public:
int tst_QGLResource::deletions = 0;
-static void qt_shared_test_free(void *data)
-{
- delete reinterpret_cast<tst_QGLResource *>(data);
-}
-
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shared_test, (qt_shared_test_free))
+Q_GLOBAL_STATIC(QGLContextGroupResource<tst_QGLResource>, qt_shared_test)
#endif
@@ -1908,10 +1902,9 @@ void tst_QGL::shareRegister()
guard.setId(3);
QVERIFY(guard.id() == 3);
- // Add a resource to the first context.
- tst_QGLResource *res1 = new tst_QGLResource();
- QVERIFY(!qt_shared_test()->value(glw1->context()));
- qt_shared_test()->insert(glw1->context(), res1);
+ // Request a tst_QGLResource object for the first context.
+ tst_QGLResource *res1 = qt_shared_test()->value(glw1->context());
+ QVERIFY(res1);
QVERIFY(qt_shared_test()->value(glw1->context()) == res1);
// Create another context that shares with the first.
@@ -1950,10 +1943,9 @@ void tst_QGL::shareRegister()
QGLSharedResourceGuard guard3(glw3->context());
guard3.setId(5);
- // Add a resource to the third context.
- tst_QGLResource *res3 = new tst_QGLResource();
- QVERIFY(!qt_shared_test()->value(glw3->context()));
- qt_shared_test()->insert(glw3->context(), res3);
+ // Request a resource to the third context.
+ tst_QGLResource *res3 = qt_shared_test()->value(glw3->context());
+ QVERIFY(res3);
QVERIFY(qt_shared_test()->value(glw1->context()) == res1);
QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
QVERIFY(qt_shared_test()->value(glw3->context()) == res3);
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
new file mode 100644
index 0000000..9043a57
--- /dev/null
+++ b/tests/auto/qglyphs/test.ttf
Binary files differ
diff --git a/tests/auto/qglyphs/tst_qglyphs.cpp b/tests/auto/qglyphs/tst_qglyphs.cpp
new file mode 100644
index 0000000..b75e801
--- /dev/null
+++ b/tests/auto/qglyphs/tst_qglyphs.cpp
@@ -0,0 +1,581 @@
+/****************************************************************************
+**
+** 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 drawStruckOutText();
+ void drawOverlinedText();
+ void drawUnderlinedText();
+ void drawRightToLeft();
+ 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);
+}
+
+void tst_QGlyphs::drawStruckOutText()
+{
+ QPixmap textLayoutDraw(1000, 1000);
+ QPixmap drawGlyphs(1000, 1000);
+
+ textLayoutDraw.fill(Qt::white);
+ drawGlyphs.fill(Qt::white);
+
+ QString s = QString::fromLatin1("Foobar");
+
+ QFont font;
+ font.setStrikeOut(true);
+
+ QTextLayout layout(s);
+ layout.setFont(font);
+ 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("drawStruckOutText_textLayoutDraw.png");
+ drawGlyphs.save("drawStruckOutText_drawGlyphIndexes.png");
+#endif
+
+ QCOMPARE(textLayoutDraw, drawGlyphs);
+}
+
+void tst_QGlyphs::drawOverlinedText()
+{
+ QPixmap textLayoutDraw(1000, 1000);
+ QPixmap drawGlyphs(1000, 1000);
+
+ textLayoutDraw.fill(Qt::white);
+ drawGlyphs.fill(Qt::white);
+
+ QString s = QString::fromLatin1("Foobar");
+
+ QFont font;
+ font.setOverline(true);
+
+ QTextLayout layout(s);
+ layout.setFont(font);
+ 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("drawOverlineText_textLayoutDraw.png");
+ drawGlyphs.save("drawOverlineText_drawGlyphIndexes.png");
+#endif
+
+ QCOMPARE(textLayoutDraw, drawGlyphs);
+}
+
+void tst_QGlyphs::drawUnderlinedText()
+{
+ QPixmap textLayoutDraw(1000, 1000);
+ QPixmap drawGlyphs(1000, 1000);
+
+ textLayoutDraw.fill(Qt::white);
+ drawGlyphs.fill(Qt::white);
+
+ QString s = QString::fromLatin1("Foobar");
+
+ QFont font;
+ font.setUnderline(true);
+
+ QTextLayout layout(s);
+ layout.setFont(font);
+ 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("drawUnderlineText_textLayoutDraw.png");
+ drawGlyphs.save("drawUnderlineText_drawGlyphIndexes.png");
+#endif
+
+ QCOMPARE(textLayoutDraw, drawGlyphs);
+}
+
+void tst_QGlyphs::drawRightToLeft()
+{
+#if defined(Q_WS_MAC)
+ QSKIP("Unstable because of QTBUG-11145", SkipAll);
+#endif
+
+ QString s;
+ s.append(QChar(1575));
+ s.append(QChar(1578));
+
+ QPixmap textLayoutDraw(1000, 1000);
+ QPixmap drawGlyphs(1000, 1000);
+
+ textLayoutDraw.fill(Qt::white);
+ drawGlyphs.fill(Qt::white);
+
+ QFont font;
+ font.setUnderline(true);
+
+ QTextLayout layout(s);
+ layout.setFont(font);
+ 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("drawRightToLeft_textLayoutDraw.png");
+ drawGlyphs.save("drawRightToLeft_drawGlyphIndexes.png");
+#endif
+
+ QCOMPARE(textLayoutDraw, drawGlyphs);
+
+}
+
+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/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
index 03c1d5b..7346f07 100644
--- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
+++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
@@ -78,6 +78,7 @@ private slots:
void horizontalSpacing();
void itemAt();
void removeAt();
+ void removeItem();
void rowAlignment();
void rowCount();
void rowMaximumHeight();
@@ -1020,6 +1021,32 @@ void tst_QGraphicsGridLayout::removeAt()
delete widget;
}
+void tst_QGraphicsGridLayout::removeItem()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+
+ QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
+ scene.addItem(widget);
+ QGraphicsGridLayout *l = new QGraphicsGridLayout();
+ widget->setLayout(l);
+
+ populateLayout(l, 3, 2);
+ QCOMPARE(l->count(), 6);
+ l->removeItem(l->itemAt(5));
+ l->removeItem(l->itemAt(4));
+ QCOMPARE(l->count(), 4);
+
+ // Avoid crashing. Note that the warning message might change in the future.
+ QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QGraphicsGridLayout::removeAt: invalid index -1").toLatin1().constData());
+ l->removeItem(0);
+ QCOMPARE(l->count(), 4);
+
+ QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QGraphicsGridLayout::removeAt: invalid index -1").toLatin1().constData());
+ l->removeItem(new QGraphicsWidget);
+ QCOMPARE(l->count(), 4);
+}
+
// public Qt::Alignment rowAlignment(int row) const
void tst_QGraphicsGridLayout::rowAlignment()
{
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 49514dc..46bc6e7 100644
--- a/tests/auto/qimage/tst_qimage.cpp
+++ b/tests/auto/qimage/tst_qimage.cpp
@@ -59,6 +59,7 @@
#endif
Q_DECLARE_METATYPE(QImage::Format)
+Q_DECLARE_METATYPE(Qt::GlobalColor)
class tst_QImage : public QObject
{
@@ -140,6 +141,11 @@ private slots:
void compareIndexed();
+ void fillColor_data();
+ void fillColor();
+
+ void fillColorWithAlpha();
+
void rgbSwapped_data();
void rgbSwapped();
};
@@ -1451,11 +1457,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()
{
@@ -1483,6 +1484,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) {
@@ -1490,11 +1492,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);
}
}
@@ -1823,6 +1829,112 @@ void tst_QImage::compareIndexed()
QCOMPARE(img, imgInverted);
}
+void tst_QImage::fillColor_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<Qt::GlobalColor>("color");
+ QTest::addColumn<uint>("pixelValue");
+
+ QTest::newRow("Mono, color0") << QImage::Format_Mono << Qt::color0 << 0u;
+ QTest::newRow("Mono, color1") << QImage::Format_Mono << Qt::color1 << 1u;
+
+ QTest::newRow("MonoLSB, color0") << QImage::Format_MonoLSB << Qt::color0 << 0u;
+ QTest::newRow("MonoLSB, color1") << QImage::Format_MonoLSB << Qt::color1 << 1u;
+
+ const char *names[] = {
+ "Indexed8",
+ "RGB32",
+ "ARGB32",
+ "ARGB32pm",
+ "RGB16",
+ "ARGB8565pm",
+ "RGB666",
+ "ARGB6666pm",
+ "RGB555",
+ "ARGB8555pm",
+ "RGB888",
+ "RGB444",
+ "ARGB4444pm",
+ 0
+ };
+
+ QImage::Format formats[] = {
+ QImage::Format_Indexed8,
+ QImage::Format_RGB32,
+ QImage::Format_ARGB32,
+ QImage::Format_ARGB32_Premultiplied,
+ QImage::Format_RGB16,
+ QImage::Format_ARGB8565_Premultiplied,
+ QImage::Format_RGB666,
+ QImage::Format_ARGB6666_Premultiplied,
+ QImage::Format_RGB555,
+ QImage::Format_ARGB8555_Premultiplied,
+ QImage::Format_RGB888,
+ QImage::Format_RGB444,
+ QImage::Format_ARGB4444_Premultiplied
+ };
+
+ for (int i=0; names[i] != 0; ++i) {
+ QByteArray name;
+ name.append(names[i]).append(", ");
+
+ QTest::newRow(QByteArray(name).append("black").constData()) << formats[i] << Qt::black << 0xff000000;
+ QTest::newRow(QByteArray(name).append("white").constData()) << formats[i] << Qt::white << 0xffffffff;
+ QTest::newRow(QByteArray(name).append("red").constData()) << formats[i] << Qt::red << 0xffff0000;
+ QTest::newRow(QByteArray(name).append("green").constData()) << formats[i] << Qt::green << 0xff00ff00;
+ QTest::newRow(QByteArray(name).append("blue").constData()) << formats[i] << Qt::blue << 0xff0000ff;
+ }
+
+ QTest::newRow("RGB16, transparent") << QImage::Format_RGB16 << Qt::transparent << 0xff000000;
+ QTest::newRow("RGB32, transparent") << QImage::Format_RGB32 << Qt::transparent << 0xff000000;
+ QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << Qt::transparent << 0x00000000u;
+ QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << Qt::transparent << 0x00000000u;
+}
+
+void tst_QImage::fillColor()
+{
+ QFETCH(QImage::Format, format);
+ QFETCH(Qt::GlobalColor, color);
+ QFETCH(uint, pixelValue);
+
+ QImage image(1, 1, format);
+
+ if (image.depth() == 8) {
+ QVector<QRgb> table;
+ table << 0xff000000;
+ table << 0xffffffff;
+ table << 0xffff0000;
+ table << 0xff00ff00;
+ table << 0xff0000ff;
+ image.setColorTable(table);
+ }
+
+ image.fill(color);
+ if (image.depth() == 1) {
+ QCOMPARE(image.pixelIndex(0, 0), (int) pixelValue);
+ } else {
+ QCOMPARE(image.pixel(0, 0), pixelValue);
+ }
+
+ image.fill(QColor(color));
+ if (image.depth() == 1) {
+ QCOMPARE(image.pixelIndex(0, 0), (int) pixelValue);
+ } else {
+ QCOMPARE(image.pixel(0, 0), pixelValue);
+ }
+}
+
+void tst_QImage::fillColorWithAlpha()
+{
+ QImage argb32(1, 1, QImage::Format_ARGB32);
+ argb32.fill(QColor(255, 0, 0, 127));
+ QCOMPARE(argb32.pixel(0, 0), qRgba(255, 0, 0, 127));
+
+ QImage argb32pm(1, 1, QImage::Format_ARGB32_Premultiplied);
+ argb32pm.fill(QColor(255, 0, 0, 127));
+ QCOMPARE(argb32pm.pixel(0, 0), 0x7f7f0000u);
+}
+
void tst_QImage::rgbSwapped_data()
{
QTest::addColumn<QImage::Format>("format");
diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp
index 3b2a716..46bd4a2 100644
--- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp
+++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp
@@ -94,6 +94,9 @@ private slots:
void task260134_layoutChangedWithAllSelected();
void QTBUG5671_layoutChangedWithAllSelected();
void QTBUG2804_layoutChangedTreeSelection();
+ void deselectRemovedMiddleRange();
+ void rangeOperatorLessThan_data();
+ void rangeOperatorLessThan();
private:
QAbstractItemModel *model;
@@ -2353,6 +2356,210 @@ 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);
+}
+
+static QStandardItemModel* getModel(QObject *parent)
+{
+ QStandardItemModel *model = new QStandardItemModel(parent);
+
+ for (int i = 0; i < 4; ++i) {
+ QStandardItem *parentItem = model->invisibleRootItem();
+ QList<QStandardItem*> list;
+ for (int j = 0; j < 4; ++j) {
+ list.append(new QStandardItem(QString("item %1, %2").arg(i).arg(j)));
+ }
+ parentItem->appendRow(list);
+ parentItem = list.first();
+ for (int j = 0; j < 4; ++j) {
+ QList<QStandardItem*> list;
+ for (int k = 0; k < 4; ++k) {
+ list.append(new QStandardItem(QString("item %1, %2").arg(i).arg(j)));
+ }
+ parentItem->appendRow(list);
+ }
+ }
+ return model;
+}
+
+enum Result {
+ LessThan,
+ NotLessThan,
+ NotEqual
+};
+
+Q_DECLARE_METATYPE(Result);
+
+void tst_QItemSelectionModel::rangeOperatorLessThan_data()
+{
+ QTest::addColumn<int>("parent1");
+ QTest::addColumn<int>("top1");
+ QTest::addColumn<int>("left1");
+ QTest::addColumn<int>("bottom1");
+ QTest::addColumn<int>("right1");
+ QTest::addColumn<int>("parent2");
+ QTest::addColumn<int>("top2");
+ QTest::addColumn<int>("left2");
+ QTest::addColumn<int>("bottom2");
+ QTest::addColumn<int>("right2");
+ QTest::addColumn<Result>("result");
+
+ QTest::newRow("lt01") << -1 << 0 << 0 << 3 << 3
+ << -1 << 0 << 0 << 3 << 3 << NotLessThan;
+
+ QTest::newRow("lt02") << -1 << 0 << 0 << 2 << 3
+ << -1 << 0 << 0 << 3 << 3 << LessThan;
+ QTest::newRow("lt03") << -1 << 0 << 0 << 3 << 2
+ << -1 << 0 << 0 << 3 << 3 << LessThan;
+ QTest::newRow("lt04") << -1 << 0 << 0 << 2 << 2
+ << -1 << 0 << 0 << 3 << 3 << LessThan;
+
+ QTest::newRow("lt05") << -1 << 0 << 0 << 3 << 3
+ << -1 << 0 << 0 << 2 << 3 << NotLessThan;
+ QTest::newRow("lt06") << -1 << 0 << 0 << 3 << 3
+ << -1 << 0 << 0 << 3 << 2 << NotLessThan;
+ QTest::newRow("lt07") << -1 << 0 << 0 << 3 << 3
+ << -1 << 0 << 0 << 2 << 2 << NotLessThan;
+
+ QTest::newRow("lt08") << -1 << 0 << 0 << 3 << 3
+ << 0 << 0 << 0 << 3 << 3 << NotEqual;
+ QTest::newRow("lt09") << 1 << 0 << 0 << 3 << 3
+ << 0 << 0 << 0 << 3 << 3 << NotEqual;
+ QTest::newRow("lt10") << 1 << 0 << 0 << 1 << 1
+ << 0 << 2 << 2 << 3 << 3 << NotEqual;
+ QTest::newRow("lt11") << 1 << 2 << 2 << 3 << 3
+ << 0 << 0 << 0 << 1 << 1 << NotEqual;
+
+ QTest::newRow("lt12") << -1 << 0 << 0 << 1 << 1
+ << -1 << 2 << 2 << 3 << 3 << LessThan;
+ QTest::newRow("lt13") << -1 << 2 << 2 << 3 << 3
+ << -1 << 0 << 0 << 1 << 1 << NotLessThan;
+ QTest::newRow("lt14") << 1 << 0 << 0 << 1 << 1
+ << 1 << 2 << 2 << 3 << 3 << LessThan;
+ QTest::newRow("lt15") << 1 << 2 << 2 << 3 << 3
+ << 1 << 0 << 0 << 1 << 1 << NotLessThan;
+
+ QTest::newRow("lt16") << -1 << 0 << 0 << 2 << 2
+ << -1 << 1 << 1 << 3 << 3 << LessThan;
+ QTest::newRow("lt17") << -1 << 1 << 1 << 3 << 3
+ << -1 << 0 << 0 << 2 << 2 << NotLessThan;
+ QTest::newRow("lt18") << 1 << 0 << 0 << 2 << 2
+ << 1 << 1 << 1 << 3 << 3 << LessThan;
+ QTest::newRow("lt19") << 1 << 1 << 1 << 3 << 3
+ << 1 << 0 << 0 << 2 << 2 << NotLessThan;
+}
+
+void tst_QItemSelectionModel::rangeOperatorLessThan()
+{
+ QStandardItemModel *model1 = getModel(this);
+ QStandardItemModel *model2 = getModel(this);
+
+ QFETCH(int, parent1);
+ QFETCH(int, top1);
+ QFETCH(int, left1);
+ QFETCH(int, bottom1);
+ QFETCH(int, right1);
+ QFETCH(int, parent2);
+ QFETCH(int, top2);
+ QFETCH(int, left2);
+ QFETCH(int, bottom2);
+ QFETCH(int, right2);
+ QFETCH(Result, result);
+
+ QModelIndex p1 = model1->index(parent1, 0);
+
+ QModelIndex tl1 = model1->index(top1, left1, p1);
+ QModelIndex br1 = model1->index(bottom1, right1, p1);
+
+ QItemSelectionRange r1(tl1, br1);
+
+ QModelIndex p2 = model1->index(parent2, 0);
+
+ QModelIndex tl2 = model1->index(top2, left2, p2);
+ QModelIndex br2 = model1->index(bottom2, right2, p2);
+
+ QItemSelectionRange r2(tl2, br2);
+
+ if (result == LessThan)
+ QVERIFY(r1 < r2);
+ else if (result == NotLessThan)
+ QVERIFY(!(r1 < r2));
+ else if (result == NotEqual)
+ if (!(r1 < r2))
+ QVERIFY(r2 < r1);
+
+ // Ranges in different models are always non-equal
+
+ QModelIndex p3 = model2->index(parent1, 0);
+
+ QModelIndex tl3 = model2->index(top1, left1, p3);
+ QModelIndex br3 = model2->index(bottom1, right1, p3);
+
+ QItemSelectionRange r3(tl3, br3);
+
+ if (!(r1 < r3))
+ QVERIFY(r3 < r1);
+
+ if (!(r2 < r3))
+ QVERIFY(r3 < r2);
+
+ QModelIndex p4 = model2->index(parent2, 0);
+
+ QModelIndex tl4 = model2->index(top2, left2, p4);
+ QModelIndex br4 = model2->index(bottom2, right2, p4);
+
+ QItemSelectionRange r4(tl4, br4);
+
+ if (!(r1 < r4))
+ QVERIFY(r4 < r1);
+
+ if (!(r2 < r4))
+ QVERIFY(r4 < r2);
+}
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/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp
index 5709196..22c679a 100644
--- a/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp
+++ b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp
@@ -2822,10 +2822,9 @@ void tst_QMatrixNxN::convertGeneric()
9.0f, 10.0f, 11.0f, 12.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
-#if !defined(QT_NO_MEMBER_TEMPLATES)
QMatrix4x4 m4(m1);
QVERIFY(isSame(m4, unique4x4));
-#endif
+
QMatrix4x4 m5 = qGenericMatrixToMatrix4x4(m1);
QVERIFY(isSame(m5, unique4x4));
@@ -2835,10 +2834,9 @@ void tst_QMatrixNxN::convertGeneric()
9.0f, 10.0f, 11.0f, 12.0f
};
QMatrix4x4 m9(uniqueValues4);
-#if !defined(QT_NO_MEMBER_TEMPLATES)
+
QMatrix4x3 m10 = m9.toGenericMatrix<4, 3>();
QVERIFY(isSame(m10, conv4x4));
-#endif
QMatrix4x3 m11 = qGenericMatrixFromMatrix4x4<4, 3>(m9);
QVERIFY(isSame(m11, conv4x4));
diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp
index bb96da1..ff39842 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..fc38a84 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:
};
@@ -663,11 +669,9 @@ void tst_QObject::findChildren()
l = qFindChildren<QObject*>(&o, "unnamed");
QCOMPARE(l.size(), 0);
-#ifndef QT_NO_MEMBER_TEMPLATES
tl = o.findChildren<QTimer *>("t1");
QCOMPARE(tl.size(), 1);
QCOMPARE(tl.at(0), &t1);
-#endif
}
@@ -727,6 +731,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 +3632,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/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index 2cbb9b2..a35e38e 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -170,6 +170,8 @@ private slots:
void clippedText();
+ void clipBoundingRect();
+
void setOpacity_data();
void setOpacity();
@@ -4565,6 +4567,41 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate()
QCOMPARE(widget->deviceTransform, proxy->deviceTransform);
}
+void tst_QPainter::clipBoundingRect()
+{
+ QPixmap pix(500, 500);
+
+ QPainter p(&pix);
+
+ // Test a basic rectangle
+ p.setClipRect(100, 100, 200, 100);
+ QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200)));
+ p.setClipRect(120, 120, 20, 20, Qt::IntersectClip);
+ QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+
+ // Test a basic path + region
+ QPainterPath path;
+ path.addRect(100, 100, 200, 100);
+ p.setClipPath(path);
+ QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200)));
+ p.setClipRegion(QRegion(120, 120, 20, 20), Qt::IntersectClip);
+ QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+
+ p.setClipRect(0, 0, 500, 500);
+ p.translate(250, 250);
+ for (int i=0; i<360; ++i) {
+ p.rotate(1);
+ p.setClipRect(-100, -100, 200, 200, Qt::IntersectClip);
+ }
+ QVERIFY(p.clipBoundingRect().contains(QRectF(-100, -100, 200, 200)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(-250, -250, 500, 500)));
+
+}
+
void tst_QPainter::drawHorizontalLine()
{
QPixmap pixmap(100, 3);
diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp
index e913cb5..1e382b8 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 7a732cc..04b2627 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -1909,7 +1909,6 @@ void tst_QScriptEngine::valueConversion()
QString snum = qScriptValueToValue<QString>(num);
QCOMPARE(snum, QLatin1String("123"));
}
-#ifndef QT_NO_MEMBER_TEMPLATES
{
QScriptValue num = eng.toScriptValue(123);
QCOMPARE(num.isNumber(), true);
@@ -1921,7 +1920,6 @@ void tst_QScriptEngine::valueConversion()
QString snum = eng.fromScriptValue<QString>(num);
QCOMPARE(snum, QLatin1String("123"));
}
-#endif
{
QScriptValue num(&eng, 123);
QCOMPARE(qScriptValueToValue<char>(num), char(123));
@@ -2091,6 +2089,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/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index 83a3388..18480cc 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -2238,19 +2238,36 @@ void tst_QScriptValue::getSetScope()
void tst_QScriptValue::getSetData()
{
QScriptEngine eng;
- QScriptValue object = eng.newObject();
- QVERIFY(!object.data().isValid());
- QScriptValue v1(true);
- object.setData(v1);
- QVERIFY(object.data().strictlyEquals(v1));
- QScriptValue v2(123);
- object.setData(v2);
- QVERIFY(object.data().strictlyEquals(v2));
- QScriptValue v3 = eng.newObject();
- object.setData(v3);
- QVERIFY(object.data().strictlyEquals(v3));
- object.setData(QScriptValue());
- QVERIFY(!object.data().isValid());
+ {
+ QScriptValue object = eng.newObject();
+ QVERIFY(!object.data().isValid());
+ QScriptValue v1(true);
+ object.setData(v1);
+ QVERIFY(object.data().strictlyEquals(v1));
+ QScriptValue v2(123);
+ object.setData(v2);
+ QVERIFY(object.data().strictlyEquals(v2));
+ QScriptValue v3 = eng.newObject();
+ object.setData(v3);
+ QVERIFY(object.data().strictlyEquals(v3));
+ object.setData(QScriptValue());
+ QVERIFY(!object.data().isValid());
+ }
+ {
+ QScriptValue value = eng.undefinedValue();
+ QVERIFY(!value.data().isValid());
+ QScriptValue v1(true);
+ value.setData(v1);
+ QVERIFY(!value.data().isValid());
+ QScriptValue v2(123);
+ value.setData(v2);
+ QVERIFY(!value.data().isValid());
+ QScriptValue v3 = eng.newObject();
+ value.setData(v3);
+ QVERIFY(!value.data().isValid());
+ value.setData(QScriptValue());
+ QVERIFY(!value.data().isValid());
+ }
}
class TestScriptClass : public QScriptClass
diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
index 6b4904f..5e624e4 100644
--- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
@@ -732,7 +732,6 @@ void tst_QSharedPointer::objectCast()
ptr = baseptr.objectCast<OtherObject>();
QVERIFY(ptr == data);
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
// again:
ptr = qobject_cast<OtherObject *>(baseptr);
QVERIFY(ptr == data);
@@ -740,7 +739,6 @@ void tst_QSharedPointer::objectCast()
// again:
ptr = qobject_cast<QSharedPointer<OtherObject> >(baseptr);
QVERIFY(ptr == data);
-#endif
}
check();
@@ -760,7 +758,6 @@ void tst_QSharedPointer::objectCast()
ptr = baseptr.objectCast<const OtherObject>();
QVERIFY(ptr == data);
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
// again:
ptr = qobject_cast<const OtherObject *>(baseptr);
QVERIFY(ptr == data);
@@ -768,7 +765,6 @@ void tst_QSharedPointer::objectCast()
// again:
ptr = qobject_cast<QSharedPointer<const OtherObject> >(baseptr);
QVERIFY(ptr == data);
-#endif
}
check();
@@ -802,7 +798,6 @@ void tst_QSharedPointer::objectCast()
QSharedPointer<OtherObject> otherptr = qSharedPointerObjectCast<OtherObject>(weakptr);
QVERIFY(otherptr.isNull());
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
// again:
otherptr = qobject_cast<OtherObject *>(weakptr);
QVERIFY(otherptr.isNull());
@@ -810,7 +805,6 @@ void tst_QSharedPointer::objectCast()
// again:
otherptr = qobject_cast<QSharedPointer<OtherObject> >(weakptr);
QVERIFY(otherptr.isNull());
-#endif
}
check();
}
@@ -1736,12 +1730,10 @@ void tst_QSharedPointer::invalidConstructs_data()
<< &QTest::QExternalTest::tryCompileFail
<< "QSharedPointer<const QObject> baseptr = QSharedPointer<const QObject>(new QObject);\n"
"qSharedPointerObjectCast<QCoreApplication>(baseptr);";
-#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
QTest::newRow("const-dropping-object-cast2")
<< &QTest::QExternalTest::tryCompileFail
<< "QSharedPointer<const QObject> baseptr = QSharedPointer<const QObject>(new QObject);\n"
"qobject_cast<QCoreApplication *>(baseptr);";
-#endif
// arithmethics through automatic cast operators
QTest::newRow("arithmethic1")
diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp
index ef82769..a3f7f15 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();
@@ -1065,12 +1070,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 );
@@ -1098,12 +1105,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 );
@@ -1112,6 +1121,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);
}
}
@@ -1172,14 +1182,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 );
@@ -1246,10 +1259,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);
@@ -1279,20 +1294,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
@@ -1307,8 +1325,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;
@@ -2829,6 +2881,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) );
@@ -2854,6 +2914,7 @@ void tst_QString::startsWith()
QVERIFY( !a.startsWith(QLatin1Char(0)) );
QVERIFY( !a.startsWith(QLatin1Char('x')) );
QVERIFY( !a.startsWith(QChar()) );
+
}
void tst_QString::endsWith()
@@ -2921,6 +2982,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 659ba1a..dcc43d0 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();
@@ -544,6 +545,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()
@@ -557,12 +562,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/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp
index f722f89..2413888 100644
--- a/tests/auto/qwidget/tst_qwidget.cpp
+++ b/tests/auto/qwidget/tst_qwidget.cpp
@@ -456,23 +456,15 @@ void tst_QWidget::getSetCheck()
QCOMPARE(obj1.minimumWidth(), 0); // A widgets width can never be less than 0
obj1.setMinimumWidth(INT_MAX);
#ifndef Q_WS_QWS //QWS doesn't allow toplevels to be bigger than the screen
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- QCOMPARE((long)obj1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
-#else
QCOMPARE(obj1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
#endif
-#endif
child1.setMinimumWidth(0);
QCOMPARE(child1.minimumWidth(), 0);
child1.setMinimumWidth(INT_MIN);
QCOMPARE(child1.minimumWidth(), 0); // A widgets width can never be less than 0
child1.setMinimumWidth(INT_MAX);
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- QCOMPARE((long)child1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
-#else
QCOMPARE(child1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
-#endif
// int QWidget::minimumHeight()
// void QWidget::setMinimumHeight(int)
@@ -482,38 +474,24 @@ void tst_QWidget::getSetCheck()
QCOMPARE(obj1.minimumHeight(), 0); // A widgets height can never be less than 0
obj1.setMinimumHeight(INT_MAX);
#ifndef Q_WS_QWS //QWS doesn't allow toplevels to be bigger than the screen
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- QCOMPARE((long)obj1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
-#else
QCOMPARE(obj1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
#endif
-#endif
child1.setMinimumHeight(0);
QCOMPARE(child1.minimumHeight(), 0);
child1.setMinimumHeight(INT_MIN);
QCOMPARE(child1.minimumHeight(), 0); // A widgets height can never be less than 0
child1.setMinimumHeight(INT_MAX);
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- QCOMPARE((long)child1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
-#else
QCOMPARE(child1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
-#endif
-
-
-// int QWidget::maximumWidth()
+ // int QWidget::maximumWidth()
// void QWidget::setMaximumWidth(int)
obj1.setMaximumWidth(0);
QCOMPARE(obj1.maximumWidth(), 0);
obj1.setMaximumWidth(INT_MIN);
QCOMPARE(obj1.maximumWidth(), 0); // A widgets width can never be less than 0
obj1.setMaximumWidth(INT_MAX);
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- QCOMPARE((long)obj1.maximumWidth(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
-#else
QCOMPARE(obj1.maximumWidth(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
-#endif
// int QWidget::maximumHeight()
// void QWidget::setMaximumHeight(int)
@@ -522,11 +500,7 @@ void tst_QWidget::getSetCheck()
obj1.setMaximumHeight(INT_MIN);
QCOMPARE(obj1.maximumHeight(), 0); // A widgets height can never be less than 0
obj1.setMaximumHeight(INT_MAX);
-#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- QCOMPARE((long)obj1.maximumHeight(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
-#else
QCOMPARE(obj1.maximumHeight(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
-#endif
// back to normal
obj1.setMinimumWidth(0);
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/kernel/qmetatype/tst_qmetatype.cpp b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 36399af..ebeea84 100644
--- a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -71,6 +71,11 @@ private slots:
void isRegisteredBuiltin();
void isRegisteredCustom();
void isRegisteredNotRegistered();
+
+ void constructCoreType_data();
+ void constructCoreType();
+ void constructCoreTypeCopy_data();
+ void constructCoreTypeCopy();
};
tst_QMetaType::tst_QMetaType()
@@ -229,5 +234,52 @@ void tst_QMetaType::isRegisteredNotRegistered()
}
}
+void tst_QMetaType::constructCoreType_data()
+{
+ QTest::addColumn<int>("typeId");
+ for (int i = 0; i <= QMetaType::LastCoreType; ++i)
+ QTest::newRow(QMetaType::typeName(i)) << i;
+ for (int i = QMetaType::FirstCoreExtType; i <= QMetaType::LastCoreExtType; ++i)
+ QTest::newRow(QMetaType::typeName(i)) << i;
+ // GUI types are tested in tst_QGuiMetaType.
+}
+
+// Tests how fast QMetaType can default-construct and destroy a Qt
+// core type. The purpose of this benchmark is to measure the overhead
+// of using type id-based creation compared to creating the type
+// directly (i.e. "T *t = new T(); delete t;").
+void tst_QMetaType::constructCoreType()
+{
+ QFETCH(int, typeId);
+ QBENCHMARK {
+ for (int i = 0; i < 100000; ++i) {
+ void *data = QMetaType::construct(typeId, (void *)0);
+ QMetaType::destroy(typeId, data);
+ }
+ }
+}
+
+void tst_QMetaType::constructCoreTypeCopy_data()
+{
+ constructCoreType_data();
+}
+
+// Tests how fast QMetaType can copy-construct and destroy a Qt core
+// type. The purpose of this benchmark is to measure the overhead of
+// using type id-based creation compared to creating the type directly
+// (i.e. "T *t = new T(other); delete t;").
+void tst_QMetaType::constructCoreTypeCopy()
+{
+ QFETCH(int, typeId);
+ QVariant other(typeId, (void *)0);
+ const void *copy = other.constData();
+ QBENCHMARK {
+ for (int i = 0; i < 100000; ++i) {
+ void *data = QMetaType::construct(typeId, copy);
+ QMetaType::destroy(typeId, data);
+ }
+ }
+}
+
QTEST_MAIN(tst_QMetaType)
#include "tst_qmetatype.moc"
diff --git a/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp
index 58cec4f..5e19c1b 100644
--- a/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -71,6 +71,11 @@ private slots:
void floatVariantValue();
void rectVariantValue();
void stringVariantValue();
+
+ void createCoreType_data();
+ void createCoreType();
+ void createCoreTypeCopy_data();
+ void createCoreTypeCopy();
};
void tst_qvariant::testBound()
@@ -220,6 +225,48 @@ void tst_qvariant::stringVariantValue()
}
}
+void tst_qvariant::createCoreType_data()
+{
+ QTest::addColumn<int>("typeId");
+ for (int i = 0; i <= QMetaType::LastCoreType; ++i)
+ QTest::newRow(QMetaType::typeName(i)) << i;
+ for (int i = QMetaType::FirstCoreExtType; i <= QMetaType::LastCoreExtType; ++i)
+ QTest::newRow(QMetaType::typeName(i)) << i;
+}
+
+// Tests how fast a Qt core type can be default-constructed by a
+// QVariant. The purpose of this benchmark is to measure the overhead
+// of creating (and destroying) a QVariant compared to creating the
+// type directly.
+void tst_qvariant::createCoreType()
+{
+ QFETCH(int, typeId);
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ QVariant(typeId, (void *)0);
+ }
+}
+
+void tst_qvariant::createCoreTypeCopy_data()
+{
+ createCoreType_data();
+}
+
+// Tests how fast a Qt core type can be copy-constructed by a
+// QVariant. The purpose of this benchmark is to measure the overhead
+// of creating (and destroying) a QVariant compared to creating the
+// type directly.
+void tst_qvariant::createCoreTypeCopy()
+{
+ QFETCH(int, typeId);
+ QVariant other(typeId, (void *)0);
+ const void *copy = other.constData();
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ QVariant(typeId, copy);
+ }
+}
+
QTEST_MAIN(tst_qvariant)
#include "tst_qvariant.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/benchmarks/gui/kernel/qguimetatype/qguimetatype.pro b/tests/benchmarks/gui/kernel/qguimetatype/qguimetatype.pro
new file mode 100644
index 0000000..7ef99e4
--- /dev/null
+++ b/tests/benchmarks/gui/kernel/qguimetatype/qguimetatype.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_bench_qguimetatype
+
+SOURCES += tst_qguimetatype.cpp
+
diff --git a/tests/benchmarks/gui/kernel/qguimetatype/tst_qguimetatype.cpp b/tests/benchmarks/gui/kernel/qguimetatype/tst_qguimetatype.cpp
new file mode 100644
index 0000000..f94767b
--- /dev/null
+++ b/tests/benchmarks/gui/kernel/qguimetatype/tst_qguimetatype.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** 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/qmetatype.h>
+
+class tst_QGuiMetaType : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QGuiMetaType();
+ virtual ~tst_QGuiMetaType();
+
+private slots:
+ void constructGuiType_data();
+ void constructGuiType();
+ void constructGuiTypeCopy_data();
+ void constructGuiTypeCopy();
+};
+
+tst_QGuiMetaType::tst_QGuiMetaType()
+{
+}
+
+tst_QGuiMetaType::~tst_QGuiMetaType()
+{
+}
+
+void tst_QGuiMetaType::constructGuiType_data()
+{
+ QTest::addColumn<int>("typeId");
+ for (int i = QMetaType::FirstGuiType; i <= QMetaType::LastGuiType; ++i)
+ QTest::newRow(QMetaType::typeName(i)) << i;
+}
+
+// Tests how fast QMetaType can default-construct and destroy a Qt GUI
+// type. The purpose of this benchmark is to measure the overhead of
+// using type id-based creation compared to creating the type directly
+// (i.e. "T *t = new T(); delete t;").
+void tst_QGuiMetaType::constructGuiType()
+{
+ QFETCH(int, typeId);
+ QBENCHMARK {
+ for (int i = 0; i < 100000; ++i) {
+ void *data = QMetaType::construct(typeId, (void *)0);
+ QMetaType::destroy(typeId, data);
+ }
+ }
+}
+
+void tst_QGuiMetaType::constructGuiTypeCopy_data()
+{
+ constructGuiType_data();
+}
+
+// Tests how fast QMetaType can copy-construct and destroy a Qt GUI
+// type. The purpose of this benchmark is to measure the overhead of
+// using type id-based creation compared to creating the type directly
+// (i.e. "T *t = new T(other); delete t;").
+void tst_QGuiMetaType::constructGuiTypeCopy()
+{
+ QFETCH(int, typeId);
+ QVariant other(typeId, (void *)0);
+ const void *copy = other.constData();
+ QBENCHMARK {
+ for (int i = 0; i < 100000; ++i) {
+ void *data = QMetaType::construct(typeId, copy);
+ QMetaType::destroy(typeId, data);
+ }
+ }
+}
+
+QTEST_MAIN(tst_QGuiMetaType)
+#include "tst_qguimetatype.moc"
diff --git a/tests/benchmarks/gui/kernel/qguivariant/qguivariant.pro b/tests/benchmarks/gui/kernel/qguivariant/qguivariant.pro
new file mode 100644
index 0000000..4e05dd7
--- /dev/null
+++ b/tests/benchmarks/gui/kernel/qguivariant/qguivariant.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_bench_qguivariant
+
+SOURCES += tst_qguivariant.cpp
+
diff --git a/tests/benchmarks/gui/kernel/qguivariant/tst_qguivariant.cpp b/tests/benchmarks/gui/kernel/qguivariant/tst_qguivariant.cpp
new file mode 100644
index 0000000..4016be1
--- /dev/null
+++ b/tests/benchmarks/gui/kernel/qguivariant/tst_qguivariant.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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/qvariant.h>
+
+#define ITERATION_COUNT 1e5
+
+class tst_QGuiVariant : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QGuiVariant();
+ virtual ~tst_QGuiVariant();
+
+private slots:
+ void createGuiType_data();
+ void createGuiType();
+ void createGuiTypeCopy_data();
+ void createGuiTypeCopy();
+};
+
+tst_QGuiVariant::tst_QGuiVariant()
+{
+}
+
+tst_QGuiVariant::~tst_QGuiVariant()
+{
+}
+
+void tst_QGuiVariant::createGuiType_data()
+{
+ QTest::addColumn<int>("typeId");
+ for (int i = QMetaType::FirstGuiType; i <= QMetaType::LastGuiType; ++i)
+ QTest::newRow(QMetaType::typeName(i)) << i;
+}
+
+// Tests how fast a Qt GUI type can be default-constructed by a
+// QVariant. The purpose of this benchmark is to measure the overhead
+// of creating (and destroying) a QVariant compared to creating the
+// type directly.
+void tst_QGuiVariant::createGuiType()
+{
+ QFETCH(int, typeId);
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ QVariant(typeId, (void *)0);
+ }
+}
+
+void tst_QGuiVariant::createGuiTypeCopy_data()
+{
+ createGuiType_data();
+}
+
+// Tests how fast a Qt GUI type can be copy-constructed by a
+// QVariant. The purpose of this benchmark is to measure the overhead
+// of creating (and destroying) a QVariant compared to creating the
+// type directly.
+void tst_QGuiVariant::createGuiTypeCopy()
+{
+ QFETCH(int, typeId);
+ QVariant other(typeId, (void *)0);
+ const void *copy = other.constData();
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ QVariant(typeId, copy);
+ }
+}
+
+QTEST_MAIN(tst_QGuiVariant)
+#include "tst_qguivariant.moc"
diff --git a/tests/benchmarks/script/qscriptqobject/qscriptqobject.pro b/tests/benchmarks/script/qscriptqobject/qscriptqobject.pro
new file mode 100644
index 0000000..30bc447
--- /dev/null
+++ b/tests/benchmarks/script/qscriptqobject/qscriptqobject.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_bench_qscriptqobject
+
+SOURCES += tst_qscriptqobject.cpp
+
+QT += script
diff --git a/tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp b/tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp
new file mode 100644
index 0000000..e68db06
--- /dev/null
+++ b/tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp
@@ -0,0 +1,1237 @@
+/****************************************************************************
+**
+** 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 <QtGui>
+#include <QtScript>
+
+#define ITERATION_COUNT 1e4
+
+struct CustomType
+{
+ int a;
+};
+Q_DECLARE_METATYPE(CustomType)
+
+class PropertyTestObject : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(EnumType)
+ Q_FLAGS(FlagsType)
+ Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty)
+ Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty)
+ Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty)
+ Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty)
+ Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty)
+ Q_PROPERTY(QObject* qobjectProperty READ qobjectProperty WRITE setQObjectProperty)
+ Q_PROPERTY(CustomType customProperty READ customProperty WRITE setCustomProperty)
+ Q_PROPERTY(EnumType enumProperty READ enumProperty WRITE setEnumProperty)
+ Q_PROPERTY(FlagsType flagsProperty READ flagsProperty WRITE setFlagsProperty)
+public:
+ enum EnumType {
+ NoEnumValue = 0,
+ FirstEnumValue = 1,
+ SecondEnumValue = 2,
+ ThirdEnumValue = 4
+ };
+ Q_DECLARE_FLAGS(FlagsType, EnumType)
+
+ PropertyTestObject(QObject *parent = 0)
+ : QObject(parent),
+ m_boolProperty(false),
+ m_intProperty(123),
+ m_doubleProperty(123),
+ m_stringProperty("hello"),
+ m_variantProperty(double(123)),
+ m_qobjectProperty(this),
+ m_enumProperty(SecondEnumValue),
+ m_flagsProperty(FirstEnumValue | ThirdEnumValue)
+ { }
+
+ bool boolProperty() const
+ { return m_boolProperty; }
+ void setBoolProperty(bool value)
+ { m_boolProperty = value; }
+
+ int intProperty() const
+ { return m_intProperty; }
+ void setIntProperty(int value)
+ { m_intProperty = value; }
+
+ int doubleProperty() const
+ { return m_doubleProperty; }
+ void setDoubleProperty(double value)
+ { m_doubleProperty = value; }
+
+ QString stringProperty() const
+ { return m_stringProperty; }
+ void setStringProperty(const QString &value)
+ { m_stringProperty = value; }
+
+ QVariant variantProperty() const
+ { return m_variantProperty; }
+ void setVariantProperty(const QVariant &value)
+ { m_variantProperty = value; }
+
+ QObject *qobjectProperty() const
+ { return m_qobjectProperty; }
+ void setQObjectProperty(QObject *qobject)
+ { m_qobjectProperty = qobject; }
+
+ CustomType customProperty() const
+ { return m_customProperty; }
+ void setCustomProperty(const CustomType &value)
+ { m_customProperty = value; }
+
+ EnumType enumProperty() const
+ { return m_enumProperty; }
+ void setEnumProperty(EnumType value)
+ { m_enumProperty = value; }
+
+ FlagsType flagsProperty() const
+ { return m_flagsProperty; }
+ void setFlagsProperty(FlagsType value)
+ { m_flagsProperty = value; }
+
+private:
+ bool m_boolProperty;
+ int m_intProperty;
+ double m_doubleProperty;
+ QString m_stringProperty;
+ QVariant m_variantProperty;
+ QObject *m_qobjectProperty;
+ CustomType m_customProperty;
+ EnumType m_enumProperty;
+ FlagsType m_flagsProperty;
+};
+
+class SlotTestObject : public QObject
+{
+ Q_OBJECT
+public:
+ SlotTestObject(QObject *parent = 0)
+ : QObject(parent),
+ m_string(QString::fromLatin1("hello")),
+ m_variant(123)
+ { }
+
+public Q_SLOTS:
+ void voidSlot() { }
+ void boolSlot(bool) { }
+ void intSlot(int) { }
+ void doubleSlot(double) { }
+ void stringSlot(const QString &) { }
+ void variantSlot(const QVariant &) { }
+ void qobjectSlot(QObject *) { }
+ void customTypeSlot(const CustomType &) { }
+
+ bool returnBoolSlot() { return true; }
+ int returnIntSlot() { return 123; }
+ double returnDoubleSlot() { return 123.0; }
+ QString returnStringSlot() { return m_string; }
+ QVariant returnVariantSlot() { return m_variant; }
+ QObject *returnQObjectSlot() { return this; }
+ CustomType returnCustomTypeSlot() { return m_custom; }
+
+ void fourDoubleSlot(double, double, double, double) { }
+ void sixDoubleSlot(double, double, double, double, double, double) { }
+ void eightDoubleSlot(double, double, double, double, double, double, double, double) { }
+
+ void fourStringSlot(const QString &, const QString &, const QString &, const QString &) { }
+ void sixStringSlot(const QString &, const QString &, const QString &, const QString &,
+ const QString &, const QString &) { }
+ void eightStringSlot(const QString &, const QString &, const QString &, const QString &,
+ const QString &, const QString &, const QString &, const QString &) { }
+
+private:
+ QString m_string;
+ QVariant m_variant;
+ CustomType m_custom;
+};
+
+class SignalTestObject : public QObject
+{
+ Q_OBJECT
+public:
+ SignalTestObject(QObject *parent = 0)
+ : QObject(parent)
+ { }
+
+ void emitVoidSignal()
+ { emit voidSignal(); }
+ void emitBoolSignal(bool value)
+ { emit boolSignal(value); }
+ void emitIntSignal(int value)
+ { emit intSignal(value); }
+ void emitDoubleSignal(double value)
+ { emit doubleSignal(value); }
+ void emitStringSignal(const QString &value)
+ { emit stringSignal(value); }
+ void emitVariantSignal(const QVariant &value)
+ { emit variantSignal(value); }
+ void emitQObjectSignal(QObject *object)
+ { emit qobjectSignal(object); }
+ void emitCustomTypeSignal(const CustomType &value)
+ { emit customTypeSignal(value); }
+
+Q_SIGNALS:
+ void voidSignal();
+ void boolSignal(bool);
+ void intSignal(int);
+ void doubleSignal(double);
+ void stringSignal(const QString &);
+ void variantSignal(const QVariant &);
+ void qobjectSignal(QObject *);
+ void customTypeSignal(const CustomType &);
+};
+
+class OverloadedSlotTestObject : public QObject
+{
+ Q_OBJECT
+public:
+ OverloadedSlotTestObject(QObject *parent = 0)
+ : QObject(parent)
+ { }
+
+public Q_SLOTS:
+ void overloadedSlot() { }
+ void overloadedSlot(bool) { }
+ void overloadedSlot(double) { }
+ void overloadedSlot(const QString &) { }
+};
+
+class QtScriptablePropertyTestObject
+ : public PropertyTestObject, public QScriptable
+{
+};
+
+class QtScriptableSlotTestObject
+ : public SlotTestObject, public QScriptable
+{
+};
+
+class tst_QScriptQObject : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QScriptQObject();
+ virtual ~tst_QScriptQObject();
+
+private slots:
+ void initTestCase();
+
+ void readMetaProperty_data();
+ void readMetaProperty();
+
+ void writeMetaProperty_data();
+ void writeMetaProperty();
+
+ void readDynamicProperty_data();
+ void readDynamicProperty();
+
+ void writeDynamicProperty_data();
+ void writeDynamicProperty();
+
+ void readMethodByName_data();
+ void readMethodByName();
+
+ void readMethodBySignature_data();
+ void readMethodBySignature();
+
+ void readChild_data();
+ void readChild();
+
+ void readOneOfManyChildren_data();
+ void readOneOfManyChildren();
+
+ void readPrototypeProperty_data();
+ void readPrototypeProperty();
+
+ void readScriptProperty_data();
+ void readScriptProperty();
+
+ void readNoSuchProperty_data();
+ void readNoSuchProperty();
+
+ void readAllMetaProperties();
+
+ void callSlot_data();
+ void callSlot();
+
+ void callOverloadedSlot_data();
+ void callOverloadedSlot();
+
+ void voidSignalHandler();
+ void boolSignalHandler();
+ void intSignalHandler();
+ void doubleSignalHandler();
+ void stringSignalHandler();
+ void variantSignalHandler();
+ void qobjectSignalHandler();
+ void customTypeSignalHandler();
+
+ void readButtonMetaProperty_data();
+ void readButtonMetaProperty();
+
+ void writeButtonMetaProperty_data();
+ void writeButtonMetaProperty();
+
+ void readDynamicButtonProperty_data();
+ void readDynamicButtonProperty();
+
+ void writeDynamicButtonProperty_data();
+ void writeDynamicButtonProperty();
+
+ void readButtonMethodByName_data();
+ void readButtonMethodByName();
+
+ void readButtonMethodBySignature_data();
+ void readButtonMethodBySignature();
+
+ void readButtonChild_data();
+ void readButtonChild();
+
+ void readButtonPrototypeProperty_data();
+ void readButtonPrototypeProperty();
+
+ void readButtonScriptProperty_data();
+ void readButtonScriptProperty();
+
+ void readNoSuchButtonProperty_data();
+ void readNoSuchButtonProperty();
+
+ void callButtonMethod_data();
+ void callButtonMethod();
+
+ void readAllButtonMetaProperties();
+
+ void readQScriptableMetaProperty_data();
+ void readQScriptableMetaProperty();
+
+ void writeQScriptableMetaProperty_data();
+ void writeQScriptableMetaProperty();
+
+ void callQScriptableSlot_data();
+ void callQScriptableSlot();
+
+private:
+ void readMetaProperty_dataHelper(const QMetaObject *mo);
+ void readMethodByName_dataHelper(const QMetaObject *mo);
+ void readMethodBySignature_dataHelper(const QMetaObject *mo);
+ void readAllMetaPropertiesHelper(QObject *o);
+
+ void readPropertyHelper(QScriptEngine &engine, const QScriptValue &object,
+ const QString &propertyName, const QString &argTemplate = ".%0");
+ void writePropertyHelper(QScriptEngine &engine, const QScriptValue &object,
+ const QString &propertyName, const QScriptValue &value,
+ const QString &argTemplate = ".%0");
+
+ void callMethodHelper(QScriptEngine &engine, QObject *object,
+ const QString &propertyName, const QString &arguments);
+ void signalHandlerHelper(QScriptEngine &engine, QObject *object, const char *signal);
+};
+
+tst_QScriptQObject::tst_QScriptQObject()
+{
+}
+
+tst_QScriptQObject::~tst_QScriptQObject()
+{
+}
+
+void tst_QScriptQObject::initTestCase()
+{
+ qMetaTypeId<CustomType>();
+}
+
+void tst_QScriptQObject::readMetaProperty_dataHelper(const QMetaObject *mo)
+{
+ QTest::addColumn<QString>("propertyName");
+
+ for (int i = 0; i < mo->propertyCount(); ++i) {
+ QMetaProperty prop = mo->property(i);
+ if (!qstrcmp(prop.name(), "default"))
+ continue; // skip reserved word
+ QTest::newRow(prop.name()) << prop.name();
+ }
+}
+
+void tst_QScriptQObject::readMethodByName_dataHelper(const QMetaObject *mo)
+{
+ QTest::addColumn<QString>("propertyName");
+
+ QSet<QByteArray> uniqueNames;
+ for (int i = 0; i < mo->methodCount(); ++i) {
+ QMetaMethod method = mo->method(i);
+ if (method.access() == QMetaMethod::Private)
+ continue;
+ QByteArray signature = method.signature();
+ QByteArray name = signature.left(signature.indexOf('('));
+ if (uniqueNames.contains(name))
+ continue;
+ QTest::newRow(name) << QString::fromLatin1(name);
+ uniqueNames.insert(name);
+ }
+}
+
+void tst_QScriptQObject::readMethodBySignature_dataHelper(const QMetaObject *mo)
+{
+ QTest::addColumn<QString>("propertyName");
+
+ for (int i = 0; i < mo->methodCount(); ++i) {
+ QMetaMethod method = mo->method(i);
+ if (method.access() == QMetaMethod::Private)
+ continue;
+ QTest::newRow(method.signature()) << QString::fromLatin1(method.signature());
+ }
+}
+
+void tst_QScriptQObject::readAllMetaPropertiesHelper(QObject *o)
+{
+ QString code = QString::fromLatin1(
+ "(function() {\n"
+ " for (var i = 0; i < 100; ++i) {\n");
+ const QMetaObject *mo = o->metaObject();
+ for (int i = 0; i < mo->propertyCount(); ++i) {
+ QMetaProperty prop = mo->property(i);
+ if (!qstrcmp(prop.name(), "default"))
+ continue; // skip reserved word
+ code.append(QString::fromLatin1(" this.%0;\n").arg(prop.name()));
+ }
+ code.append(
+ " }\n"
+ "})");
+
+ QScriptEngine engine;
+ QScriptValue fun = engine.evaluate(code);
+ QVERIFY(fun.isFunction());
+
+ QScriptValue wrapper = engine.newQObject(o);
+ QBENCHMARK {
+ fun.call(wrapper);
+ }
+ QVERIFY(!engine.hasUncaughtException());
+}
+
+void tst_QScriptQObject::readPropertyHelper(
+ QScriptEngine &engine, const QScriptValue &object,
+ const QString &propertyName, const QString &argTemplate)
+{
+ QString code = QString::fromLatin1(
+ "(function() {\n"
+ " for (var i = 0; i < %0; ++i)\n"
+ " this%1;\n"
+ "})").arg(ITERATION_COUNT).arg(argTemplate.arg(propertyName));
+ QScriptValue fun = engine.evaluate(code);
+ QVERIFY(fun.isFunction());
+
+ QBENCHMARK {
+ fun.call(object);
+ }
+ QVERIFY(!engine.hasUncaughtException());
+}
+
+void tst_QScriptQObject::writePropertyHelper(
+ QScriptEngine &engine, const QScriptValue &object,
+ const QString &propertyName, const QScriptValue &value,
+ const QString &argTemplate)
+{
+ QVERIFY(value.isValid());
+ QString code = QString::fromLatin1(
+ "(function(v) {\n"
+ " for (var i = 0; i < %0; ++i)\n"
+ " this%1 = v;\n"
+ "})").arg(ITERATION_COUNT).arg(argTemplate.arg(propertyName));
+ QScriptValue fun = engine.evaluate(code);
+ QVERIFY(fun.isFunction());
+
+ QScriptValueList args;
+ args << value;
+ QBENCHMARK {
+ fun.call(object, args);
+ }
+ QVERIFY(!engine.hasUncaughtException());
+}
+
+void tst_QScriptQObject::callMethodHelper(
+ QScriptEngine &engine, QObject *object,
+ const QString &propertyName, const QString &arguments)
+{
+ QScriptValue wrapper = engine.newQObject(object);
+ QScriptValue method = wrapper.property(propertyName);
+ QVERIFY(method.isFunction());
+
+ // Generate code that calls the function directly; in this way
+ // only function call performance is measured, not function lookup
+ // as well.
+ QString code = QString::fromLatin1(
+ "(function(f) {\n"
+ " for (var i = 0; i < %0; ++i)\n"
+ " f(%1);\n"
+ "})").arg(ITERATION_COUNT).arg(arguments);
+ QScriptValue fun = engine.evaluate(code);
+ QVERIFY(fun.isFunction());
+
+ QScriptValueList args;
+ args << method;
+ QBENCHMARK {
+ fun.call(wrapper, args);
+ }
+ QVERIFY(!engine.hasUncaughtException());
+}
+
+void tst_QScriptQObject::signalHandlerHelper(
+ QScriptEngine &engine, QObject *object, const char *signal)
+{
+ QScriptValue handler = engine.evaluate("(function(a) { return a; })");
+ QVERIFY(handler.isFunction());
+ QVERIFY(qScriptConnect(object, signal, QScriptValue(), handler));
+}
+
+void tst_QScriptQObject::readMetaProperty_data()
+{
+ readMetaProperty_dataHelper(&PropertyTestObject::staticMetaObject);
+}
+
+// Reads a meta-object-defined property from JS. The purpose of this
+// benchmark is to measure the overhead of reading a property from JS
+// compared to calling the property getter directly from C++ without
+// introspection or value conversion (that's the fastest we could
+// possibly hope to get).
+void tst_QScriptQObject::readMetaProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ PropertyTestObject testObject;
+ readPropertyHelper(engine, engine.newQObject(&testObject), propertyName);
+}
+
+void tst_QScriptQObject::writeMetaProperty_data()
+{
+ readMetaProperty_data();
+}
+
+// Writes a meta-object-defined property from JS. The purpose of this
+// benchmark is to measure the overhead of writing a property from JS
+// compared to calling the property setter directly from C++ without
+// introspection or value conversion (that's the fastest we could
+// possibly hope to get).
+void tst_QScriptQObject::writeMetaProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ PropertyTestObject testObject;
+ QScriptValue wrapper = engine.newQObject(&testObject);
+ QScriptValue value = wrapper.property(propertyName);
+ writePropertyHelper(engine, wrapper, propertyName, value);
+}
+
+void tst_QScriptQObject::readDynamicProperty_data()
+{
+ QTest::addColumn<QVariant>("value");
+
+ QTest::newRow("bool") << QVariant(false);
+ QTest::newRow("int") << QVariant(123);
+ QTest::newRow("double") << QVariant(double(123.0));
+ QTest::newRow("string") << QVariant(QString::fromLatin1("hello"));
+ QTest::newRow("QObject*") << qVariantFromValue((QObject*)this);
+ QTest::newRow("CustomType") << qVariantFromValue(CustomType());
+}
+
+// Reads a dynamic property from JS. The purpose of this benchmark is
+// to measure the overhead of reading a dynamic property from JS
+// versus calling QObject::property(aDynamicProperty) directly from
+// C++.
+void tst_QScriptQObject::readDynamicProperty()
+{
+ QFETCH(QVariant, value);
+
+ QObject testObject;
+ const char *propertyName = "dynamicProperty";
+ testObject.setProperty(propertyName, value);
+ QVERIFY(testObject.dynamicPropertyNames().contains(propertyName));
+
+ QScriptEngine engine;
+ readPropertyHelper(engine, engine.newQObject(&testObject), propertyName);
+}
+
+void tst_QScriptQObject::writeDynamicProperty_data()
+{
+ readDynamicProperty_data();
+}
+
+// Writes an existing dynamic property from JS. The purpose of this
+// benchmark is to measure the overhead of writing a dynamic property
+// from JS versus calling QObject::setProperty(aDynamicProperty,
+// aVariant) directly from C++.
+void tst_QScriptQObject::writeDynamicProperty()
+{
+ QFETCH(QVariant, value);
+
+ QObject testObject;
+ const char *propertyName = "dynamicProperty";
+ testObject.setProperty(propertyName, value);
+ QVERIFY(testObject.dynamicPropertyNames().contains(propertyName));
+
+ QScriptEngine engine;
+ writePropertyHelper(engine, engine.newQObject(&testObject), propertyName,
+ qScriptValueFromValue(&engine, value));
+}
+
+void tst_QScriptQObject::readMethodByName_data()
+{
+ readMethodByName_dataHelper(&SlotTestObject::staticMetaObject);
+}
+
+// Reads a meta-object-defined method from JS by name. The purpose of
+// this benchmark is to measure the overhead of resolving a method
+// from JS (effectively, creating and returning a JS wrapper function
+// object for a C++ method).
+void tst_QScriptQObject::readMethodByName()
+{
+ readMetaProperty();
+}
+
+void tst_QScriptQObject::readMethodBySignature_data()
+{
+ readMethodBySignature_dataHelper(&SlotTestObject::staticMetaObject);
+}
+
+// Reads a meta-object-defined method from JS by signature. The
+// purpose of this benchmark is to measure the overhead of resolving a
+// method from JS (effectively, creating and returning a JS wrapper
+// function object for a C++ method).
+void tst_QScriptQObject::readMethodBySignature()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ SlotTestObject testObject;
+ readPropertyHelper(engine, engine.newQObject(&testObject), propertyName, "['%0']");
+}
+
+void tst_QScriptQObject::readChild_data()
+{
+ QTest::addColumn<QString>("propertyName");
+
+ QTest::newRow("child") << "child";
+}
+
+// Reads a child object from JS. The purpose of this benchmark is to
+// measure the overhead of reading a child object from JS compared to
+// calling e.g. qFindChild() directly from C++, when the test object
+// is a plain QObject with only one child.
+void tst_QScriptQObject::readChild()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QObject testObject;
+ QObject *child = new QObject(&testObject);
+ child->setObjectName(propertyName);
+ readPropertyHelper(engine, engine.newQObject(&testObject), propertyName);
+}
+
+void tst_QScriptQObject::readOneOfManyChildren_data()
+{
+ QTest::addColumn<QString>("propertyName");
+
+ QTest::newRow("child0") << "child0";
+ QTest::newRow("child50") << "child50";
+ QTest::newRow("child99") << "child99";
+}
+
+// Reads a child object from JS for an object that has many
+// children. The purpose of this benchmark is to measure the overhead
+// of reading a child object from JS compared to calling
+// e.g. qFindChild() directly from C++.
+void tst_QScriptQObject::readOneOfManyChildren()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QObject testObject;
+ for (int i = 0; i < 100; ++i) {
+ QObject *child = new QObject(&testObject);
+ child->setObjectName(QString::fromLatin1("child%0").arg(i));
+ }
+ readPropertyHelper(engine, engine.newQObject(&testObject), propertyName);
+}
+
+void tst_QScriptQObject::readPrototypeProperty_data()
+{
+ QTest::addColumn<QString>("propertyName");
+
+ // Inherited from Object.prototype.
+ QTest::newRow("hasOwnProperty") << "hasOwnProperty";
+ QTest::newRow("isPrototypeOf") << "isPrototypeOf";
+ QTest::newRow("propertyIsEnumerable") << "propertyIsEnumerable";
+ QTest::newRow("valueOf") << "valueOf";
+}
+
+// Reads a property that's inherited from a prototype object. The
+// purpose of this benchmark is to measure the overhead of resolving a
+// prototype property (i.e., how long it takes the binding to
+// determine that the QObject doesn't have the property itself).
+void tst_QScriptQObject::readPrototypeProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ PropertyTestObject testObject;
+ readPropertyHelper(engine, engine.newQObject(&testObject), propertyName);
+}
+
+void tst_QScriptQObject::readScriptProperty_data()
+{
+ QTest::addColumn<QString>("propertyName");
+
+ QTest::newRow("scriptProperty") << "scriptProperty";
+}
+
+// Reads a JS (non-Qt) property of a wrapper object. The purpose of
+// this benchmark is to measure the overhead of reading a property
+// that only exists on the wrapper object, not on the underlying
+// QObject.
+void tst_QScriptQObject::readScriptProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ PropertyTestObject testObject;
+ QScriptValue wrapper = engine.newQObject(&testObject);
+ wrapper.setProperty(propertyName, 123);
+ QVERIFY(wrapper.property(propertyName).isValid());
+ QVERIFY(!testObject.property(propertyName.toLatin1()).isValid());
+
+ readPropertyHelper(engine, wrapper, propertyName);
+}
+
+void tst_QScriptQObject::readNoSuchProperty_data()
+{
+ QTest::addColumn<QString>("propertyName");
+
+ QTest::newRow("noSuchProperty") << "noSuchProperty";
+}
+
+// Reads a non-existing (undefined) property of a wrapper object. The
+// purpose of this benchmark is to measure the overhead of reading a
+// property that doesn't exist (i.e., how long it takes the binding to
+// determine this).
+void tst_QScriptQObject::readNoSuchProperty()
+{
+ readMetaProperty();
+}
+
+// Reads all meta-object-defined properties from JS. The purpose of
+// this benchmark is to measure the overhead of reading different
+// properties in sequence, not just the same one repeatedly (like
+// readMetaProperty() does).
+void tst_QScriptQObject::readAllMetaProperties()
+{
+ PropertyTestObject testObject;
+ readAllMetaPropertiesHelper(&testObject);
+}
+
+void tst_QScriptQObject::callSlot_data()
+{
+ QTest::addColumn<QString>("propertyName");
+ QTest::addColumn<QString>("arguments");
+
+ QTest::newRow("voidSlot()") << "voidSlot" << "";
+
+ QTest::newRow("boolSlot(true)") << "boolSlot" << "true";
+ QTest::newRow("intSlot(123)") << "intSlot" << "123";
+ QTest::newRow("doubleSlot(123)") << "doubleSlot" << "123";
+ QTest::newRow("stringSlot('hello')") << "stringSlot" << "'hello'";
+ QTest::newRow("variantSlot(123)") << "variantSlot" << "123";
+ QTest::newRow("qobjectSlot(this)") << "qobjectSlot" << "this"; // assumes 'this' is a QObject
+
+ QTest::newRow("returnBoolSlot()") << "returnBoolSlot" << "";
+ QTest::newRow("returnIntSlot()") << "returnIntSlot" << "";
+ QTest::newRow("returnDoubleSlot()") << "returnDoubleSlot" << "";
+ QTest::newRow("returnStringSlot()") << "returnStringSlot" << "";
+ QTest::newRow("returnVariantSlot()") << "returnVariantSlot" << "";
+ QTest::newRow("returnQObjectSlot()") << "returnQObjectSlot" << "";
+ QTest::newRow("returnCustomTypeSlot()") << "returnCustomTypeSlot" << "";
+
+ // Implicit conversion.
+ QTest::newRow("boolSlot(0)") << "boolSlot" << "0";
+ QTest::newRow("intSlot('123')") << "intSlot" << "'123'";
+ QTest::newRow("doubleSlot('123')") << "doubleSlot" << "'123'";
+ QTest::newRow("stringSlot(123)") << "stringSlot" << "123";
+
+ // Many arguments.
+ QTest::newRow("fourDoubleSlot(1,2,3,4)") << "fourDoubleSlot" << "1,2,3,4";
+ QTest::newRow("sixDoubleSlot(1,2,3,4,5,6)") << "sixDoubleSlot" << "1,2,3,4,5,6";
+ QTest::newRow("eightDoubleSlot(1,2,3,4,5,6,7,8)") << "eightDoubleSlot" << "1,2,3,4,5,6,7,8";
+
+ QTest::newRow("fourStringSlot('a','b','c','d')") << "fourStringSlot" << "'a','b','c','d'";
+ QTest::newRow("sixStringSlot('a','b','c','d','e','f')") << "sixStringSlot" << "'a','b','c','d','e','f'";
+ QTest::newRow("eightStringSlot('a','b','c','d','e','f','g','h')") << "eightStringSlot" << "'a','b','c','d','e','f','g','h'";
+}
+
+// Calls a slot from JS. The purpose of this benchmark is to measure
+// the overhead of calling a slot from JS compared to calling the slot
+// directly from C++ without introspection or value conversion (that's
+// the fastest we could possibly hope to get). The slots themselves
+// don't do any work.
+void tst_QScriptQObject::callSlot()
+{
+ QFETCH(QString, propertyName);
+ QFETCH(QString, arguments);
+
+ QScriptEngine engine;
+ SlotTestObject testObject;
+ callMethodHelper(engine, &testObject, propertyName, arguments);
+}
+
+void tst_QScriptQObject::callOverloadedSlot_data()
+{
+ QTest::addColumn<QString>("propertyName");
+ QTest::addColumn<QString>("arguments");
+
+ QTest::newRow("overloadedSlot()") << "overloadedSlot" << "";
+ QTest::newRow("overloadedSlot(true)") << "overloadedSlot" << "true";
+ QTest::newRow("overloadedSlot(123)") << "overloadedSlot" << "123";
+ QTest::newRow("overloadedSlot('hello')") << "overloadedSlot" << "'hello'";
+}
+
+// Calls an overloaded slot from JS. The purpose of this benchmark is
+// to measure the overhead of calling an overloaded slot from JS
+// compared to calling the overloaded slot directly from C++ without
+// introspection or value conversion (that's the fastest we could
+// possibly hope to get).
+void tst_QScriptQObject::callOverloadedSlot()
+{
+ QFETCH(QString, propertyName);
+ QFETCH(QString, arguments);
+
+ QScriptEngine engine;
+ OverloadedSlotTestObject testObject;
+ callMethodHelper(engine, &testObject, propertyName, arguments);
+}
+
+// Benchmarks for JS signal handling. The purpose of these benchmarks
+// is to measure the overhead of dispatching a Qt signal to JS code
+// compared to a normal C++ signal-to-slot dispatch.
+
+void tst_QScriptQObject::voidSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(voidSignal()));
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitVoidSignal();
+ }
+}
+
+void tst_QScriptQObject::boolSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(boolSignal(bool)));
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitBoolSignal(true);
+ }
+}
+
+void tst_QScriptQObject::intSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(intSignal(int)));
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitIntSignal(123);
+ }
+}
+
+void tst_QScriptQObject::doubleSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(doubleSignal(double)));
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitDoubleSignal(123.0);
+ }
+}
+
+void tst_QScriptQObject::stringSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(stringSignal(QString)));
+ QString value = QString::fromLatin1("hello");
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitStringSignal(value);
+ }
+}
+
+void tst_QScriptQObject::variantSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(variantSignal(QVariant)));
+ QVariant value = 123;
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitVariantSignal(value);
+ }
+}
+
+void tst_QScriptQObject::qobjectSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(qobjectSignal(QObject*)));
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitQObjectSignal(this);
+ }
+}
+
+void tst_QScriptQObject::customTypeSignalHandler()
+{
+ SignalTestObject testObject;
+ QScriptEngine engine;
+ signalHandlerHelper(engine, &testObject, SIGNAL(customTypeSignal(CustomType)));
+ CustomType value;
+ QBENCHMARK {
+ for (int i = 0; i < ITERATION_COUNT; ++i)
+ testObject.emitCustomTypeSignal(value);
+ }
+}
+
+void tst_QScriptQObject::readButtonMetaProperty_data()
+{
+ readMetaProperty_dataHelper(&QPushButton::staticMetaObject);
+}
+
+// Reads a meta-object-defined property from JS. The purpose of this
+// benchmark is to measure the overhead of reading a property from JS
+// compared to calling the property getter directly from C++ without
+// introspection or value conversion (that's the fastest we could
+// possibly hope to get).
+void tst_QScriptQObject::readButtonMetaProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QPushButton pb;
+ readPropertyHelper(engine, engine.newQObject(&pb), propertyName);
+}
+
+void tst_QScriptQObject::writeButtonMetaProperty_data()
+{
+ readButtonMetaProperty_data();
+}
+
+// Writes a meta-object-defined property from JS. The purpose of this
+// benchmark is to measure the overhead of writing a property from JS
+// compared to calling the property setter directly from C++ without
+// introspection or value conversion (that's the fastest we could
+// possibly hope to get).
+void tst_QScriptQObject::writeButtonMetaProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QPushButton pb;
+ QVariant value = pb.property(propertyName.toLatin1());
+ writePropertyHelper(engine, engine.newQObject(&pb), propertyName,
+ qScriptValueFromValue(&engine, value));
+}
+
+void tst_QScriptQObject::readDynamicButtonProperty_data()
+{
+ readDynamicProperty_data();
+}
+
+// Reads a dynamic property from JS. The purpose of this benchmark is
+// to measure the overhead of reading a dynamic property from JS
+// versus calling QObject::property(aDynamicProperty) directly from
+// C++.
+void tst_QScriptQObject::readDynamicButtonProperty()
+{
+ QFETCH(QVariant, value);
+
+ QPushButton pb;
+ const char *propertyName = "dynamicProperty";
+ pb.setProperty(propertyName, value);
+ QVERIFY(pb.dynamicPropertyNames().contains(propertyName));
+
+ QScriptEngine engine;
+ readPropertyHelper(engine, engine.newQObject(&pb), propertyName);
+}
+
+void tst_QScriptQObject::writeDynamicButtonProperty_data()
+{
+ readDynamicButtonProperty_data();
+}
+
+// Writes an existing dynamic property from JS. The purpose of this
+// benchmark is to measure the overhead of writing a dynamic property
+// from JS versus calling QObject::setProperty(aDynamicProperty,
+// aVariant) directly from C++.
+void tst_QScriptQObject::writeDynamicButtonProperty()
+{
+ QFETCH(QVariant, value);
+
+ QPushButton pb;
+ const char *propertyName = "dynamicProperty";
+ pb.setProperty(propertyName, value);
+ QVERIFY(pb.dynamicPropertyNames().contains(propertyName));
+
+ QScriptEngine engine;
+ writePropertyHelper(engine, engine.newQObject(&pb), propertyName,
+ qScriptValueFromValue(&engine, value));
+}
+
+void tst_QScriptQObject::readButtonMethodByName_data()
+{
+ readMethodByName_dataHelper(&QPushButton::staticMetaObject);
+}
+
+// Reads a meta-object-defined method from JS by name. The purpose of
+// this benchmark is to measure the overhead of resolving a method
+// from JS (effectively, creating and returning a JS wrapper function
+// object for a C++ method).
+void tst_QScriptQObject::readButtonMethodByName()
+{
+ readButtonMetaProperty();
+}
+
+void tst_QScriptQObject::readButtonMethodBySignature_data()
+{
+ readMethodBySignature_dataHelper(&QPushButton::staticMetaObject);
+}
+
+// Reads a meta-object-defined method from JS by signature. The
+// purpose of this benchmark is to measure the overhead of resolving a
+// method from JS (effectively, creating and returning a JS wrapper
+// function object for a C++ method).
+void tst_QScriptQObject::readButtonMethodBySignature()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QPushButton pb;
+ readPropertyHelper(engine, engine.newQObject(&pb), propertyName, "['%0']");
+}
+
+void tst_QScriptQObject::readButtonChild_data()
+{
+ QTest::addColumn<QString>("propertyName");
+
+ QTest::newRow("child") << "child";
+}
+
+// Reads a child object from JS. The purpose of this benchmark is to
+// measure the overhead of reading a child object from JS compared to
+// calling e.g. qFindChild() directly from C++.
+void tst_QScriptQObject::readButtonChild()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QPushButton pb;
+ QObject *child = new QObject(&pb);
+ child->setObjectName(propertyName);
+ readPropertyHelper(engine, engine.newQObject(&pb), propertyName);
+}
+
+void tst_QScriptQObject::readButtonPrototypeProperty_data()
+{
+ readPrototypeProperty_data();
+}
+
+// Reads a property that's inherited from a prototype object. The
+// purpose of this benchmark is to measure the overhead of resolving a
+// prototype property (i.e., how long does it take the binding to
+// determine that the QObject doesn't have the property itself).
+void tst_QScriptQObject::readButtonPrototypeProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QPushButton pb;
+ readPropertyHelper(engine, engine.newQObject(&pb), propertyName);
+}
+
+void tst_QScriptQObject::readButtonScriptProperty_data()
+{
+ readScriptProperty_data();
+}
+
+// Reads a JS (non-Qt) property of a wrapper object. The purpose of
+// this benchmark is to measure the overhead of reading a property
+// that only exists on the wrapper object, not on the underlying
+// QObject.
+void tst_QScriptQObject::readButtonScriptProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QPushButton pb;
+ QScriptValue wrapper = engine.newQObject(&pb);
+ wrapper.setProperty(propertyName, 123);
+ QVERIFY(wrapper.property(propertyName).isValid());
+ QVERIFY(!pb.property(propertyName.toLatin1()).isValid());
+
+ readPropertyHelper(engine, wrapper, propertyName);
+}
+
+void tst_QScriptQObject::readNoSuchButtonProperty_data()
+{
+ readNoSuchProperty_data();
+}
+
+// Reads a non-existing (undefined) property of a wrapper object. The
+// purpose of this benchmark is to measure the overhead of reading a
+// property that doesn't exist (i.e., how long does it take the
+// binding to determine that it doesn't exist).
+void tst_QScriptQObject::readNoSuchButtonProperty()
+{
+ readButtonMetaProperty();
+}
+
+void tst_QScriptQObject::callButtonMethod_data()
+{
+ QTest::addColumn<QString>("propertyName");
+ QTest::addColumn<QString>("arguments");
+
+ QTest::newRow("click()") << "click" << "";
+ QTest::newRow("animateClick(50)") << "animateClick" << "10";
+ QTest::newRow("setChecked(true)") << "setChecked" << "true";
+ QTest::newRow("close()") << "close" << "";
+ QTest::newRow("setWindowTitle('foo')") << "setWindowTitle" << "'foo'";
+}
+
+// Calls a slot from JS. The purpose of this benchmark is to measure
+// the overhead of calling a slot from JS compared to calling the slot
+// directly from C++ without introspection or value conversion (that's
+// the fastest we could possibly hope to get).
+void tst_QScriptQObject::callButtonMethod()
+{
+ QFETCH(QString, propertyName);
+ QFETCH(QString, arguments);
+
+ QScriptEngine engine;
+ QPushButton pb;
+ callMethodHelper(engine, &pb, propertyName, arguments);
+}
+
+// Reads all meta-object-defined properties from JS. The purpose of
+// this benchmark is to measure the overhead of reading different
+// properties in sequence, not just the same one repeatedly (like
+// readButtonMetaProperty() does).
+void tst_QScriptQObject::readAllButtonMetaProperties()
+{
+ QPushButton pb;
+ readAllMetaPropertiesHelper(&pb);
+}
+
+void tst_QScriptQObject::readQScriptableMetaProperty_data()
+{
+ readMetaProperty_dataHelper(&QtScriptablePropertyTestObject::staticMetaObject);
+}
+
+// Reads a meta-object-defined property from JS for an object that
+// subclasses QScriptable. The purpose of this benchmark is to measure
+// the overhead compared to reading a property of a non-QScriptable
+// (see readMetaProperty()).
+void tst_QScriptQObject::readQScriptableMetaProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QtScriptablePropertyTestObject testObject;
+ readPropertyHelper(engine, engine.newQObject(&testObject), propertyName);
+}
+
+void tst_QScriptQObject::writeQScriptableMetaProperty_data()
+{
+ readMetaProperty_data();
+}
+
+// Writes a meta-object-defined property from JS for an object that
+// subclasses QScriptable. The purpose of this benchmark is to measure
+// the overhead compared to writing a property of a non-QScriptable
+// object (see writeMetaProperty()).
+void tst_QScriptQObject::writeQScriptableMetaProperty()
+{
+ QFETCH(QString, propertyName);
+
+ QScriptEngine engine;
+ QtScriptablePropertyTestObject testObject;
+ QVariant value = testObject.property(propertyName.toLatin1());
+ writePropertyHelper(engine, engine.newQObject(&testObject), propertyName,
+ qScriptValueFromValue(&engine, value));
+}
+
+void tst_QScriptQObject::callQScriptableSlot_data()
+{
+ callSlot_data();
+}
+
+// Calls a slot from JS for an object that subclasses QScriptable. The
+// purpose of this benchmark is to measure the overhead compared to
+// calling a slot of a non-QScriptable object (see callSlot()).
+void tst_QScriptQObject::callQScriptableSlot()
+{
+ QFETCH(QString, propertyName);
+ QFETCH(QString, arguments);
+
+ QScriptEngine engine;
+ QtScriptableSlotTestObject testObject;
+ callMethodHelper(engine, &testObject, propertyName, arguments);
+}
+
+QTEST_MAIN(tst_QScriptQObject)
+#include "tst_qscriptqobject.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;