aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp74
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp6
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.h2
-rw-r--r--tests/auto/qml/qjsengine/idtranslatable-unicode.js5
-rw-r--r--tests/auto/qml/qjsengine/idtranslatable.js5
-rw-r--r--tests/auto/qml/qjsengine/qjsengine.pro1
-rw-r--r--tests/auto/qml/qjsengine/qjsengine.qrc8
-rw-r--r--tests/auto/qml/qjsengine/translatable-unicode.js9
-rw-r--r--tests/auto/qml/qjsengine/translatable.js12
-rw-r--r--tests/auto/qml/qjsengine/translatable2.js9
-rw-r--r--tests/auto/qml/qjsengine/translations/idtranslatable-unicode.qmbin0 -> 209 bytes
-rw-r--r--tests/auto/qml/qjsengine/translations/idtranslatable-unicode.ts26
-rw-r--r--tests/auto/qml/qjsengine/translations/idtranslatable_la.qmbin0 -> 342 bytes
-rw-r--r--tests/auto/qml/qjsengine/translations/idtranslatable_la.ts30
-rw-r--r--tests/auto/qml/qjsengine/translations/translatable-unicode.qmbin0 -> 322 bytes
-rw-r--r--tests/auto/qml/qjsengine/translations/translatable-unicode.ts37
-rw-r--r--tests/auto/qml/qjsengine/translations/translatable_la.qmbin0 -> 975 bytes
-rw-r--r--tests/auto/qml/qjsengine/translations/translatable_la.ts88
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp486
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp8
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.1.qml2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.3.qml2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.4.qml2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.6.qml2
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp20
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp81
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h20
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp18
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp4
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp8
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp83
-rw-r--r--tests/auto/qml/v4misc/tst_v4misc.cpp2
-rw-r--r--tests/auto/qmltest/item/tst_layerInPositioner.qml207
-rw-r--r--tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml160
-rw-r--r--tests/auto/qmltest/shadersource/tst_DynamicallyCreated.qml84
-rw-r--r--tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml81
-rw-r--r--tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml81
-rw-r--r--tests/auto/quick/nodes/tst_nodestest.cpp30
-rw-r--r--tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp16
-rw-r--r--tests/auto/quick/qquickapplication/tst_qquickapplication.cpp19
-rw-r--r--tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp35
-rw-r--r--tests/auto/quick/qquickdrag/tst_qquickdrag.cpp27
-rw-r--r--tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp114
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp20
-rw-r--r--tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp5
-rw-r--r--tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp4
-rw-r--r--tests/auto/quick/qquickimage/tst_qquickimage.cpp24
-rw-r--r--tests/auto/quick/qquickitem/qquickitem.pro1
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp4
-rw-r--r--tests/auto/quick/qquickitem2/data/grabToImage.qml60
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp110
-rw-r--r--tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp7
-rw-r--r--tests/auto/quick/qquicklistview/data/sizeTransitions.qml101
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp53
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp16
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp45
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro1
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp91
-rw-r--r--tests/auto/quick/qquickpincharea/qquickpincharea.pro1
-rw-r--r--tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp25
-rw-r--r--tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp10
-rw-r--r--tests/auto/quick/qquickrepeater/data/invalidContextCrash.qml7
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp43
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp10
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp9
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp55
-rw-r--r--tests/auto/quick/qquickwindow/qquickwindow.pro1
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp156
-rw-r--r--tests/auto/quick/rendernode/data/matrix.qml87
-rw-r--r--tests/auto/quick/rendernode/rendernode.pro2
-rw-r--r--tests/auto/quick/rendernode/tst_rendernode.cpp98
-rw-r--r--tests/auto/quick/shared/viewtestutil.cpp23
-rw-r--r--tests/auto/quick/shared/viewtestutil.h4
-rw-r--r--tests/auto/quick/touchmouse/touchmouse.pro1
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp117
-rw-r--r--tests/auto/quickwidgets/qquickwidget/data/animating.qml11
-rw-r--r--tests/auto/quickwidgets/qquickwidget/data/error1.qml5
-rw-r--r--tests/auto/quickwidgets/qquickwidget/data/rectangle.qml8
-rw-r--r--tests/auto/quickwidgets/qquickwidget/data/resizemodeitem.qml7
-rw-r--r--tests/auto/quickwidgets/qquickwidget/qquickwidget.pro19
-rw-r--r--tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp276
-rw-r--r--tests/auto/quickwidgets/quickwidgets.pro2
-rw-r--r--tests/auto/shared/testhttpserver.cpp15
-rw-r--r--tests/auto/shared/testhttpserver.h5
85 files changed, 3124 insertions, 321 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 715f3e01ad..d37e4a57ed 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -9,6 +9,8 @@ SUBDIRS=\
cmake \
installed_cmake
+qtHaveModule(widgets): SUBDIRS += quickwidgets
+
qmldevtools.CONFIG = host_build
installed_cmake.depends = cmake
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index b544427c08..935b9d4120 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -61,6 +61,7 @@ struct QQmlProfilerData
int column; //used by RangeLocation
int framerate; //used by animation events
int animationcount; //used by animation events
+ qint64 amount; //used by heap events
QByteArray toByteArray() const;
};
@@ -79,6 +80,7 @@ public:
Complete, // end of transmission
PixmapCacheEvent,
SceneGraphFrame,
+ MemoryAllocation,
MaximumMessage
};
@@ -131,6 +133,12 @@ public:
MaximumSceneGraphFrameType
};
+ enum MemoryType {
+ HeapPage,
+ LargeItem,
+ SmallItem
+ };
+
QQmlProfilerClient(QQmlDebugConnection *connection)
: QQmlDebugClient(QLatin1String("CanvasFrameRate"), connection)
{
@@ -138,6 +146,7 @@ public:
QList<QQmlProfilerData> qmlMessages;
QList<QQmlProfilerData> javascriptMessages;
+ QList<QQmlProfilerData> jsHeapMessages;
QList<QQmlProfilerData> asynchronousMessages;
QList<QQmlProfilerData> pixmapMessages;
@@ -175,6 +184,7 @@ private:
void connect(bool block, const QString &testFile);
void checkTraceReceived();
+ void checkJsHeap();
private slots:
void cleanup();
@@ -303,6 +313,11 @@ void QQmlProfilerClient::messageReceived(const QByteArray &message)
}
break;
}
+ case QQmlProfilerClient::MemoryAllocation: {
+ stream >> data.detailType;
+ stream >> data.amount;
+ break;
+ }
default:
QString failMsg = QString("Unknown message type:") + data.messageType;
QFAIL(qPrintable(failMsg));
@@ -314,6 +329,8 @@ void QQmlProfilerClient::messageReceived(const QByteArray &message)
else if (data.messageType == QQmlProfilerClient::SceneGraphFrame ||
data.messageType == QQmlProfilerClient::Event)
asynchronousMessages.append(data);
+ else if (data.messageType == QQmlProfilerClient::MemoryAllocation)
+ jsHeapMessages.append(data);
else if (data.detailType == QQmlProfilerClient::Javascript)
javascriptMessages.append(data);
else
@@ -357,6 +374,48 @@ void tst_QQmlProfilerService::checkTraceReceived()
QCOMPARE(m_client->asynchronousMessages.last().detailType, (int)QQmlProfilerClient::EndTrace);
}
+void tst_QQmlProfilerService::checkJsHeap()
+{
+ QVERIFY2(m_client->jsHeapMessages.count() > 0, "no JavaScript heap messages received");
+
+ bool seen_alloc = false;
+ bool seen_small = false;
+ bool seen_large = false;
+ qint64 allocated = 0;
+ qint64 used = 0;
+ foreach (const QQmlProfilerData &message, m_client->jsHeapMessages) {
+ switch (message.detailType) {
+ case QQmlProfilerClient::HeapPage:
+ allocated += message.amount;
+ seen_alloc = true;
+ break;
+ case QQmlProfilerClient::SmallItem:
+ used += message.amount;
+ seen_small = true;
+ break;
+ case QQmlProfilerClient::LargeItem:
+ allocated += message.amount;
+ used += message.amount;
+ seen_large = true;
+ break;
+ }
+
+ QVERIFY2(used >= 0, QString::fromLatin1("Negative memory usage seen: %1")
+ .arg(used).toUtf8().constData());
+
+ QVERIFY2(allocated >= 0, QString::fromLatin1("Negative memory allocation seen: %1")
+ .arg(allocated).toUtf8().constData());
+
+ QVERIFY2(used <= allocated,
+ QString::fromLatin1("More memory usage than allocation seen: %1 > %2")
+ .arg(used).arg(allocated).toUtf8().constData());
+ }
+
+ QVERIFY2(seen_alloc, "No heap allocation seen");
+ QVERIFY2(seen_small, "No small item seen");
+ QVERIFY2(seen_large, "No large item seen");
+}
+
void tst_QQmlProfilerService::cleanup()
{
if (QTest::currentTestFailed()) {
@@ -388,6 +447,12 @@ void tst_QQmlProfilerService::cleanup()
<< data.line << data.column;
}
qDebug() << " ";
+ qDebug() << "Javascript Heap Messages:" << m_client->jsHeapMessages.count();
+ i = 0;
+ foreach (const QQmlProfilerData &data, m_client->jsHeapMessages) {
+ qDebug() << i++ << data.time << data.messageType << data.detailType;
+ }
+ qDebug() << " ";
qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
qDebug() << "Connection State:" << (m_connection ? m_connection->stateString() : QLatin1String("null"));
@@ -410,6 +475,7 @@ void tst_QQmlProfilerService::blockingConnectWithTraceEnabled()
m_client->setTraceState(true);
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
}
void tst_QQmlProfilerService::blockingConnectWithTraceDisabled()
@@ -422,6 +488,7 @@ void tst_QQmlProfilerService::blockingConnectWithTraceDisabled()
m_client->setTraceState(true);
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
}
void tst_QQmlProfilerService::nonBlockingConnect()
@@ -433,6 +500,7 @@ void tst_QQmlProfilerService::nonBlockingConnect()
m_client->setTraceState(true);
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
}
void tst_QQmlProfilerService::pixmapCacheData()
@@ -451,6 +519,7 @@ void tst_QQmlProfilerService::pixmapCacheData()
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
QVERIFY2(m_client->pixmapMessages.count() >= 4,
QString::number(m_client->pixmapMessages.count()).toUtf8().constData());
@@ -487,6 +556,7 @@ void tst_QQmlProfilerService::scenegraphData()
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
// check that at least one frame was rendered
// there should be a SGPolishAndSync + SGRendererFrame + SGRenderLoopFrame sequence
@@ -516,6 +586,7 @@ void tst_QQmlProfilerService::profileOnExit()
m_client->setTraceState(true);
checkTraceReceived();
+ checkJsHeap();
}
void tst_QQmlProfilerService::controlFromJS()
@@ -526,6 +597,7 @@ void tst_QQmlProfilerService::controlFromJS()
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
}
void tst_QQmlProfilerService::signalSourceLocation()
@@ -539,6 +611,7 @@ void tst_QQmlProfilerService::signalSourceLocation()
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
QVERIFY2(m_client->qmlMessages.count() >= 16,
QString::number(m_client->qmlMessages.count()).toUtf8().constData());
@@ -569,6 +642,7 @@ void tst_QQmlProfilerService::javascript()
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
m_client->setTraceState(false);
checkTraceReceived();
+ checkJsHeap();
QVERIFY2(m_client->javascriptMessages.count() >= 22,
QString::number(m_client->javascriptMessages.count()).toUtf8().constData());
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
index 610d80d559..022ba8c440 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
@@ -84,7 +84,8 @@ QQmlEngineDebugClient::QQmlEngineDebugClient(
QQmlDebugConnection *connection)
: QQmlDebugClient(QLatin1String("QmlDebugger"), connection),
m_nextId(0),
- m_valid(false)
+ m_valid(false),
+ m_connection(connection)
{
}
@@ -467,6 +468,9 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
{
m_valid = false;
QDataStream ds(data);
+ ds.setVersion(m_connection->dataStreamVersion());
+
+
int queryId;
QByteArray type;
ds >> type >> queryId;
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
index 1d4b95a9e3..2712692389 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
@@ -242,6 +242,8 @@ private:
QmlDebugObjectReference m_object;
QList<QmlDebugObjectReference> m_objects;
QVariant m_exprResult;
+
+ QQmlDebugConnection *m_connection;
};
#endif // QQMLENGINEDEBUGCLIENT_H
diff --git a/tests/auto/qml/qjsengine/idtranslatable-unicode.js b/tests/auto/qml/qjsengine/idtranslatable-unicode.js
new file mode 100644
index 0000000000..e17d6172bc
--- /dev/null
+++ b/tests/auto/qml/qjsengine/idtranslatable-unicode.js
@@ -0,0 +1,5 @@
+qsTrId('\u01F8\u01D2\u0199\u01D0\u01E1');
+
+QT_TRID_NOOP("\u0191\u01CE\u0211\u0229\u019C\u018E\u019A\u01D0");
+
+qsTrId("\u0181\u01A1\u0213\u018F\u018C", 10);
diff --git a/tests/auto/qml/qjsengine/idtranslatable.js b/tests/auto/qml/qjsengine/idtranslatable.js
new file mode 100644
index 0000000000..554ca88d41
--- /dev/null
+++ b/tests/auto/qml/qjsengine/idtranslatable.js
@@ -0,0 +1,5 @@
+qsTrId("qtn_foo_bar");
+
+var more_greeting_strings = [ QT_TRID_NOOP("qtn_needle"), QT_TRID_NOOP("qtn_haystack") ];
+
+qsTrId("qtn_bar_baz", 10);
diff --git a/tests/auto/qml/qjsengine/qjsengine.pro b/tests/auto/qml/qjsengine/qjsengine.pro
index a62eb75c21..fc2452c2bc 100644
--- a/tests/auto/qml/qjsengine/qjsengine.pro
+++ b/tests/auto/qml/qjsengine/qjsengine.pro
@@ -4,6 +4,7 @@ TARGET = tst_qjsengine
QT += qml qml-private widgets testlib gui-private
macx:CONFIG -= app_bundle
SOURCES += tst_qjsengine.cpp
+RESOURCES += qjsengine.qrc
TESTDATA = script/*
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qjsengine/qjsengine.qrc b/tests/auto/qml/qjsengine/qjsengine.qrc
new file mode 100644
index 0000000000..d05d115966
--- /dev/null
+++ b/tests/auto/qml/qjsengine/qjsengine.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>translations/translatable_la.qm</file>
+ <file>translations/idtranslatable_la.qm</file>
+ <file>translations/translatable-unicode.qm</file>
+ <file>translations/idtranslatable-unicode.qm</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/qml/qjsengine/translatable-unicode.js b/tests/auto/qml/qjsengine/translatable-unicode.js
new file mode 100644
index 0000000000..afe2aff21c
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translatable-unicode.js
@@ -0,0 +1,9 @@
+qsTr("H\u2082O");
+qsTranslate("\u010C\u0101\u011F\u0115", "CO\u2082");
+
+var unicode_strings = [
+ QT_TR_NOOP("\u0391\u0392\u0393"),
+ QT_TRANSLATE_NOOP("\u010C\u0101\u011F\u0115", "\u0414\u0415\u0416")
+];
+
+qsTr("H\u2082O", "not the same H\u2082O");
diff --git a/tests/auto/qml/qjsengine/translatable.js b/tests/auto/qml/qjsengine/translatable.js
new file mode 100644
index 0000000000..5d6ad9b3b6
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translatable.js
@@ -0,0 +1,12 @@
+qsTr("One");
+qsTranslate("FooContext", "Two");
+
+var greeting_strings = [
+ QT_TR_NOOP("Hello"),
+ QT_TRANSLATE_NOOP("FooContext", "Goodbye")
+];
+
+qsTr("One", "not the same one");
+
+qsTr("%n message(s) saved", "", 10);
+qsTranslate("FooContext", "%n fooish bar(s) found", "", 10);
diff --git a/tests/auto/qml/qjsengine/translatable2.js b/tests/auto/qml/qjsengine/translatable2.js
new file mode 100644
index 0000000000..eee66f17c1
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translatable2.js
@@ -0,0 +1,9 @@
+qsTr("Three");
+qsTranslate("BarContext", "Four");
+
+var celebration_strings = [
+ QT_TR_NOOP("Happy birthday!"),
+ QT_TRANSLATE_NOOP("BarContext", "Congratulations!")
+];
+
+qsTr("Three", "not the same three");
diff --git a/tests/auto/qml/qjsengine/translations/idtranslatable-unicode.qm b/tests/auto/qml/qjsengine/translations/idtranslatable-unicode.qm
new file mode 100644
index 0000000000..8c5fb91b1d
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/idtranslatable-unicode.qm
Binary files differ
diff --git a/tests/auto/qml/qjsengine/translations/idtranslatable-unicode.ts b/tests/auto/qml/qjsengine/translations/idtranslatable-unicode.ts
new file mode 100644
index 0000000000..74ebf43c47
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/idtranslatable-unicode.ts
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="nb_NO">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name></name>
+ <message id="Ǹǒƙǐǡ">
+ <location filename="idtranslatable-unicode.js" line="1"/>
+ <source></source>
+ <translation>Ƨưƈȼȝȿș</translation>
+ </message>
+ <message id="ƑǎȑȩƜƎƚǐ">
+ <location filename="idtranslatable-unicode.js" line="3"/>
+ <source></source>
+ <translation>Ǡȡȋȅȕ</translation>
+ </message>
+ <message id="ƁơȓƏƌ" numerus="yes">
+ <location filename="idtranslatable-unicode.js" line="5"/>
+ <source></source>
+ <translation>
+ <numerusform>Ƒưǹ</numerusform>
+ <numerusform>%n ƒơǒ(ș)</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qml/qjsengine/translations/idtranslatable_la.qm b/tests/auto/qml/qjsengine/translations/idtranslatable_la.qm
new file mode 100644
index 0000000000..c8c0b72acb
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/idtranslatable_la.qm
Binary files differ
diff --git a/tests/auto/qml/qjsengine/translations/idtranslatable_la.ts b/tests/auto/qml/qjsengine/translations/idtranslatable_la.ts
new file mode 100644
index 0000000000..b6d7053024
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/idtranslatable_la.ts
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="nb_NO">
+<context>
+ <name></name>
+ <message id="qtn_foo_bar">
+ <location filename="idtranslatable.js" line="1"/>
+ <source></source>
+ <translation>First string</translation>
+ </message>
+ <message id="qtn_needle">
+ <location filename="idtranslatable.js" line="3"/>
+ <source></source>
+ <translation>Second string</translation>
+ </message>
+ <message id="qtn_haystack">
+ <location filename="idtranslatable.js" line="3"/>
+ <source></source>
+ <translation>Third string</translation>
+ </message>
+ <message id="qtn_bar_baz" numerus="yes">
+ <location filename="idtranslatable.js" line="5"/>
+ <source></source>
+ <translation>
+ <numerusform>Fourth string</numerusform>
+ <numerusform>%n fooish bar(s) found</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qml/qjsengine/translations/translatable-unicode.qm b/tests/auto/qml/qjsengine/translations/translatable-unicode.qm
new file mode 100644
index 0000000000..aa75ce61df
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/translatable-unicode.qm
Binary files differ
diff --git a/tests/auto/qml/qjsengine/translations/translatable-unicode.ts b/tests/auto/qml/qjsengine/translations/translatable-unicode.ts
new file mode 100644
index 0000000000..1b8b4d2309
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/translatable-unicode.ts
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>translatable-unicode</name>
+ <message>
+ <location filename="translatable-unicode.js" line="1"/>
+ <source>H₂O</source>
+ <translation>ͻͼͽ</translation>
+ </message>
+ <message>
+ <location filename="translatable-unicode.js" line="5"/>
+ <source>ΑΒΓ</source>
+ <translation>ӜҴѼ</translation>
+ </message>
+ <message>
+ <location filename="translatable-unicode.js" line="9"/>
+ <source>H₂O</source>
+ <comment>not the same H₂O</comment>
+ <translation>ԶՊՒ</translation>
+ </message>
+</context>
+<context>
+ <name>Čāğĕ</name>
+ <message>
+ <location filename="translatable-unicode.js" line="2"/>
+ <source>CO₂</source>
+ <translation>בךע</translation>
+ </message>
+ <message>
+ <location filename="translatable-unicode.js" line="6"/>
+ <source>ДЕЖ</source>
+ <translation>خسس</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qml/qjsengine/translations/translatable_la.qm b/tests/auto/qml/qjsengine/translations/translatable_la.qm
new file mode 100644
index 0000000000..d76b1cad5f
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/translatable_la.qm
Binary files differ
diff --git a/tests/auto/qml/qjsengine/translations/translatable_la.ts b/tests/auto/qml/qjsengine/translations/translatable_la.ts
new file mode 100644
index 0000000000..36271c9cbe
--- /dev/null
+++ b/tests/auto/qml/qjsengine/translations/translatable_la.ts
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="nb_NO">
+<context>
+ <name>BarContext</name>
+ <message>
+ <location filename="translatable2.js" line="2"/>
+ <source>Four</source>
+ <translation>Fire</translation>
+ </message>
+ <message>
+ <location filename="translatable2.js" line="6"/>
+ <source>Congratulations!</source>
+ <translation>Gratulerer!</translation>
+ </message>
+</context>
+<context>
+ <name>FooContext</name>
+ <message>
+ <location filename="translatable.js" line="2"/>
+ <source>Two</source>
+ <translation>To</translation>
+ </message>
+ <message>
+ <location filename="translatable.js" line="6"/>
+ <source>Goodbye</source>
+ <translation>Farvel</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="translatable.js" line="12"/>
+ <source>%n fooish bar(s) found</source>
+ <translation>
+ <numerusform>%n fooaktig bar funnet</numerusform>
+ <numerusform>%n fooaktige barer funnet</numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>translatable</name>
+ <message>
+ <location filename="translatable.js" line="1"/>
+ <source>One</source>
+ <translation>En</translation>
+ </message>
+ <message>
+ <location filename="translatable.js" line="5"/>
+ <source>Hello</source>
+ <translation>Hallo</translation>
+ </message>
+ <message>
+ <location filename="translatable.js" line="9"/>
+ <source>One</source>
+ <comment>not the same one</comment>
+ <translation>Enda en</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="translatable.js" line="11"/>
+ <source>%n message(s) saved</source>
+ <translation>
+ <numerusform>%n melding lagret</numerusform>
+ <numerusform>%n meldinger lagret</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Goodbye</source>
+ <translation type="obsolete">Farvel</translation>
+ </message>
+</context>
+<context>
+ <name>translatable2</name>
+ <message>
+ <location filename="translatable2.js" line="1"/>
+ <source>Three</source>
+ <translation>Tre</translation>
+ </message>
+ <message>
+ <location filename="translatable2.js" line="5"/>
+ <source>Happy birthday!</source>
+ <translation>Gratulerer med dagen!</translation>
+ </message>
+ <message>
+ <location filename="translatable2.js" line="9"/>
+ <source>Three</source>
+ <comment>not the same three</comment>
+ <translation>Tre andre</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 51cd69998a..8a1bedb600 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -159,6 +159,27 @@ private slots:
void scopeOfEvaluate();
+ void callConstants();
+
+ void installTranslatorFunctions();
+ void translateScript_data();
+ void translateScript();
+ void translateScript_crossScript();
+ void translateScript_trNoOp();
+ void translateScript_callQsTrFromCpp();
+ void translateWithInvalidArgs_data();
+ void translateWithInvalidArgs();
+ void translationContext_data();
+ void translationContext();
+ void translateScriptIdBased();
+ void translateScriptUnicode_data();
+ void translateScriptUnicode();
+ void translateScriptUnicodeIdBased_data();
+ void translateScriptUnicodeIdBased();
+ void translateFromBuiltinCallback();
+
+ void privateMethods();
+
signals:
void testSignal();
};
@@ -3099,6 +3120,471 @@ void tst_QJSEngine::scopeOfEvaluate()
QCOMPARE(result.toInt(), 42);
}
+void tst_QJSEngine::callConstants()
+{
+ QJSEngine engine;
+ engine.evaluate("function f() {\n"
+ " var one; one();\n"
+ " var two = null; two();\n"
+ "}\n");
+}
+
+void tst_QJSEngine::installTranslatorFunctions()
+{
+ QJSEngine eng;
+ QJSValue global = eng.globalObject();
+ QVERIFY(global.property("qsTranslate").isUndefined());
+ QVERIFY(global.property("QT_TRANSLATE_NOOP").isUndefined());
+ QVERIFY(global.property("qsTr").isUndefined());
+ QVERIFY(global.property("QT_TR_NOOP").isUndefined());
+ QVERIFY(global.property("qsTrId").isUndefined());
+ QVERIFY(global.property("QT_TRID_NOOP").isUndefined());
+
+ eng.installTranslatorFunctions();
+ QVERIFY(global.property("qsTranslate").isCallable());
+ QVERIFY(global.property("QT_TRANSLATE_NOOP").isCallable());
+ QVERIFY(global.property("qsTr").isCallable());
+ QVERIFY(global.property("QT_TR_NOOP").isCallable());
+ QVERIFY(global.property("qsTrId").isCallable());
+ QVERIFY(global.property("QT_TRID_NOOP").isCallable());
+
+ {
+ QJSValue ret = eng.evaluate("qsTr('foo')");
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QString::fromLatin1("foo"));
+ }
+ {
+ QJSValue ret = eng.evaluate("qsTranslate('foo', 'bar')");
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QString::fromLatin1("bar"));
+ }
+ {
+ QJSValue ret = eng.evaluate("QT_TR_NOOP('foo')");
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QString::fromLatin1("foo"));
+ }
+ {
+ QJSValue ret = eng.evaluate("QT_TRANSLATE_NOOP('foo', 'bar')");
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QString::fromLatin1("bar"));
+ }
+
+ {
+ QJSValue ret = eng.evaluate("qsTrId('foo')");
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QString::fromLatin1("foo"));
+ }
+ {
+ QJSValue ret = eng.evaluate("QT_TRID_NOOP('foo')");
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QString::fromLatin1("foo"));
+ }
+ QVERIFY(eng.evaluate("QT_TRID_NOOP()").isUndefined());
+}
+
+class TranslationScope
+{
+public:
+ TranslationScope(const QString &fileName)
+ {
+ translator.load(fileName);
+ QCoreApplication::instance()->installTranslator(&translator);
+ }
+ ~TranslationScope()
+ {
+ QCoreApplication::instance()->removeTranslator(&translator);
+ }
+
+private:
+ QTranslator translator;
+};
+
+void tst_QJSEngine::translateScript_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("expectedTranslation");
+
+ QString fileName = QString::fromLatin1("translatable.js");
+ // Top-level
+ QTest::newRow("qsTr('One')@translatable.js")
+ << QString::fromLatin1("qsTr('One')") << fileName << QString::fromLatin1("En");
+ QTest::newRow("qsTr('Hello')@translatable.js")
+ << QString::fromLatin1("qsTr('Hello')") << fileName << QString::fromLatin1("Hallo");
+ // From function
+ QTest::newRow("(function() { return qsTr('One'); })()@translatable.js")
+ << QString::fromLatin1("(function() { return qsTr('One'); })()") << fileName << QString::fromLatin1("En");
+ QTest::newRow("(function() { return qsTr('Hello'); })()@translatable.js")
+ << QString::fromLatin1("(function() { return qsTr('Hello'); })()") << fileName << QString::fromLatin1("Hallo");
+ // Plural
+ QTest::newRow("qsTr('%n message(s) saved', '', 1)@translatable.js")
+ << QString::fromLatin1("qsTr('%n message(s) saved', '', 1)") << fileName << QString::fromLatin1("1 melding lagret");
+ QTest::newRow("qsTr('%n message(s) saved', '', 3).arg@translatable.js")
+ << QString::fromLatin1("qsTr('%n message(s) saved', '', 3)") << fileName << QString::fromLatin1("3 meldinger lagret");
+
+ // Top-level
+ QTest::newRow("qsTranslate('FooContext', 'Two')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Two')") << fileName << QString::fromLatin1("To");
+ QTest::newRow("qsTranslate('FooContext', 'Goodbye')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye')") << fileName << QString::fromLatin1("Farvel");
+ // From eval
+ QTest::newRow("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')@translatable.js")
+ << QString::fromLatin1("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')") << fileName << QString::fromLatin1("To");
+ QTest::newRow("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')@translatable.js")
+ << QString::fromLatin1("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')") << fileName << QString::fromLatin1("Farvel");
+
+ QTest::newRow("qsTranslate('FooContext', 'Goodbye', '')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '')") << fileName << QString::fromLatin1("Farvel");
+
+ QTest::newRow("qsTranslate('FooContext', 'Goodbye', '', 42)@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '', 42)") << fileName << QString::fromLatin1("Goodbye");
+
+ QTest::newRow("qsTr('One', 'not the same one')@translatable.js")
+ << QString::fromLatin1("qsTr('One', 'not the same one')") << fileName << QString::fromLatin1("Enda en");
+
+ QTest::newRow("qsTr('One', 'not the same one', 42)@translatable.js")
+ << QString::fromLatin1("qsTr('One', 'not the same one', 42)") << fileName << QString::fromLatin1("One");
+
+ // Plural
+ QTest::newRow("qsTranslate('FooContext', '%n fooish bar(s) found', '', 1)@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', '%n fooish bar(s) found', '', 1)") << fileName << QString::fromLatin1("1 fooaktig bar funnet");
+ QTest::newRow("qsTranslate('FooContext', '%n fooish bar(s) found', '', 2)@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', '%n fooish bar(s) found', '', 2)") << fileName << QString::fromLatin1("2 fooaktige barer funnet");
+
+ // Don't exist in translation
+ QTest::newRow("qsTr('Three')@translatable.js")
+ << QString::fromLatin1("qsTr('Three')") << fileName << QString::fromLatin1("Three");
+ QTest::newRow("qsTranslate('FooContext', 'So long')@translatable.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'So long')") << fileName << QString::fromLatin1("So long");
+ QTest::newRow("qsTranslate('BarContext', 'Goodbye')@translatable.js")
+ << QString::fromLatin1("qsTranslate('BarContext', 'Goodbye')") << fileName << QString::fromLatin1("Goodbye");
+
+ // Translate strings from the second script (translatable2.js)
+
+ QString fileName2 = QString::fromLatin1("translatable2.js");
+ QTest::newRow("qsTr('Three')@translatable2.js")
+ << QString::fromLatin1("qsTr('Three')") << fileName2 << QString::fromLatin1("Tre");
+ QTest::newRow("qsTr('Happy birthday!')@translatable2.js")
+ << QString::fromLatin1("qsTr('Happy birthday!')") << fileName2 << QString::fromLatin1("Gratulerer med dagen!");
+
+ // Not translated because translation is only in translatable.js
+ QTest::newRow("qsTr('One')@translatable2.js")
+ << QString::fromLatin1("qsTr('One')") << fileName2 << QString::fromLatin1("One");
+ QTest::newRow("(function() { return qsTr('One'); })()@translatable2.js")
+ << QString::fromLatin1("(function() { return qsTr('One'); })()") << fileName2 << QString::fromLatin1("One");
+
+ // For qsTranslate() the filename shouldn't matter
+ QTest::newRow("qsTranslate('FooContext', 'Two')@translatable2.js")
+ << QString::fromLatin1("qsTranslate('FooContext', 'Two')") << fileName2 << QString::fromLatin1("To");
+ QTest::newRow("qsTranslate('BarContext', 'Congratulations!')@translatable.js")
+ << QString::fromLatin1("qsTranslate('BarContext', 'Congratulations!')") << fileName << QString::fromLatin1("Gratulerer!");
+}
+
+void tst_QJSEngine::translateScript()
+{
+ QFETCH(QString, expression);
+ QFETCH(QString, fileName);
+ QFETCH(QString, expectedTranslation);
+
+ QJSEngine engine;
+
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ QCOMPARE(engine.evaluate(expression, fileName).toString(), expectedTranslation);
+}
+
+void tst_QJSEngine::translateScript_crossScript()
+{
+ QJSEngine engine;
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ QString fileName = QString::fromLatin1("translatable.js");
+ QString fileName2 = QString::fromLatin1("translatable2.js");
+ // qsTr() should use the innermost filename as context
+ engine.evaluate("function foo(s) { return bar(s); }", fileName);
+ engine.evaluate("function bar(s) { return qsTr(s); }", fileName2);
+ QCOMPARE(engine.evaluate("bar('Three')", fileName2).toString(), QString::fromLatin1("Tre"));
+ QCOMPARE(engine.evaluate("bar('Three')", fileName).toString(), QString::fromLatin1("Tre"));
+ QCOMPARE(engine.evaluate("bar('One')", fileName2).toString(), QString::fromLatin1("One"));
+
+ engine.evaluate("function foo(s) { return bar(s); }", fileName2);
+ engine.evaluate("function bar(s) { return qsTr(s); }", fileName);
+ QCOMPARE(engine.evaluate("bar('Three')", fileName2).toString(), QString::fromLatin1("Three"));
+ QCOMPARE(engine.evaluate("bar('One')", fileName).toString(), QString::fromLatin1("En"));
+ QCOMPARE(engine.evaluate("bar('One')", fileName2).toString(), QString::fromLatin1("En"));
+}
+
+void tst_QJSEngine::translateScript_trNoOp()
+{
+ QJSEngine engine;
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ QVERIFY(engine.evaluate("QT_TR_NOOP()").isUndefined());
+ QCOMPARE(engine.evaluate("QT_TR_NOOP('One')").toString(), QString::fromLatin1("One"));
+
+ QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP()").isUndefined());
+ QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP('FooContext')").isUndefined());
+ QCOMPARE(engine.evaluate("QT_TRANSLATE_NOOP('FooContext', 'Two')").toString(), QString::fromLatin1("Two"));
+}
+
+void tst_QJSEngine::translateScript_callQsTrFromCpp()
+{
+ QJSEngine engine;
+ TranslationScope tranScope(":/translations/translatable_la");
+ engine.installTranslatorFunctions();
+
+ // There is no context, but it shouldn't crash
+ QCOMPARE(engine.globalObject().property("qsTr").call(QJSValueList() << "One").toString(), QString::fromLatin1("One"));
+}
+
+void tst_QJSEngine::translateWithInvalidArgs_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QString>("expectedError");
+
+ QTest::newRow("qsTr()") << "qsTr()" << "Error: qsTr() requires at least one argument";
+ QTest::newRow("qsTr(123)") << "qsTr(123)" << "Error: qsTr(): first argument (sourceText) must be a string";
+ QTest::newRow("qsTr('foo', 123)") << "qsTr('foo', 123)" << "Error: qsTr(): second argument (disambiguation) must be a string";
+ QTest::newRow("qsTr('foo', 'bar', 'baz')") << "qsTr('foo', 'bar', 'baz')" << "Error: qsTr(): third argument (n) must be a number";
+ QTest::newRow("qsTr('foo', 'bar', true)") << "qsTr('foo', 'bar', true)" << "Error: qsTr(): third argument (n) must be a number";
+
+ QTest::newRow("qsTranslate()") << "qsTranslate()" << "Error: qsTranslate() requires at least two arguments";
+ QTest::newRow("qsTranslate('foo')") << "qsTranslate('foo')" << "Error: qsTranslate() requires at least two arguments";
+ QTest::newRow("qsTranslate(123, 'foo')") << "qsTranslate(123, 'foo')" << "Error: qsTranslate(): first argument (context) must be a string";
+ QTest::newRow("qsTranslate('foo', 123)") << "qsTranslate('foo', 123)" << "Error: qsTranslate(): second argument (sourceText) must be a string";
+ QTest::newRow("qsTranslate('foo', 'bar', 123)") << "qsTranslate('foo', 'bar', 123)" << "Error: qsTranslate(): third argument (disambiguation) must be a string";
+
+ QTest::newRow("qsTrId()") << "qsTrId()" << "Error: qsTrId() requires at least one argument";
+ QTest::newRow("qsTrId(123)") << "qsTrId(123)" << "TypeError: qsTrId(): first argument (id) must be a string";
+ QTest::newRow("qsTrId('foo', 'bar')") << "qsTrId('foo', 'bar')" << "TypeError: qsTrId(): second argument (n) must be a number";
+}
+
+void tst_QJSEngine::translateWithInvalidArgs()
+{
+ QFETCH(QString, expression);
+ QFETCH(QString, expectedError);
+ QJSEngine engine;
+ engine.installTranslatorFunctions();
+ QJSValue result = engine.evaluate(expression);
+ QVERIFY(result.isError());
+ QCOMPARE(result.toString(), expectedError);
+}
+
+void tst_QJSEngine::translationContext_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("expectedTranslation");
+
+ QTest::newRow("translatable.js") << "translatable.js" << "One" << "En";
+ QTest::newRow("/translatable.js") << "/translatable.js" << "One" << "En";
+ QTest::newRow("/foo/translatable.js") << "/foo/translatable.js" << "One" << "En";
+ QTest::newRow("/foo/bar/translatable.js") << "/foo/bar/translatable.js" << "One" << "En";
+ QTest::newRow("./translatable.js") << "./translatable.js" << "One" << "En";
+ QTest::newRow("../translatable.js") << "../translatable.js" << "One" << "En";
+ QTest::newRow("foo/translatable.js") << "foo/translatable.js" << "One" << "En";
+ QTest::newRow("file:///home/qt/translatable.js") << "file:///home/qt/translatable.js" << "One" << "En";
+ QTest::newRow(":/resources/translatable.js") << ":/resources/translatable.js" << "One" << "En";
+ QTest::newRow("/translatable.js.foo") << "/translatable.js.foo" << "One" << "En";
+ QTest::newRow("/translatable.txt") << "/translatable.txt" << "One" << "En";
+ QTest::newRow("translatable") << "translatable" << "One" << "En";
+ QTest::newRow("foo/translatable") << "foo/translatable" << "One" << "En";
+
+ QTest::newRow("translatable.js/") << "translatable.js/" << "One" << "One";
+ QTest::newRow("nosuchscript.js") << "" << "One" << "One";
+ QTest::newRow("(empty)") << "" << "One" << "One";
+}
+
+void tst_QJSEngine::translationContext()
+{
+ TranslationScope tranScope(":/translations/translatable_la");
+
+ QJSEngine engine;
+ engine.installTranslatorFunctions();
+
+ QFETCH(QString, path);
+ QFETCH(QString, text);
+ QFETCH(QString, expectedTranslation);
+ QJSValue ret = engine.evaluate(QString::fromLatin1("qsTr('%0')").arg(text), path);
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), expectedTranslation);
+}
+
+void tst_QJSEngine::translateScriptIdBased()
+{
+ QJSEngine engine;
+
+ TranslationScope tranScope(":/translations/idtranslatable_la");
+ engine.installTranslatorFunctions();
+
+ QString fileName = QString::fromLatin1("idtranslatable.js");
+
+ QHash<QString, QString> expectedTranslations;
+ expectedTranslations["qtn_foo_bar"] = "First string";
+ expectedTranslations["qtn_needle"] = "Second string";
+ expectedTranslations["qtn_haystack"] = "Third string";
+ expectedTranslations["qtn_bar_baz"] = "Fourth string";
+
+ QHash<QString, QString>::const_iterator it;
+ for (it = expectedTranslations.constBegin(); it != expectedTranslations.constEnd(); ++it) {
+ for (int x = 0; x < 2; ++x) {
+ QString fn;
+ if (x)
+ fn = fileName;
+ // Top-level
+ QCOMPARE(engine.evaluate(QString::fromLatin1("qsTrId('%0')")
+ .arg(it.key()), fn).toString(),
+ it.value());
+ QCOMPARE(engine.evaluate(QString::fromLatin1("QT_TRID_NOOP('%0')")
+ .arg(it.key()), fn).toString(),
+ it.key());
+ // From function
+ QCOMPARE(engine.evaluate(QString::fromLatin1("(function() { return qsTrId('%0'); })()")
+ .arg(it.key()), fn).toString(),
+ it.value());
+ QCOMPARE(engine.evaluate(QString::fromLatin1("(function() { return QT_TRID_NOOP('%0'); })()")
+ .arg(it.key()), fn).toString(),
+ it.key());
+ }
+ }
+
+ // Plural form
+ QCOMPARE(engine.evaluate("qsTrId('qtn_bar_baz', 10)").toString(),
+ QString::fromLatin1("10 fooish bar(s) found"));
+ QCOMPARE(engine.evaluate("qsTrId('qtn_foo_bar', 10)").toString(),
+ QString::fromLatin1("qtn_foo_bar")); // Doesn't have plural
+}
+
+// How to add a new test row:
+// - Find a nice list of Unicode characters to choose from
+// - Write source string/context/comment in .js using Unicode escape sequences (\uABCD)
+// - Update corresponding .ts file (e.g. lupdate foo.js -ts foo.ts -codecfortr UTF-8)
+// - Enter translation in Linguist
+// - Update corresponding .qm file (e.g. lrelease foo.ts)
+// - Evaluate script that performs translation; make sure the correct result is returned
+// (e.g. by setting the resulting string as the text of a QLabel and visually verifying
+// that it looks the same as what you entered in Linguist :-) )
+// - Generate the expectedTranslation column data using toUtf8().toHex()
+void tst_QJSEngine::translateScriptUnicode_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("expectedTranslation");
+
+ QString fileName = QString::fromLatin1("translatable-unicode.js");
+ QTest::newRow("qsTr('H\\u2082O')@translatable-unicode.js")
+ << QString::fromLatin1("qsTr('H\\u2082O')") << fileName << QString::fromUtf8("\xcd\xbb\xcd\xbc\xcd\xbd");
+ QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')@translatable-unicode.js")
+ << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')") << fileName << QString::fromUtf8("\xd7\x91\xd7\x9a\xd7\xa2");
+ QTest::newRow("qsTr('\\u0391\\u0392\\u0393')@translatable-unicode.js")
+ << QString::fromLatin1("qsTr('\\u0391\\u0392\\u0393')") << fileName << QString::fromUtf8("\xd3\x9c\xd2\xb4\xd1\xbc");
+ QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', '\\u0414\\u0415\\u0416')@translatable-unicode.js")
+ << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', '\\u0414\\u0415\\u0416')") << fileName << QString::fromUtf8("\xd8\xae\xd8\xb3\xd8\xb3");
+ QTest::newRow("qsTr('H\\u2082O', 'not the same H\\u2082O')@translatable-unicode.js")
+ << QString::fromLatin1("qsTr('H\\u2082O', 'not the same H\\u2082O')") << fileName << QString::fromUtf8("\xd4\xb6\xd5\x8a\xd5\x92");
+ QTest::newRow("qsTr('H\\u2082O')")
+ << QString::fromLatin1("qsTr('H\\u2082O')") << QString() << QString::fromUtf8("\x48\xe2\x82\x82\x4f");
+ QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')")
+ << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')") << QString() << QString::fromUtf8("\xd7\x91\xd7\x9a\xd7\xa2");
+}
+
+void tst_QJSEngine::translateScriptUnicode()
+{
+ QFETCH(QString, expression);
+ QFETCH(QString, fileName);
+ QFETCH(QString, expectedTranslation);
+
+ QJSEngine engine;
+
+ TranslationScope tranScope(":/translations/translatable-unicode");
+ engine.installTranslatorFunctions();
+
+ QCOMPARE(engine.evaluate(expression, fileName).toString(), expectedTranslation);
+}
+
+void tst_QJSEngine::translateScriptUnicodeIdBased_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QString>("expectedTranslation");
+
+ QTest::newRow("qsTrId('\\u01F8\\u01D2\\u0199\\u01D0\\u01E1'')")
+ << QString::fromLatin1("qsTrId('\\u01F8\\u01D2\\u0199\\u01D0\\u01E1')") << QString::fromUtf8("\xc6\xa7\xc6\xb0\xc6\x88\xc8\xbc\xc8\x9d\xc8\xbf\xc8\x99");
+ QTest::newRow("qsTrId('\\u0191\\u01CE\\u0211\\u0229\\u019C\\u018E\\u019A\\u01D0')")
+ << QString::fromLatin1("qsTrId('\\u0191\\u01CE\\u0211\\u0229\\u019C\\u018E\\u019A\\u01D0')") << QString::fromUtf8("\xc7\xa0\xc8\xa1\xc8\x8b\xc8\x85\xc8\x95");
+ QTest::newRow("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C', 10)")
+ << QString::fromLatin1("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C', 10)") << QString::fromUtf8("\x31\x30\x20\xc6\x92\xc6\xa1\xc7\x92\x28\xc8\x99\x29");
+ QTest::newRow("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C')")
+ << QString::fromLatin1("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C')") << QString::fromUtf8("\xc6\x91\xc6\xb0\xc7\xb9");
+ QTest::newRow("qsTrId('\\u01CD\\u0180\\u01A8\\u0190\\u019E\\u01AB')")
+ << QString::fromLatin1("qsTrId('\\u01CD\\u0180\\u01A8\\u0190\\u019E\\u01AB')") << QString::fromUtf8("\xc7\x8d\xc6\x80\xc6\xa8\xc6\x90\xc6\x9e\xc6\xab");
+}
+
+void tst_QJSEngine::translateScriptUnicodeIdBased()
+{
+ QFETCH(QString, expression);
+ QFETCH(QString, expectedTranslation);
+
+ QJSEngine engine;
+
+ TranslationScope tranScope(":/translations/idtranslatable-unicode");
+ engine.installTranslatorFunctions();
+
+ QCOMPARE(engine.evaluate(expression).toString(), expectedTranslation);
+}
+
+void tst_QJSEngine::translateFromBuiltinCallback()
+{
+ QJSEngine eng;
+ eng.installTranslatorFunctions();
+
+ // Callback has no translation context.
+ eng.evaluate("function foo() { qsTr('foo'); }");
+
+ // Stack at translation time will be:
+ // qsTr, foo, forEach, global
+ // qsTr() needs to walk to the outer-most (global) frame before it finds
+ // a translation context, and this should not crash.
+ eng.evaluate("[10,20].forEach(foo)", "script.js");
+}
+
+class ObjectWithPrivateMethods : public QObject
+{
+ Q_OBJECT
+private slots:
+ void myPrivateMethod() {}
+};
+
+void tst_QJSEngine::privateMethods()
+{
+ ObjectWithPrivateMethods object;
+ QJSEngine engine;
+ QJSValue jsWrapper = engine.newQObject(&object);
+ QQmlEngine::setObjectOwnership(&object, QQmlEngine::CppOwnership);
+
+ QSet<QString> privateMethods;
+ {
+ const QMetaObject *mo = object.metaObject();
+ for (int i = 0; i < mo->methodCount(); ++i) {
+ const QMetaMethod method = mo->method(i);
+ if (method.access() == QMetaMethod::Private)
+ privateMethods << QString::fromUtf8(method.name());
+ }
+ }
+
+ QVERIFY(privateMethods.contains("myPrivateMethod"));
+ QVERIFY(privateMethods.contains("_q_reregisterTimers"));
+ privateMethods << QStringLiteral("deleteLater") << QStringLiteral("destroyed");
+
+ QJSValueIterator it(jsWrapper);
+ while (it.hasNext()) {
+ it.next();
+ QVERIFY(!privateMethods.contains(it.name()));
+ }
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
index dbf28a5471..d5a5f10634 100644
--- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
+++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
@@ -267,8 +267,8 @@ void tst_qqmlcomponent::qmlCreateParentReference()
void tst_qqmlcomponent::async()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine);
@@ -287,8 +287,8 @@ void tst_qqmlcomponent::async()
void tst_qqmlcomponent::asyncHierarchy()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
// ensure that the item hierarchy is compiled correctly.
diff --git a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.1.qml b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.1.qml
index be283fdda1..027fdbdfcb 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.1.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.1.qml
@@ -3,7 +3,7 @@ import Qt.test 1.0
MySequenceConversionObject {
intListProperty: [1, 2]
- qrealListProperty: [1.1, 2.2]
+ qrealListProperty: [1.1, 2.2, 3]
boolListProperty: [false, true]
urlListProperty: [ "http://www.example1.com", "http://www.example2.com" ]
stringListProperty: [ "one", "two" ]
diff --git a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.3.qml b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.3.qml
index ad8a92e317..e486feb96c 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.3.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.3.qml
@@ -3,7 +3,7 @@ import Qt.test 1.0
MySequenceConversionObject {
intListProperty: 1
- qrealListProperty: 1.1
+ qrealListProperty: 1
boolListProperty: false
urlListProperty: Qt.resolvedUrl("example.html")
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.4.qml b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.4.qml
index a9f2e642d1..10e49af8e0 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.4.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.4.qml
@@ -4,7 +4,7 @@ import Qt.test 1.0
MySequenceConversionObject {
Component.onCompleted: {
intListProperty = [1, 2]
- qrealListProperty = [1.1, 2.2]
+ qrealListProperty = [1.1, 2.2, 3]
boolListProperty = [false, true]
urlListProperty = [ "http://www.example1.com", "http://www.example2.com" ]
stringListProperty = [ "one", "two" ]
diff --git a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.6.qml b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.6.qml
index 7a794eb694..bc72b78af7 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.6.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignSequenceTypes.6.qml
@@ -4,7 +4,7 @@ import Qt.test 1.0
MySequenceConversionObject {
Component.onCompleted: {
intListProperty = 1;
- qrealListProperty = 1.1;
+ qrealListProperty = 1;
boolListProperty = false;
urlListProperty = Qt.resolvedUrl("example.html");
}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index a1e36b42e6..35fb42f02d 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -4171,8 +4171,8 @@ void tst_qqmlecmascript::importScripts()
QFETCH(QStringList, propertyNames);
QFETCH(QVariantList, propertyValues);
- TestHTTPServer server(8111);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(8111), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory() + "/remote");
QStringList importPathList = engine.importPathList();
@@ -5548,7 +5548,7 @@ void tst_qqmlecmascript::assignSequenceTypes()
MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
QVERIFY(object != 0);
QCOMPARE(object->intListProperty(), (QList<int>() << 1 << 2));
- QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2));
+ QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2 << 3));
QCOMPARE(object->boolListProperty(), (QList<bool>() << false << true));
QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com") << QUrl("http://www.example2.com")));
QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one") << QLatin1String("two")));
@@ -5576,7 +5576,7 @@ void tst_qqmlecmascript::assignSequenceTypes()
MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
QVERIFY(object != 0);
QCOMPARE(object->intListProperty(), (QList<int>() << 1));
- QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1));
+ QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1));
QCOMPARE(object->boolListProperty(), (QList<bool>() << false));
QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html"))));
delete object;
@@ -5588,7 +5588,7 @@ void tst_qqmlecmascript::assignSequenceTypes()
MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
QVERIFY(object != 0);
QCOMPARE(object->intListProperty(), (QList<int>() << 1 << 2));
- QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2));
+ QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2 << 3));
QCOMPARE(object->boolListProperty(), (QList<bool>() << false << true));
QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com") << QUrl("http://www.example2.com")));
QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one") << QLatin1String("two")));
@@ -5616,7 +5616,7 @@ void tst_qqmlecmascript::assignSequenceTypes()
MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
QVERIFY(object != 0);
QCOMPARE(object->intListProperty(), (QList<int>() << 1));
- QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1));
+ QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1));
QCOMPARE(object->boolListProperty(), (QList<bool>() << false));
QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html"))));
delete object;
@@ -5999,8 +5999,8 @@ void tst_qqmlecmascript::include()
// Remote - error
{
- TestHTTPServer server(8111);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(8111), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine, testFileUrl("include_remote_missing.qml"));
@@ -6024,8 +6024,8 @@ void tst_qqmlecmascript::includeRemoteSuccess()
#endif
// Remote - success
- TestHTTPServer server(8111);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(8111), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine, testFileUrl("include_remote.qml"));
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 8ffa327cf2..1498fba9e2 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -40,6 +40,8 @@
****************************************************************************/
#include "testtypes.h"
+#include <private/qqmlcompiler_p.h>
+
void registerTypes()
{
qmlRegisterInterface<MyInterface>("MyInterface");
@@ -105,105 +107,70 @@ QVariant myCustomVariantTypeConverter(const QString &data)
}
-QByteArray CustomBindingParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
-{
- QByteArray result;
- QDataStream ds(&result, QIODevice::WriteOnly);
-
- ds << bindings.count();
- for (int i = 0; i < bindings.count(); ++i) {
- const QV4::CompiledData::Binding *binding = bindings.at(i);
- ds << qmlUnit->header.stringAt(binding->propertyNameIndex);
-
- Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
- int bindingId = bindingIdentifier(binding);
- ds << bindingId;
-
- ds << binding->location.line;
- }
-
- return result;
-}
-
-void CustomBindingParser::setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData*)
+void CustomBindingParser::applyBindings(QObject *object, QQmlCompiledData *cdata, const QList<const QV4::CompiledData::Binding *> &bindings)
{
CustomBinding *customBinding = qobject_cast<CustomBinding*>(object);
Q_ASSERT(customBinding);
- customBinding->m_bindingData = data;
+ customBinding->cdata = cdata;
+ customBinding->bindings = bindings;
}
void CustomBinding::componentComplete()
{
Q_ASSERT(m_target);
- QDataStream ds(m_bindingData);
- int count;
- ds >> count;
- for (int i = 0; i < count; ++i) {
- QString name;
- ds >> name;
+ foreach (const QV4::CompiledData::Binding *binding, bindings) {
+ QString name = cdata->compilationUnit->data->stringAt(binding->propertyNameIndex);
- int bindingId;
- ds >> bindingId;
+ int bindingId = binding->value.compiledScriptIndex;
- int line;
- ds >> line;
+ QQmlContextData *context = QQmlContextData::get(qmlContext(this));
- QQmlBinding *binding = QQmlBinding::createBinding(QQmlBinding::Identifier(bindingId), m_target, qmlContext(this));
+ QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this)));
+ QV4::ScopedValue function(scope, QV4::QmlBindingWrapper::createQmlCallableForFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId]));
+ QQmlBinding *qmlBinding = new QQmlBinding(function, m_target, context);
QQmlProperty property(m_target, name, qmlContext(this));
- binding->setTarget(property);
- QQmlPropertyPrivate::setBinding(property, binding);
+ qmlBinding->setTarget(property);
+ QQmlPropertyPrivate::setBinding(property, qmlBinding);
}
}
-QByteArray EnumSupportingCustomParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
+void EnumSupportingCustomParser::verifyBindings(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
{
- Q_UNUSED(qmlUnit)
-
if (bindings.count() != 1) {
error(bindings.first(), QStringLiteral("Custom parser invoked incorrectly for unit test"));
- return QByteArray();
+ return;
}
const QV4::CompiledData::Binding *binding = bindings.first();
if (qmlUnit->header.stringAt(binding->propertyNameIndex) != QStringLiteral("foo")) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property name"));
- return QByteArray();
+ return;
}
if (binding->type != QV4::CompiledData::Binding::Type_Script) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Expected script that evaluates to enum"));
- return QByteArray();
+ return;
}
QByteArray script = qmlUnit->header.stringAt(binding->stringIndex).toUtf8();
bool ok;
int v = evaluateEnum(script, &ok);
if (!ok) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Script did not evaluate to enum"));
- return QByteArray();
+ return;
}
if (v != MyEnum1Class::A_13) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Enum value is not the expected value."));
- return QByteArray();
+ return;
}
-
- return QByteArray();
-}
-
-
-QByteArray SimpleObjectCustomParser::compile(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &bindings)
-{
- return QByteArray::number(bindings.count());
}
-void SimpleObjectCustomParser::setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData*)
+void SimpleObjectCustomParser::applyBindings(QObject *object, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &bindings)
{
- SimpleObjectWithCustomParser *o = qobject_cast<SimpleObjectWithCustomParser*>(object);
- Q_ASSERT(o);
- bool ok = false;
- o->setCustomBindingsCount(data.toInt(&ok));
- Q_ASSERT(ok);
+ SimpleObjectWithCustomParser *o = qobject_cast<SimpleObjectWithCustomParser*>(object);
+ Q_ASSERT(o);
+ o->setCustomBindingsCount(bindings.count());
}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 1c13a2e21c..509cf40e47 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -54,7 +54,7 @@
#include <QtQml/qqmlpropertyvaluesource.h>
#include <QtQml/qqmlscriptstring.h>
#include <QtQml/qqmlproperty.h>
-
+#include <private/qqmlcompiler_p.h>
#include <private/qqmlcustomparser_p.h>
QVariant myCustomVariantTypeConverter(const QString &data);
@@ -739,15 +739,15 @@ class MyCustomParserType : public QObject
class MyCustomParserTypeParser : public QQmlCustomParser
{
public:
- QByteArray compile(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) { return QByteArray(); }
- void setCustomData(QObject *, const QByteArray &, QQmlCompiledData*) {}
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {}
};
class EnumSupportingCustomParser : public QQmlCustomParser
{
public:
- QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
- void setCustomData(QObject *, const QByteArray &, QQmlCompiledData*) {}
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &);
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {}
};
class MyParserStatus : public QObject, public QQmlParserStatus
@@ -1112,13 +1112,15 @@ public:
void setTarget(QObject *newTarget) { m_target = newTarget; }
QPointer<QObject> m_target;
+ QQmlRefPointer<QQmlCompiledData> cdata;
+ QList<const QV4::CompiledData::Binding*> bindings;
QByteArray m_bindingData;
};
class CustomBindingParser : public QQmlCustomParser
{
- virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
- virtual void setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData *);
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &);
};
class SimpleObjectWithCustomParser : public QObject
@@ -1144,8 +1146,8 @@ private:
class SimpleObjectCustomParser : public QQmlCustomParser
{
- virtual QByteArray compile(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &bindings);
- virtual void setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData *);
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &);
};
class RootObjectInCreationTester : public QObject
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 95d6eb9262..e77c15b79a 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -2358,7 +2358,8 @@ void tst_qqmllanguage::basicRemote()
QFETCH(QString, type);
QFETCH(QString, error);
- TestHTTPServer server(14447);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14447), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine, url);
@@ -2402,7 +2403,8 @@ void tst_qqmllanguage::importsRemote()
QFETCH(QString, type);
QFETCH(QString, error);
- TestHTTPServer server(14447);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14447), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
testType(qml,type,error);
@@ -2494,7 +2496,8 @@ void tst_qqmllanguage::importsInstalledRemote()
QFETCH(QString, type);
QFETCH(QString, error);
- TestHTTPServer server(14447);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14447), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QString serverdir = "http://127.0.0.1:14447/lib/";
@@ -2560,7 +2563,8 @@ void tst_qqmllanguage::importsPath()
QFETCH(QString, qml);
QFETCH(QString, value);
- TestHTTPServer server(14447);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14447), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
engine.setImportPathList(QStringList(defaultImportPathList) << importPath);
@@ -3136,7 +3140,8 @@ void tst_qqmllanguage::registeredCompositeType()
// QTBUG-18268
void tst_qqmllanguage::remoteLoadCrash()
{
- TestHTTPServer server(14448);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14448), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine);
@@ -3626,7 +3631,8 @@ void tst_qqmllanguage::compositeSingletonQmlDirError()
// Load a remote composite singleton type via qmldir that defines the type as a singleton
void tst_qqmllanguage::compositeSingletonRemote()
{
- TestHTTPServer server(14447);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14447), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine, testFile("singletonTest15.qml"));
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index b37f0e3d26..ede80b355a 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -353,12 +353,12 @@ void tst_qqmllistmodel::dynamic_i18n_data()
QTest::newRow("qsTr")
<< QString::fromUtf8("ListElement { foo: qsTr(\"test\") }")
<< QVariant(QString::fromUtf8("test"))
- << QString("ListElement: cannot use script for property value");
+ << QString();
QTest::newRow("qsTrId")
<< "ListElement { foo: qsTrId(\"qtn_test\") }"
<< QVariant(QString("qtn_test"))
- << QString("ListElement: cannot use script for property value");
+ << QString();
}
void tst_qqmllistmodel::dynamic_i18n()
diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
index 15be1fdbc0..1861b37bea 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
@@ -247,8 +247,8 @@ void tst_qqmlmoduleplugin::importPluginWithQmlFile()
void tst_qqmlmoduleplugin::remoteImportWithQuotedUrl()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(m_dataImportsDirectory);
QQmlEngine engine;
@@ -268,8 +268,8 @@ void tst_qqmlmoduleplugin::remoteImportWithQuotedUrl()
void tst_qqmlmoduleplugin::remoteImportWithUnquotedUri()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(m_dataImportsDirectory);
QQmlEngine engine;
diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
index 17becb3714..e1ccde2c42 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
+++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
@@ -240,13 +240,12 @@ void tst_qqmlxmlhttprequest::open()
QFETCH(QString, url);
QFETCH(bool, remote);
- QScopedPointer<TestHTTPServer> server; // ensure deletion in case test fails
+ TestHTTPServer server;
if (remote) {
- server.reset(new TestHTTPServer(SERVER_PORT));
- QVERIFY(server->isValid());
- QVERIFY(server->wait(testFileUrl("open_network.expect"),
- testFileUrl("open_network.reply"),
- testFileUrl("testdocument.html")));
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
+ QVERIFY(server.wait(testFileUrl("open_network.expect"),
+ testFileUrl("open_network.reply"),
+ testFileUrl("testdocument.html")));
}
QQmlComponent component(&engine, qmlFile);
@@ -322,8 +321,8 @@ void tst_qqmlxmlhttprequest::open_arg_count()
// Test valid setRequestHeader() calls
void tst_qqmlxmlhttprequest::setRequestHeader()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("setRequestHeader.expect"),
testFileUrl("setRequestHeader.reply"),
testFileUrl("testdocument.html")));
@@ -340,8 +339,8 @@ void tst_qqmlxmlhttprequest::setRequestHeader()
// Test valid setRequestHeader() calls with different header cases
void tst_qqmlxmlhttprequest::setRequestHeader_caseInsensitive()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("setRequestHeader.expect"),
testFileUrl("setRequestHeader.reply"),
testFileUrl("testdocument.html")));
@@ -397,8 +396,8 @@ void tst_qqmlxmlhttprequest::setRequestHeader_illegalName()
{
QFETCH(QString, name);
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("open_network.expect"),
testFileUrl("open_network.reply"),
testFileUrl("testdocument.html")));
@@ -423,8 +422,8 @@ void tst_qqmlxmlhttprequest::setRequestHeader_illegalName()
// Test that attempting to set a header after a request is sent throws an exception
void tst_qqmlxmlhttprequest::setRequestHeader_sent()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("open_network.expect"),
testFileUrl("open_network.reply"),
testFileUrl("testdocument.html")));
@@ -475,8 +474,8 @@ void tst_qqmlxmlhttprequest::send_alreadySent()
void tst_qqmlxmlhttprequest::send_ignoreData()
{
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("send_ignoreData_GET.expect"),
testFileUrl("send_ignoreData.reply"),
testFileUrl("testdocument.html")));
@@ -492,8 +491,8 @@ void tst_qqmlxmlhttprequest::send_ignoreData()
}
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("send_ignoreData_HEAD.expect"),
testFileUrl("send_ignoreData.reply"),
QUrl()));
@@ -509,8 +508,8 @@ void tst_qqmlxmlhttprequest::send_ignoreData()
}
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("send_ignoreData_DELETE.expect"),
testFileUrl("send_ignoreData.reply"),
QUrl()));
@@ -532,8 +531,8 @@ void tst_qqmlxmlhttprequest::send_withdata()
QFETCH(QString, file_expected);
QFETCH(QString, file_qml);
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl(file_expected),
testFileUrl("send_data.reply"),
testFileUrl("testdocument.html")));
@@ -602,8 +601,8 @@ void tst_qqmlxmlhttprequest::abort_opened()
// Test abort() aborts in progress send
void tst_qqmlxmlhttprequest::abort()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("abort.expect"),
testFileUrl("abort.reply"),
testFileUrl("testdocument.html")));
@@ -626,8 +625,8 @@ void tst_qqmlxmlhttprequest::getResponseHeader()
{
QQmlEngine engine; // Avoid cookie contamination
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("getResponseHeader.expect"),
testFileUrl("getResponseHeader.reply"),
testFileUrl("testdocument.html")));
@@ -693,8 +692,8 @@ void tst_qqmlxmlhttprequest::getAllResponseHeaders()
{
QQmlEngine engine; // Avoid cookie contamination
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("getResponseHeader.expect"),
testFileUrl("getResponseHeader.reply"),
testFileUrl("testdocument.html")));
@@ -754,8 +753,8 @@ void tst_qqmlxmlhttprequest::status()
QFETCH(QUrl, replyUrl);
QFETCH(int, status);
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("status.expect"),
replyUrl,
testFileUrl("testdocument.html")));
@@ -793,8 +792,8 @@ void tst_qqmlxmlhttprequest::statusText()
QFETCH(QUrl, replyUrl);
QFETCH(QString, statusText);
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("status.expect"),
replyUrl,
testFileUrl("testdocument.html")));
@@ -833,8 +832,8 @@ void tst_qqmlxmlhttprequest::responseText()
QFETCH(QUrl, bodyUrl);
QFETCH(QString, responseText);
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
QVERIFY(server.wait(testFileUrl("status.expect"),
replyUrl,
bodyUrl));
@@ -934,8 +933,8 @@ void tst_qqmlxmlhttprequest::invalidMethodUsage()
void tst_qqmlxmlhttprequest::redirects()
{
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirecttarget.html");
server.serveDirectory(dataDirectory());
@@ -951,8 +950,8 @@ void tst_qqmlxmlhttprequest::redirects()
}
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirectmissing.html");
server.serveDirectory(dataDirectory());
@@ -968,8 +967,8 @@ void tst_qqmlxmlhttprequest::redirects()
}
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirect.html");
server.serveDirectory(dataDirectory());
@@ -1070,8 +1069,8 @@ void tst_qqmlxmlhttprequest::stateChangeCallingContext()
// ensure that we don't crash by attempting to evaluate
// without a valid calling context.
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
QQmlComponent component(&engine, testFileUrl("stateChangeCallingContext.qml"));
diff --git a/tests/auto/qml/v4misc/tst_v4misc.cpp b/tests/auto/qml/v4misc/tst_v4misc.cpp
index 79ccdc9a4b..17f2fed3f9 100644
--- a/tests/auto/qml/v4misc/tst_v4misc.cpp
+++ b/tests/auto/qml/v4misc/tst_v4misc.cpp
@@ -139,7 +139,7 @@ void tst_v4misc::rangeSplitting_3()
interval.validate();
QCOMPARE(interval.end(), 71);
- LifeTimeInterval newInterval = interval.split(64, LifeTimeInterval::Invalid);
+ LifeTimeInterval newInterval = interval.split(64, LifeTimeInterval::InvalidPosition);
interval.validate();
newInterval.validate();
QVERIFY(!newInterval.isValid());
diff --git a/tests/auto/qmltest/item/tst_layerInPositioner.qml b/tests/auto/qmltest/item/tst_layerInPositioner.qml
new file mode 100644
index 0000000000..9144fe1d8f
--- /dev/null
+++ b/tests/auto/qmltest/item/tst_layerInPositioner.qml
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtTest 1.0
+
+Item {
+ id: root;
+ width: 400
+ height: 400
+
+ TestCase {
+ id: testCase
+ name: "transparentForPositioner"
+ when: windowShown
+ function test_endresult() {
+ var image = grabImage(root);
+
+ // Row of red, green, blue and white box inside blue
+ // At 10,10, spanning 10x10 pixels each
+ verify(image.pixel(10, 10) == Qt.rgba(1, 0, 0, 1));
+ verify(image.pixel(20, 10) == Qt.rgba(0, 1, 0, 1));
+ verify(image.pixel(30, 10) == Qt.rgba(0, 0, 1, 1));
+
+ // Column of red, green, blue and white box inside blue
+ // At 10,30, spanning 10x10 pixels each
+ verify(image.pixel(10, 30) == Qt.rgba(1, 0, 0, 1));
+ verify(image.pixel(10, 40) == Qt.rgba(0, 1, 0, 1));
+ verify(image.pixel(10, 50) == Qt.rgba(0, 0, 1, 1));
+
+ // Flow of red, green, blue and white box inside blue
+ // At 30,30, spanning 10x10 pixels each, wrapping after two boxes
+ verify(image.pixel(30, 30) == Qt.rgba(1, 0, 0, 1));
+ verify(image.pixel(40, 30) == Qt.rgba(0, 1, 0, 1));
+ verify(image.pixel(30, 40) == Qt.rgba(0, 0, 1, 1));
+
+ // Flow of red, green, blue and white box inside blue
+ // At 100,10, spanning 10x10 pixels each, wrapping after two boxes
+ verify(image.pixel(60, 10) == Qt.rgba(1, 0, 0, 1));
+ verify(image.pixel(70, 10) == Qt.rgba(0, 1, 0, 1));
+ verify(image.pixel(60, 20) == Qt.rgba(0, 0, 1, 1));
+ }
+ }
+
+ Component {
+ id: greenPassThrough
+ ShaderEffect {
+ fragmentShader:
+ "
+ uniform lowp sampler2D source;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(0, 1, 0, 1);
+ }
+ "
+ }
+ }
+
+ Row {
+ id: theRow
+ x: 10
+ y: 10
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ff0000"
+ layer.enabled: true
+ }
+
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ffffff"
+ layer.enabled: true
+ layer.effect: greenPassThrough
+ }
+
+ Rectangle {
+ id: blueInRow
+ width: 10
+ height: 10
+ color: "#0000ff"
+ }
+ }
+
+ Column {
+ id: theColumn
+ x: 10
+ y: 30
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ff0000"
+ layer.enabled: true
+ }
+
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ffffff"
+ layer.enabled: true
+ layer.effect: greenPassThrough
+ }
+
+ Rectangle {
+ id: blueInColumn
+ width: 10
+ height: 10
+ color: "#0000ff"
+ }
+ }
+
+ Flow {
+ id: theFlow
+ x: 30
+ y: 30
+ width: 20
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ff0000"
+ layer.enabled: true
+ }
+
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ffffff"
+ layer.enabled: true
+ layer.effect: greenPassThrough
+ }
+
+ Rectangle {
+ id: blueInFlow
+ width: 10
+ height: 10
+ color: "#0000ff"
+ }
+ }
+
+ Grid {
+ id: theGrid
+ x: 60
+ y: 10
+ columns: 2
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ff0000"
+ layer.enabled: true
+ }
+
+ Rectangle {
+ width: 10
+ height: 10
+ color: "#ffffff"
+ layer.enabled: true
+ layer.effect: greenPassThrough
+ }
+
+ Rectangle {
+ id: blueInGrid
+ width: 10
+ height: 10
+ color: "#0000ff"
+ }
+ }
+
+}
diff --git a/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml b/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml
new file mode 100644
index 0000000000..4f827bbf33
--- /dev/null
+++ b/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtTest 1.0
+
+Item {
+ id: root;
+ width: 400
+ height: 400
+
+ TestCase {
+ id: testCase
+ name: "item-grabber"
+ when: imageOnDisk.ready && imageOnDiskSmall.ready && imageInCache.ready && imageInCacheSmall.ready
+ function test_endresult() {
+ var image = grabImage(root);
+
+ // imageOnDisk at (0, 0) - (100x100)
+ compare(imageOnDisk.width, 100);
+ compare(imageOnDisk.height, 100);
+ verify(image.pixel(0, 0) === Qt.rgba(1, 0, 0, 1)); // Use verify because compare doesn't support colors (QTBUG-34878)
+ verify(image.pixel(99, 99) === Qt.rgba(0, 0, 1, 1));
+
+ // imageOnDiskSmall at (100, 0) - 50x50
+ compare(imageOnDiskSmall.width, 50);
+ compare(imageOnDiskSmall.height, 50);
+ verify(image.pixel(100, 0) === Qt.rgba(1, 0, 0, 1));
+ verify(image.pixel(149, 49) === Qt.rgba(0, 0, 1, 1));
+
+ // imageInCache at (0, 100) - 100x100
+ compare(imageInCache.width, 100);
+ compare(imageInCache.height, 100);
+ verify(image.pixel(0, 100) === Qt.rgba(1, 0, 0, 1));
+ verify(image.pixel(99, 199) === Qt.rgba(0, 0, 1, 1));
+
+ // imageInCacheSmall at (100, 100) - 50x50
+ compare(imageInCacheSmall.width, 50);
+ compare(imageInCacheSmall.height, 50);
+ verify(image.pixel(100, 100) === Qt.rgba(1, 0, 0, 1));
+ verify(image.pixel(149, 149) === Qt.rgba(0, 0, 1, 1));
+
+ // After all that has been going on, it should only have been called that one time..
+ compare(imageOnDisk.callCount, 1);
+ }
+
+ onWindowShownChanged: {
+ box.grabToImage(imageOnDisk.handleGrab);
+ box.grabToImage(imageOnDiskSmall.handleGrab, Qt.size(50, 50));
+ box.grabToImage(imageInCache.handleGrab);
+ box.grabToImage(imageInCacheSmall.handleGrab, Qt.size(50, 50));
+ }
+
+ }
+
+ Rectangle {
+ id: box
+ width: 100
+ height: 100
+ color: "red";
+
+ visible: false
+
+ Rectangle {
+ anchors.bottom: parent.bottom;
+ anchors.right: parent.right;
+ width: 10
+ height: 10
+ color: "blue";
+ }
+ }
+
+ Image {
+ id: imageOnDisk
+ x: 0
+ y: 0
+ property int callCount: 0;
+ property bool ready: false;
+ function handleGrab(result) {
+ if (!result.saveToFile("image.png"))
+ print("Error: Failed to save image to disk...");
+ source = "image.png";
+ ready = true;
+ ++callCount;
+ }
+ }
+
+ Image {
+ id: imageOnDiskSmall
+ x: 100
+ y: 0
+ property bool ready: false;
+ function handleGrab(result) {
+ if (!result.saveToFile("image_small.png"))
+ print("Error: Failed to save image to disk...");
+ source = "image_small.png";
+ ready = true;
+ }
+ }
+
+ Image {
+ id: imageInCache
+ x: 0
+ y: 100
+ property bool ready: false;
+ function handleGrab(result) {
+ source = result.url;
+ ready = true;
+ }
+ }
+
+ Image {
+ id: imageInCacheSmall
+ x: 100
+ y: 100
+ property bool ready: false;
+ function handleGrab(result) {
+ source = result.url;
+ ready = true;
+ }
+ }
+}
diff --git a/tests/auto/qmltest/shadersource/tst_DynamicallyCreated.qml b/tests/auto/qmltest/shadersource/tst_DynamicallyCreated.qml
new file mode 100644
index 0000000000..ba0289fadc
--- /dev/null
+++ b/tests/auto/qmltest/shadersource/tst_DynamicallyCreated.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Window 2.0
+import QtTest 1.0
+
+Item {
+ width: 100
+ height: 100
+
+ Window {
+ id: win
+
+ width: 100
+ height: 100
+
+ property bool rendered: false;
+ visible: true
+
+ title: "QML window"
+
+ onFrameSwapped: {
+ if (shaderSource.sourceItem) {
+ rendered = true;
+ } else {
+ var com = Qt.createQmlObject('import QtQuick 2.2; Rectangle { color: "red"; width: 100; height: 100 }', win);
+ shaderSource.sourceItem = com;
+ }
+ }
+
+ ShaderEffectSource {
+ id: shaderSource
+ }
+
+ }
+
+ TestCase {
+ when: win.rendered;
+ name: "shadersource-dynamic-sourceobject"
+ function test_endresult() {
+ var image = grabImage(shaderSource);
+ compare(image.pixel(0, 0), Qt.rgba(1, 0, 0, 1));
+ }
+ }
+}
diff --git a/tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml b/tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml
new file mode 100644
index 0000000000..d9959d7fad
--- /dev/null
+++ b/tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Window 2.0
+
+import QtTest 1.0
+
+Item {
+ Rectangle {
+ id: box
+ color: "red"
+ }
+
+ Window {
+ id: childWindow
+
+ width: 100
+ height: 100
+
+ property bool rendered: false;
+ visible: true
+ onFrameSwapped: rendered = true;
+
+ ShaderEffectSource {
+ id: theSource
+ sourceItem: box
+ }
+
+ ShaderEffect {
+ property variant source: theSource;
+ anchors.fill: parent
+ }
+ }
+
+ TestCase {
+ name: "shadersource-from-other-window"
+ when: childWindow.isRendered
+ function test_endresult() {
+ verify(true); // that we got here without problems...
+ }
+ }
+}
diff --git a/tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml b/tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml
new file mode 100644
index 0000000000..436705befc
--- /dev/null
+++ b/tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Window 2.0
+
+import QtTest 1.0
+
+Item {
+ Rectangle {
+ id: box
+ color: "red"
+ }
+
+ ShaderEffectSource {
+ id: theSource
+ sourceItem: box
+ }
+
+ Window {
+ id: childWindow
+
+ width: 100
+ height: 100
+
+ property bool rendered: false;
+ visible: true
+ onFrameSwapped: rendered = true;
+
+ ShaderEffect {
+ property variant source: theSource;
+ anchors.fill: parent
+ }
+ }
+
+ TestCase {
+ name: "shadersource-from-other-window"
+ when: childWindow.isRendered
+ function test_endresult() {
+ verify(true); // that we got here without problems...
+ }
+ }
+}
diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp
index 662e78ef6c..212337957e 100644
--- a/tests/auto/quick/nodes/tst_nodestest.cpp
+++ b/tests/auto/quick/nodes/tst_nodestest.cpp
@@ -52,6 +52,8 @@
#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/qsgsimplerectnode.h>
+#include <QtQuick/qsgsimpletexturenode.h>
+#include <QtQuick/private/qsgtexture_p.h>
class NodesTest : public QObject
{
@@ -74,6 +76,8 @@ private Q_SLOTS:
void isBlockedCheck();
+ void textureNodeTextureOwnership();
+
private:
QOffscreenSurface *surface;
QOpenGLContext *context;
@@ -259,6 +263,32 @@ void NodesTest::isBlockedCheck()
QVERIFY(!updater.isNodeBlocked(node, &root));
}
+void NodesTest::textureNodeTextureOwnership()
+{
+ { // Check that it is not deleted by default
+ QPointer<QSGTexture> texture(new QSGPlainTexture());
+
+ QSGSimpleTextureNode *tn = new QSGSimpleTextureNode();
+ QVERIFY(!tn->ownsTexture());
+
+ tn->setTexture(texture);
+ delete tn;
+ QVERIFY(!texture.isNull());
+ }
+
+ { // Check that it is deleted when we so desire
+ QPointer<QSGTexture> texture(new QSGPlainTexture());
+
+ QSGSimpleTextureNode *tn = new QSGSimpleTextureNode();
+ tn->setOwnsTexture(true);
+ QVERIFY(tn->ownsTexture());
+
+ tn->setTexture(texture);
+ delete tn;
+ QVERIFY(texture.isNull());
+ }
+}
+
QTEST_MAIN(NodesTest);
#include "tst_nodestest.moc"
diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
index d10963b579..49bbb3a4c5 100644
--- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
+++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
@@ -259,8 +259,8 @@ void tst_qquickanimatedimage::remote()
QFETCH(QString, fileName);
QFETCH(bool, paused);
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
@@ -324,8 +324,8 @@ void tst_qquickanimatedimage::invalidSource()
void tst_qquickanimatedimage::sourceSizeChanges()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
@@ -390,8 +390,8 @@ void tst_qquickanimatedimage::sourceSizeChanges()
void tst_qquickanimatedimage::qtbug_16520()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
@@ -413,8 +413,8 @@ void tst_qquickanimatedimage::qtbug_16520()
void tst_qquickanimatedimage::progressAndStatusChanges()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
index dfcef43a7e..0993d03ee4 100644
--- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
+++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
@@ -60,6 +60,7 @@ private slots:
void state();
void layoutDirection();
void inputMethod();
+ void cleanup();
private:
QQmlEngine engine;
@@ -69,6 +70,14 @@ tst_qquickapplication::tst_qquickapplication()
{
}
+void tst_qquickapplication::cleanup()
+{
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
+ QTest::waitForEvents();
+ }
+}
+
void tst_qquickapplication::active()
{
QQmlComponent component(&engine);
@@ -98,12 +107,19 @@ void tst_qquickapplication::active()
QVERIFY(item->property("active").toBool());
QVERIFY(item->property("active2").toBool());
- // not active again
QWindowSystemInterface::handleWindowActivated(0);
+#ifdef Q_OS_OSX
+ // OS X has the concept of "reactivation"
+ QTRY_VERIFY(QGuiApplication::focusWindow() != &window);
+ QVERIFY(item->property("active").toBool());
+ QVERIFY(item->property("active2").toBool());
+#else
+ // not active again
QTRY_VERIFY(QGuiApplication::focusWindow() != &window);
QVERIFY(!item->property("active").toBool());
QVERIFY(!item->property("active2").toBool());
+#endif
}
void tst_qquickapplication::state()
@@ -117,6 +133,7 @@ void tst_qquickapplication::state()
" target: Qt.application; "
" onStateChanged: state2 = Qt.application.state; "
" } "
+ " Component.onCompleted: state2 = Qt.application.state; "
"}", QUrl::fromLocalFile(""));
QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
QVERIFY(item);
diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
index 4e7b6522dd..c02a5c7a87 100644
--- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
+++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
@@ -143,11 +143,10 @@ void tst_qquickborderimage::imageSource()
QFETCH(bool, remote);
QFETCH(QString, error);
- TestHTTPServer *server = 0;
+ TestHTTPServer server;
if (remote) {
- server = new TestHTTPServer(SERVER_PORT);
- QVERIFY(server->isValid());
- server->serveDirectory(dataDirectory());
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
+ server.serveDirectory(dataDirectory());
}
if (!error.isEmpty())
@@ -177,7 +176,6 @@ void tst_qquickborderimage::imageSource()
}
delete obj;
- delete server;
}
void tst_qquickborderimage::clearSource()
@@ -292,11 +290,11 @@ void tst_qquickborderimage::sciSource()
QFETCH(bool, valid);
bool remote = source.startsWith("http");
- TestHTTPServer *server = 0;
+
+ TestHTTPServer server;
if (remote) {
- server = new TestHTTPServer(SERVER_PORT);
- QVERIFY(server->isValid());
- server->serveDirectory(dataDirectory());
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
+ server.serveDirectory(dataDirectory());
}
QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\"; width: 300; height: 300 }";
@@ -325,7 +323,6 @@ void tst_qquickborderimage::sciSource()
}
delete obj;
- delete server;
}
void tst_qquickborderimage::sciSource_data()
@@ -435,11 +432,10 @@ void tst_qquickborderimage::statusChanges()
QFETCH(bool, remote);
QFETCH(QQuickImageBase::Status, finalStatus);
- TestHTTPServer *server = 0;
+ TestHTTPServer server;
if (remote) {
- server = new TestHTTPServer(SERVER_PORT);
- QVERIFY(server->isValid());
- server->serveDirectory(dataDirectory(), TestHTTPServer::Delay);
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
+ server.serveDirectory(dataDirectory());
}
QString componentStr = "import QtQuick 2.0\nBorderImage { width: 300; height: 300 }";
@@ -452,18 +448,17 @@ void tst_qquickborderimage::statusChanges()
QVERIFY(obj != 0);
obj->setSource(source);
if (remote)
- server->sendDelayedItem();
+ server.sendDelayedItem();
QTRY_VERIFY(obj->status() == finalStatus);
QCOMPARE(spy.count(), emissions);
delete obj;
- delete server;
}
void tst_qquickborderimage::sourceSizeChanges()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
@@ -528,8 +523,8 @@ void tst_qquickborderimage::sourceSizeChanges()
void tst_qquickborderimage::progressAndStatusChanges()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
diff --git a/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp b/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp
index 15282d4b02..410220899a 100644
--- a/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp
+++ b/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp
@@ -416,7 +416,7 @@ void tst_QQuickDrag::drop()
QCOMPARE(evaluate<bool>(item, "dragActive"), true);
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget));
- QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
innerTarget.reset(); outerTarget.reset();
@@ -425,7 +425,7 @@ void tst_QQuickDrag::drop()
QCOMPARE(evaluate<bool>(item, "dragActive"), false);
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget));
- QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1);
innerTarget.reset(); outerTarget.reset();
@@ -434,24 +434,13 @@ void tst_QQuickDrag::drop()
QCOMPARE(evaluate<bool>(item, "dragActive"), true);
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget));
- QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
- // Inner target declines the drop so it is propagated to the outer target.
- innerTarget.accept = false;
-
- innerTarget.reset(); outerTarget.reset();
- QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.CopyAction"), true);
- QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
- QCOMPARE(evaluate<bool>(item, "dragActive"), false);
- QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
- QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
- QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1);
- QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1);
-
+ evaluate<void>(item, "Drag.active = false");
// Inner target doesn't accept enter so drop goes directly to outer.
- innerTarget.accept = true;
+ innerTarget.accept = false;
innerTarget.setFlags(QQuickItem::Flags());
innerTarget.reset(); outerTarget.reset();
@@ -584,10 +573,9 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&rightTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&rightTarget));
- QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
- QCOMPARE(outerTarget.position.x(), qreal(75)); QCOMPARE(outerTarget.position.y(), qreal(50));
QCOMPARE(rightTarget.position.x(), qreal(5)); QCOMPARE(rightTarget.position.y(), qreal(15));
// Move into the left target.
@@ -596,10 +584,9 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&leftTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&leftTarget));
- QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(leftTarget .enterEvents, 1); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 1); QCOMPARE(rightTarget.moveEvents, 0);
- QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50));
QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(15));
// Move within the left target.
diff --git a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
index b65e766190..375613e3c7 100644
--- a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
+++ b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
@@ -84,6 +84,7 @@ private slots:
void position_external();
void drop_internal();
// void drop_external();
+ void competingDrags();
void simultaneousDrags();
private:
@@ -767,6 +768,50 @@ void tst_QQuickDropArea::drop_internal()
//{
//}
+void tst_QQuickDropArea::competingDrags()
+{
+ QQuickWindow window;
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "width: 100; height: 100\n"
+ "objectName: \"dropArea1\"\n"
+ "property string statuslol\n"
+ "onEntered: { statuslol = 'parent' }\n"
+ "DropArea {\n"
+ "objectName: \"dropArea2\"\n"
+ "width: 100; height: 100\n"
+ "property bool acceptsEnters: true\n"
+ "onEntered: { parent.statuslol = 'son'; drag.accepted = acceptsEnters; }\n"
+ "}\n"
+ "Item {\n"
+ "objectName: \"dragItem\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}\n"
+ "}\n", QUrl());
+
+ QScopedPointer<QObject> object(component.create());
+ QQuickItem *dropArea1 = qobject_cast<QQuickItem *>(object.data());
+ QVERIFY(dropArea1);
+ dropArea1->setParentItem(window.contentItem());
+
+ QQuickItem *dropArea2 = dropArea1->findChild<QQuickItem *>("dropArea2");
+ QVERIFY(dropArea2);
+
+ QQuickItem *dragItem = dropArea1->findChild<QQuickItem *>("dragItem");
+ QVERIFY(dragItem);
+
+ QCOMPARE(evaluate<QString>(dropArea1, "statuslol"), QStringLiteral(""));
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<QString>(dropArea1, "statuslol"), QStringLiteral("son"));
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dropArea2, "acceptsEnters = false");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<QString>(dropArea1, "statuslol"), QStringLiteral("parent"));
+}
+
void tst_QQuickDropArea::simultaneousDrags()
{
QQuickWindow window;
@@ -777,6 +822,7 @@ void tst_QQuickDropArea::simultaneousDrags()
"property int enterEvents: 0\n"
"property int exitEvents: 0\n"
"width: 100; height: 100\n"
+ "objectName: \"dropArea1\"\n"
"keys: [\"red\", \"text/x-red\"]\n"
"onEntered: {++enterEvents}\n"
"onExited: {++exitEvents}\n"
@@ -827,8 +873,8 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dragItem1, "Drag.active = true");
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
@@ -837,32 +883,33 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dragItem2, "Drag.active = true");
+ //DropArea discards events if already contains something being dragged in
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
evaluate<void>(dragItem2, "Drag.active = false");
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
evaluate<void>(dragItem2, "Drag.active = true");
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
evaluate<void>(dragItem1, "Drag.active = false");
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
@@ -873,7 +920,7 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dragItem2, "Drag.active = false");
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
@@ -882,8 +929,8 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dragItem1, "Drag.active = true");
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
@@ -892,32 +939,33 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction);
+ //Same as in the first case, dropArea2 already contains a drag, dropArea1 will get the event
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
QWindowSystemInterface::handleDrag(&alternateWindow, &data, QPoint(50, 50), Qt::CopyAction);
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction);
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
evaluate<void>(dragItem1, "Drag.active = false");
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
@@ -928,7 +976,7 @@ void tst_QQuickDropArea::simultaneousDrags()
QWindowSystemInterface::handleDrag(&alternateWindow, &data, QPoint(50, 50), Qt::CopyAction);
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
@@ -937,8 +985,8 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction);
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
@@ -948,31 +996,31 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
evaluate<void>(dragItem2, "Drag.active = true");
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
evaluate<void>(dragItem2, "Drag.active = false");
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
evaluate<void>(dragItem2, "Drag.active = true");
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
QWindowSystemInterface::handleDrag(&alternateWindow, &data, QPoint(50, 50), Qt::CopyAction);
- QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
- QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
@@ -983,7 +1031,7 @@ void tst_QQuickDropArea::simultaneousDrags()
evaluate<void>(dragItem2, "Drag.active = false");
QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
- QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 8ab86bf2d3..7cc3350b05 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -100,7 +100,7 @@ private slots:
void pressDelayWithLoader();
private:
- void flickWithTouch(QWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
+ void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
QQmlEngine engine;
};
@@ -1349,20 +1349,18 @@ void tst_qquickflickable::flickTwiceUsingTouches()
QTRY_VERIFY(contentYAfterSecondFlick > (contentYAfterFirstFlick + 80.0f));
}
-void tst_qquickflickable::flickWithTouch(QWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to)
+void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to)
{
- QTest::touchEvent(window, touchDevice)
- .press(0, from, window);
- QTest::qWait(1);
+ QTest::touchEvent(window, touchDevice).press(0, from, window);
+ QQuickTouchUtils::flush(window);
+
QPoint diff = to - from;
for (int i = 1; i <= 8; ++i) {
- QTest::touchEvent(window, touchDevice)
- .move(0, from + i*diff/8, window);
- QTest::qWait(1);
+ QTest::touchEvent(window, touchDevice).move(0, from + i*diff/8, window);
+ QQuickTouchUtils::flush(window);
}
- QTest::touchEvent(window, touchDevice)
- .release(0, to, window);
- QTest::qWait(1);
+ QTest::touchEvent(window, touchDevice).release(0, to, window);
+ QQuickTouchUtils::flush(window);
}
void tst_qquickflickable::nestedStopAtBounds_data()
diff --git a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp
index bcb496eab7..5c2bbf1650 100644
--- a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp
+++ b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp
@@ -75,8 +75,7 @@ private:
TestHTTPServer server;
};
-tst_qquickfontloader::tst_qquickfontloader() :
- server(SERVER_PORT)
+tst_qquickfontloader::tst_qquickfontloader()
{
}
@@ -84,7 +83,7 @@ void tst_qquickfontloader::initTestCase()
{
QQmlDataTest::initTestCase();
server.serveDirectory(dataDirectory());
- QVERIFY(server.isValid());
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
}
void tst_qquickfontloader::noFont()
diff --git a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp
index b7b58c6d3d..35a01b33ba 100644
--- a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp
+++ b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp
@@ -45,6 +45,7 @@
#include <QtQuick/qquickview.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglframebufferobject.h>
+#include <QtGui/qopenglfunctions.h>
#include <QtQuick/QQuickFramebufferObject>
@@ -62,7 +63,7 @@ struct FrameInfo {
QSize fboSize;
} frameInfo;
-class ColorRenderer : public QQuickFramebufferObject::Renderer
+class ColorRenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions
{
public:
void render();
@@ -142,6 +143,7 @@ void ColorRenderer::synchronize(QQuickFramebufferObject *item)
QOpenGLFramebufferObject *ColorRenderer::createFramebufferObject(const QSize &size)
{
+ initializeOpenGLFunctions();
frameInfo.createFBOCount++;
QOpenGLFramebufferObjectFormat format;
if (msaa)
diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
index 0e012c5c6a..7951cb07cf 100644
--- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp
+++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
@@ -177,9 +177,9 @@ void tst_qquickimage::imageSource()
QFETCH(bool, cache);
QFETCH(QString, error);
- TestHTTPServer server(SERVER_PORT);
+ TestHTTPServer server;
if (remote) {
- QVERIFY(server.isValid());
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png");
}
@@ -529,8 +529,8 @@ void tst_qquickimage::noLoading()
{
qRegisterMetaType<QQuickImageBase::Status>();
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png");
@@ -690,8 +690,8 @@ void tst_qquickimage::nullPixmapPaint()
void tst_qquickimage::imageCrash_QTBUG_22125()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
{
@@ -761,8 +761,8 @@ void tst_qquickimage::sourceSize()
void tst_qquickimage::sourceSizeChanges()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
@@ -827,8 +827,8 @@ void tst_qquickimage::sourceSizeChanges()
void tst_qquickimage::progressAndStatusChanges()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14449), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlEngine engine;
@@ -935,8 +935,8 @@ void tst_qquickimage::correctStatus()
void tst_qquickimage::highdpi()
{
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QString componentStr = "import QtQuick 2.0\nImage { source: srcImage ; }";
diff --git a/tests/auto/quick/qquickitem/qquickitem.pro b/tests/auto/quick/qquickitem/qquickitem.pro
index d4bd0874d8..1d8ae0148b 100644
--- a/tests/auto/quick/qquickitem/qquickitem.pro
+++ b/tests/auto/quick/qquickitem/qquickitem.pro
@@ -3,6 +3,7 @@ TARGET = tst_qquickitem
SOURCES += tst_qquickitem.cpp
include (../../shared/util.pri)
+include (../shared/util.pri)
macx:CONFIG -= app_bundle
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 2db510a69e..40327b0666 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -51,6 +51,7 @@
#include <QTimer>
#include <QQmlEngine>
#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
class TestItem : public QQuickItem
{
@@ -1313,6 +1314,7 @@ void tst_qquickitem::touchEventAcceptIgnore()
item->touchEventReached = false;
bool accepted = window.event(&event);
+ QQuickTouchUtils::flush(&window);
QVERIFY(item->touchEventReached);
@@ -1336,6 +1338,7 @@ void tst_qquickitem::touchEventAcceptIgnore()
item->touchEventReached = false;
bool accepted = window.event(&event);
+ QQuickTouchUtils::flush(&window);
QCOMPARE(item->touchEventReached, itemSupportsTouch);
@@ -1359,6 +1362,7 @@ void tst_qquickitem::touchEventAcceptIgnore()
item->touchEventReached = false;
bool accepted = window.event(&event);
+ QQuickTouchUtils::flush(&window);
QCOMPARE(item->touchEventReached, itemSupportsTouch);
diff --git a/tests/auto/quick/qquickitem2/data/grabToImage.qml b/tests/auto/quick/qquickitem2/data/grabToImage.qml
new file mode 100644
index 0000000000..9f25210ee2
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/grabToImage.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+ Rectangle {
+ objectName: "myItem";
+ width: 100
+ height: 100
+ color: "red"
+ Rectangle {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ width: 10
+ height: 10
+ color: "blue"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index bcfafac93b..e7f0adb24d 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -43,6 +43,7 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQml/qqmlcontext.h>
+#include <QtQuick/qquickitemgrabresult.h>
#include <QtQuick/qquickview.h>
#include <QtGui/private/qinputmethod_p.h>
#include <QtQuick/private/qquickrectangle_p.h>
@@ -91,6 +92,7 @@ private slots:
void keyNavigation_RightToLeft();
void keyNavigation_skipNotVisible();
void keyNavigation_implicitSetting();
+ void keyNavigation_focusReason();
void layoutMirroring();
void layoutMirroringIllegalParent();
void smooth();
@@ -120,6 +122,8 @@ private slots:
void contains();
void childAt();
+ void grab();
+
private:
QQmlEngine engine;
bool qt_tab_all_widgets() {
@@ -215,6 +219,21 @@ public:
int mKey;
};
+class FocusEventFilter : public QObject
+{
+protected:
+ bool eventFilter(QObject *watched, QEvent *event) {
+ if ((event->type() == QEvent::FocusIn) || (event->type() == QEvent::FocusOut)) {
+ QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
+ lastFocusReason = focusEvent->reason();
+ return false;
+ } else
+ return QObject::eventFilter(watched, event);
+ }
+public:
+ Qt::FocusReason lastFocusReason;
+};
+
QML_DECLARE_TYPE(KeyTestItem);
class HollowTestItem : public QQuickItem
@@ -1961,6 +1980,62 @@ void tst_QQuickItem::keyNavigation_implicitSetting()
delete window;
}
+void tst_QQuickItem::keyNavigation_focusReason()
+{
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(240,320));
+
+ FocusEventFilter focusEventFilter;
+
+ window->setSource(testFileUrl("keynavigationtest.qml"));
+ window->show();
+ window->requestActivate();
+
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ // install event filter on first item
+ QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+ item->installEventFilter(&focusEventFilter);
+
+ //install event filter on second item
+ item = findItem<QQuickItem>(window->rootObject(), "item2");
+ QVERIFY(item);
+ item->installEventFilter(&focusEventFilter);
+
+ //install event filter on third item
+ item = findItem<QQuickItem>(window->rootObject(), "item3");
+ QVERIFY(item);
+ item->installEventFilter(&focusEventFilter);
+
+ //install event filter on last item
+ item = findItem<QQuickItem>(window->rootObject(), "item4");
+ QVERIFY(item);
+ item->installEventFilter(&focusEventFilter);
+
+ // tab
+ QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+ QCOMPARE(focusEventFilter.lastFocusReason, Qt::TabFocusReason);
+
+ // backtab
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+ QCOMPARE(focusEventFilter.lastFocusReason, Qt::BacktabFocusReason);
+
+ // some arbitrary cursor key
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+ QCOMPARE(focusEventFilter.lastFocusReason, Qt::OtherFocusReason);
+
+ delete window;
+}
+
void tst_QQuickItem::smooth()
{
QQmlComponent component(&engine);
@@ -2737,6 +2812,41 @@ void tst_QQuickItem::childAt()
QCOMPARE(parent.childAt(300, 300), static_cast<QQuickItem *>(0));
}
+void tst_QQuickItem::grab()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("grabToImage.qml"));
+ view.show();
+ QTest::qWaitForWindowExposed(&view);
+
+ QQuickItem *root = qobject_cast<QQuickItem *>(view.rootObject());
+ QVERIFY(root);
+ QQuickItem *item = root->findChild<QQuickItem *>("myItem");
+ QVERIFY(item);
+
+ { // Default size (item is 100x100)
+ QSharedPointer<QQuickItemGrabResult> result = item->grabToImage();
+ QSignalSpy spy(result.data(), SIGNAL(ready()));
+ QTRY_VERIFY(spy.size() > 0);
+ QVERIFY(!result->url().isEmpty());
+ QImage image = result->image();
+ QCOMPARE(image.pixel(0, 0), qRgb(255, 0, 0));
+ QCOMPARE(image.pixel(99, 99), qRgb(0, 0, 255));
+ }
+
+ { // Smaller size
+ QSharedPointer<QQuickItemGrabResult> result = item->grabToImage(QSize(50, 50));
+ QVERIFY(!result.isNull());
+ QSignalSpy spy(result.data(), SIGNAL(ready()));
+ QTRY_VERIFY(spy.size() > 0);
+ QVERIFY(!result->url().isEmpty());
+ QImage image = result->image();
+ QCOMPARE(image.pixel(0, 0), qRgb(255, 0, 0));
+ QCOMPARE(image.pixel(49, 49), qRgb(0, 0, 255));
+ }
+
+}
+
QTEST_MAIN(tst_QQuickItem)
diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
index b5980929a6..bd7b89b104 100644
--- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
+++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
@@ -44,6 +44,7 @@
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglfunctions.h>
#include "../../shared/util.h"
@@ -107,13 +108,13 @@ tst_QQuickItemLayer::tst_QQuickItemLayer()
window.create();
context.create();
context.makeCurrent(&window);
- const char *vendor = (const char *)glGetString(GL_VENDOR);
- const char *renderer = (const char *)glGetString(GL_RENDERER);
+ const char *vendor = (const char *)context.functions()->glGetString(GL_VENDOR);
+ const char *renderer = (const char *)context.functions()->glGetString(GL_RENDERER);
m_isMesaSoftwareRasterizer = strcmp(vendor, "Mesa Project") == 0
&& strcmp(renderer, "Software Rasterizer") == 0;
if (m_isMesaSoftwareRasterizer) {
// Expects format: <OpenGL version> Mesa <Mesa version>[-devel] [...]
- const char *version = (const char *)glGetString(GL_VERSION);
+ const char *version = (const char *)context.functions()->glGetString(GL_VERSION);
QList<QByteArray> list = QByteArray(version).split(' ');
if (list.size() >= 3) {
list = list.at(2).split('-').at(0).split('.');
diff --git a/tests/auto/quick/qquicklistview/data/sizeTransitions.qml b/tests/auto/quick/qquicklistview/data/sizeTransitions.qml
new file mode 100644
index 0000000000..6dfc5ee70a
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/sizeTransitions.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Window 2.1
+
+Rectangle {
+ id: root
+ width: 500
+ height: 600
+ property int animationDuration: 10
+ property int itemHeight: 40
+
+ Rectangle {
+ id: sightingsListPanel
+ border.width: 2
+ border.color: "lightgray"
+ y: 200
+ anchors.fill: parent
+ anchors.topMargin: 200
+ anchors.leftMargin: 200
+ ListView {
+ id: list
+ objectName: "list"
+ orientation: topToBottom ? ListView.Vertical : ListView.Horizontal
+ property bool transitionFinished: false
+ property bool scriptActionExecuted : false
+ anchors { fill: parent; margins: parent.border.width; }
+ model: testModel
+ delegate: listDelegate
+ // clip when we have no animation running
+ clip: false
+ add: Transition {
+ id: trans
+ onRunningChanged: {
+ if (!running)
+ list.transitionFinished = true;
+ }
+ SequentialAnimation {
+ ParallelAnimation {
+ NumberAnimation { properties: "x"; from: -100; duration: root.animationDuration }
+ NumberAnimation { properties: "y"; from: -100; duration: root.animationDuration }
+ NumberAnimation { properties: "width"; from: 1; to: list.width; duration: root.animationDuration;}
+ // Commenting out the height animation and it works
+ NumberAnimation { properties: "height"; from: 1; to: root.itemHeight; duration: root.animationDuration }
+ }
+ ScriptAction { script: list.scriptActionExecuted = true;}
+ }
+
+ }
+ }
+ // Delegate for defining a template for an item in the list
+ Component {
+ id: listDelegate
+ Rectangle {
+ id: background
+ width: list.width
+ height: root.itemHeight
+ border.width: 2
+ radius: 3
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 2093265163..b909d14301 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -194,6 +194,9 @@ private slots:
void populateTransitions();
void populateTransitions_data();
+ void sizeTransitions();
+ void sizeTransitions_data();
+
void addTransitions();
void addTransitions_data();
void moveTransitions();
@@ -5800,6 +5803,56 @@ void tst_QQuickListView::populateTransitions_data()
QTest::newRow("empty to start with, no populate") << false << false << false;
}
+
+/*
+ * Tests if the first visible item is not repositioned if the same item
+ * resized + changes position during a transition. The test does not test the
+ * actual position while it is transitioning (since its timing sensitive), but
+ * rather tests if the transition has reached its target state properly.
+ **/
+void tst_QQuickListView::sizeTransitions()
+{
+ QFETCH(bool, topToBottom);
+ QQuickView *window = getView();
+ QQmlContext *ctxt = window->rootContext();
+ QaimModel model;
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("topToBottom", topToBottom);
+ TestObject *testObject = new TestObject;
+ ctxt->setContextProperty("testObject", &model);
+ window->setSource(testFileUrl("sizeTransitions.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+
+ // the following will start the transition
+ model.addItem(QLatin1String("Test"), "");
+
+ // This ensures early failure in case of failure (in which case
+ // transitionFinished == true and scriptActionExecuted == false)
+ QTRY_COMPARE(listview->property("scriptActionExecuted").toBool() ||
+ listview->property("transitionFinished").toBool(), true);
+ QCOMPARE(listview->property("scriptActionExecuted").toBool(), true);
+ QCOMPARE(listview->property("transitionFinished").toBool(), true);
+
+ releaseView(window);
+ delete testObject;
+}
+
+void tst_QQuickListView::sizeTransitions_data()
+{
+ QTest::addColumn<bool>("topToBottom");
+
+ QTest::newRow("TopToBottom")
+ << true;
+
+ QTest::newRow("LeftToRight")
+ << false;
+}
+
void tst_QQuickListView::addTransitions()
{
QFETCH(int, initialItemCount);
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 877bb59613..9ac2663f24 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -446,8 +446,8 @@ void tst_QQuickLoader::noResize()
void tst_QQuickLoader::networkRequestUrl()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine);
@@ -470,8 +470,8 @@ void tst_QQuickLoader::networkRequestUrl()
/* XXX Component waits until all dependencies are loaded. Is this actually possible? */
void tst_QQuickLoader::networkComponent()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
QQmlComponent component(&engine);
@@ -503,8 +503,8 @@ void tst_QQuickLoader::networkComponent()
void tst_QQuickLoader::failNetworkRequest()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
QTest::ignoreMessage(QtWarningMsg, SERVER_ADDR "/IDontExist.qml: File not found");
@@ -718,8 +718,8 @@ void tst_QQuickLoader::initialPropertyValues()
QFETCH(QStringList, propertyNames);
QFETCH(QVariantList, propertyValues);
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory());
foreach (const QString &warning, expectedWarnings)
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index d0a1c18885..ee29ed2075 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -86,6 +86,7 @@ private slots:
void resetDrag();
void dragging_data() { acceptedButton_data(); }
void dragging();
+ void dragSmoothed();
void dragThreshold();
void invalidDrag_data() { rejectedButton_data(); }
void invalidDrag();
@@ -334,6 +335,50 @@ void tst_QQuickMouseArea::dragging()
QCOMPARE(blackRect->y(), 61.0);
}
+void tst_QQuickMouseArea::dragSmoothed()
+{
+ QQuickView window;
+ QByteArray errorMessage;
+ QVERIFY2(initView(window, testFileUrl("dragging.qml"), true, &errorMessage), errorMessage.constData());
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject() != 0);
+
+ QQuickMouseArea *mouseRegion = window.rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+ QQuickDrag *drag = mouseRegion->drag();
+ drag->setThreshold(5);
+
+ mouseRegion->setAcceptedButtons(Qt::LeftButton);
+ QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect");
+ QVERIFY(blackRect != 0);
+ QVERIFY(blackRect == drag->target());
+ QVERIFY(!drag->active());
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 102), 50);
+ QTest::mouseMove(&window, QPoint(100, 106), 50);
+ QTest::mouseMove(&window, QPoint(100, 122), 50);
+ QTRY_COMPARE(blackRect->x(), 50.0);
+ QTRY_COMPARE(blackRect->y(), 66.0);
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(100,122));
+
+ // reset rect position
+ blackRect->setX(50.0);
+ blackRect->setY(50.0);
+
+ // now try with smoothed disabled
+ drag->setSmoothed(false);
+ QVERIFY(!drag->active());
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 102), 50);
+ QTest::mouseMove(&window, QPoint(100, 106), 50);
+ QTest::mouseMove(&window, QPoint(100, 122), 50);
+ QTRY_COMPARE(blackRect->x(), 50.0);
+ QTRY_COMPARE(blackRect->y(), 72.0);
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(100, 122));
+}
void tst_QQuickMouseArea::dragThreshold()
{
diff --git a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
index d3abc198d9..5724a7179e 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
+++ b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
@@ -8,6 +8,7 @@ SOURCES += tst_qquickmultipointtoucharea.cpp
TESTDATA = data/*
include(../../shared/util.pri)
+include(../shared/util.pri)
QT += core-private gui-private qml-private quick-private testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index 1d4932c432..842babddd9 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -48,12 +48,14 @@
#include <QtQuick/qquickview.h>
#include <QtGui/QScreen>
#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
class tst_QQuickMultiPointTouchArea : public QQmlDataTest
{
Q_OBJECT
public:
tst_QQuickMultiPointTouchArea() : device(0) { }
+
private slots:
void initTestCase() {
QQmlDataTest::initTestCase();
@@ -118,6 +120,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).press(1, p2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
@@ -126,6 +129,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
QMetaObject::invokeMethod(area, "clearCounts");
sequence.stationary(0).stationary(1).press(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
@@ -136,6 +140,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
sequence.move(0, p1).move(1, p2).stationary(2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 2);
@@ -146,6 +151,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
p3 += QPoint(10,10);
sequence.release(0, p1).release(1, p2)
.move(2, p3).press(3, p4).press(4, p5).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 1);
@@ -154,6 +160,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
QMetaObject::invokeMethod(area, "clearCounts");
sequence.release(2, p3).release(3, p4).release(4, p5).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
@@ -177,12 +184,14 @@ void tst_QQuickMultiPointTouchArea::release()
QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point1->pressed(), true);
p1 += QPoint(0,10);
sequence.move(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point1->pressed(), true);
QCOMPARE(point1->x(), qreal(20)); QCOMPARE(point1->y(), qreal(110));
@@ -190,6 +199,7 @@ void tst_QQuickMultiPointTouchArea::release()
p1 += QPoint(4,10);
sequence.release(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
//test that a release without a prior move to the release position successfully updates the point's position
QCOMPARE(point1->pressed(), false);
@@ -216,12 +226,14 @@ void tst_QQuickMultiPointTouchArea::reuse()
QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).press(1, p2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point1->pressed(), true);
QCOMPARE(point2->pressed(), true);
QCOMPARE(point3->pressed(), false);
sequence.release(0, p1).stationary(1).press(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
//we shouldn't reuse point 1 yet
QCOMPARE(point1->pressed(), false);
@@ -230,24 +242,28 @@ void tst_QQuickMultiPointTouchArea::reuse()
//back to base state (no touches)
sequence.release(1, p2).release(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point1->pressed(), false);
QCOMPARE(point2->pressed(), false);
QCOMPARE(point3->pressed(), false);
sequence.press(0, p1).press(1, p2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point1->pressed(), true);
QCOMPARE(point2->pressed(), true);
QCOMPARE(point3->pressed(), false);
sequence.release(0, p1).stationary(1).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point1->pressed(), false);
QCOMPARE(point2->pressed(), true);
QCOMPARE(point3->pressed(), false);
sequence.press(4, p4).stationary(1).commit();
+ QQuickTouchUtils::flush(window.data());
//the new touch point should reuse point 1
QCOMPARE(point1->pressed(), true);
@@ -283,6 +299,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), false);
QCOMPARE(point12->pressed(), false);
@@ -291,6 +308,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
QCOMPARE(point23->pressed(), false);
sequence.stationary(0).press(1, p2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -304,6 +322,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
p1 += QPoint(0,10);
p2 += QPoint(5,0);
sequence.move(0, p1).move(1, p2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -315,6 +334,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
sequence.stationary(0).stationary(1).press(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -323,6 +343,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
QCOMPARE(point23->pressed(), false);
sequence.stationary(0).stationary(1).stationary(2).press(3, p4).press(4, p5).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -342,6 +363,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
p4 += QPoint(1,-1);
p5 += QPoint(-7,10);
sequence.move(0, p1).move(1, p2).move(2, p3).move(3, p4).move(4, p5).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -356,6 +378,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
QCOMPARE(point23->x(), qreal(93)); QCOMPARE(point23->y(), qreal(30));
sequence.release(0, p1).release(1, p2).release(2, p3).release(3, p4).release(4, p5).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), false);
QCOMPARE(point12->pressed(), false);
@@ -388,6 +411,7 @@ void tst_QQuickMultiPointTouchArea::nested()
QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), false);
QCOMPARE(point12->pressed(), false);
@@ -396,6 +420,7 @@ void tst_QQuickMultiPointTouchArea::nested()
QCOMPARE(point23->pressed(), false);
sequence.stationary(0).press(1, p2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -409,6 +434,7 @@ void tst_QQuickMultiPointTouchArea::nested()
p1 += QPoint(0,10);
p2 += QPoint(5,0);
sequence.move(0, p1).move(1, p2).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -420,6 +446,7 @@ void tst_QQuickMultiPointTouchArea::nested()
QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
sequence.stationary(0).stationary(1).press(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -435,6 +462,7 @@ void tst_QQuickMultiPointTouchArea::nested()
QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
sequence.stationary(0).stationary(1).stationary(2).press(3, QPoint(80,180)).press(4, QPoint(100,180)).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -455,6 +483,7 @@ void tst_QQuickMultiPointTouchArea::nested()
p2 += QPoint(17,17);
p3 += QPoint(3,0);
sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -472,6 +501,7 @@ void tst_QQuickMultiPointTouchArea::nested()
p2 += QPoint(17,17);
p3 += QPoint(3,0);
sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), false);
QCOMPARE(point12->pressed(), false);
@@ -489,6 +519,7 @@ void tst_QQuickMultiPointTouchArea::nested()
sequence.release(0, p1).release(1, p2).release(2, p3).commit();
sequence.press(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), false);
QCOMPARE(point12->pressed(), false);
@@ -497,11 +528,13 @@ void tst_QQuickMultiPointTouchArea::nested()
QCOMPARE(point23->pressed(), false);
sequence.release(0, p1).commit();
+ QQuickTouchUtils::flush(window.data());
//test with grabbing turned off
window->rootObject()->setProperty("grabInnerArea", false);
sequence.press(0, p1).press(1, p2).press(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -513,6 +546,7 @@ void tst_QQuickMultiPointTouchArea::nested()
p2 -= QPoint(17,17);
p3 -= QPoint(3,0);
sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -530,6 +564,7 @@ void tst_QQuickMultiPointTouchArea::nested()
p2 -= QPoint(17,17);
p3 -= QPoint(3,0);
sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -545,6 +580,7 @@ void tst_QQuickMultiPointTouchArea::nested()
QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
sequence.release(0, p1).release(1, p2).release(2, p3).commit();
+ QQuickTouchUtils::flush(window.data());
}
void tst_QQuickMultiPointTouchArea::inFlickable()
@@ -569,25 +605,30 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
//moving one point vertically
QTest::touchEvent(window.data(), device).press(0, p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
QVERIFY(flickable->contentY() < 0);
QCOMPARE(point11->pressed(), false);
QCOMPARE(point12->pressed(), false);
QTest::touchEvent(window.data(), device).release(0, p1);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window.data());
QTRY_VERIFY(!flickable->isMoving());
@@ -595,6 +636,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
p1 = QPoint(20,100);
QTest::touchEvent(window.data(), device).press(0, p1).press(1, p2);
QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -604,18 +646,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
QVERIFY(flickable->contentY() < 0);
QCOMPARE(point11->pressed(), false);
@@ -625,7 +671,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2);
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window.data());
QTRY_VERIFY(!flickable->isMoving());
@@ -633,6 +679,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
p1 = QPoint(20,100);
p2 = QPoint(40,100);
QTest::touchEvent(window.data(), device).press(0, p1).press(1, p2);
+ QQuickTouchUtils::flush(window.data());
// ensure that mouse events do not fall through to the Flickable
mpta->setMaximumTouchPoints(3);
QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
@@ -643,34 +690,42 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
p1 += QPoint(15,0); p2 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(15,0); p2 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(15,0); p2 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(15,0); p2 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15); p2 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
QTest::mouseMove(window.data(), p1);
+ QQuickTouchUtils::flush(window.data());
QVERIFY(flickable->contentY() == 0);
QCOMPARE(point11->pressed(), true);
@@ -678,7 +733,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2);
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window.data());
}
// test that dragging out of a Flickable containing a MPTA doesn't harm Flickable's state.
@@ -699,28 +754,34 @@ void tst_QQuickMultiPointTouchArea::inFlickable2()
// move point horizontally, out of Flickable area
QTest::touchEvent(window.data(), device).press(0, p1);
+ QQuickTouchUtils::flush(window.data());
QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
p1 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
QTest::mouseMove(window.data(), p1);
QVERIFY(!flickable->isMoving());
QVERIFY(point11->pressed());
QTest::touchEvent(window.data(), device).release(0, p1);
+ QQuickTouchUtils::flush(window.data());
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
QTest::qWait(50);
@@ -729,26 +790,32 @@ void tst_QQuickMultiPointTouchArea::inFlickable2()
// Check that we can still move the Flickable
p1 = QPoint(50,100);
QTest::touchEvent(window.data(), device).press(0, p1);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(point11->pressed(), true);
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
QVERIFY(flickable->contentY() < 0);
QVERIFY(flickable->isMoving());
QCOMPARE(point11->pressed(), true);
QTest::touchEvent(window.data(), device).release(0, p1);
+ QQuickTouchUtils::flush(window.data());
QTest::qWait(50);
QTRY_VERIFY(!flickable->isMoving());
@@ -859,7 +926,9 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
// Touch both, release one, manipulate other touchpoint with mouse
QTest::touchEvent(window.data(), device).press(1, touch1);
+ QQuickTouchUtils::flush(window.data());
QTest::touchEvent(window.data(), device).press(2, touch2);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -867,12 +936,14 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
QTest::touchEvent(window.data(), device).release(1, touch1);
touch1.setY(20);
QTest::mousePress(window.data(), Qt::LeftButton, 0, touch1);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
QCOMPARE(touch2rect->property("y").toInt(), touch2.y());
QTest::touchEvent(window.data(), device).release(2, touch2);
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, touch1);
+ QQuickTouchUtils::flush(window.data());
// Start with mouse, move it, touch second point, move it
QTest::mousePress(window.data(), Qt::LeftButton, 0, touch1);
@@ -882,12 +953,14 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
touch2.setX(60);
QTest::touchEvent(window.data(), device).press(3, touch2);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
QCOMPARE(touch2rect->property("y").toInt(), touch2.y());
touch2.setY(150);
QTest::touchEvent(window.data(), device).move(3, touch2);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -895,6 +968,7 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
// Touch third point - nothing happens
QTest::touchEvent(window.data(), device).press(4, touch3);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -903,7 +977,9 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
// Release all
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, touch1);
QTest::touchEvent(window.data(), device).release(3, touch2);
+ QQuickTouchUtils::flush(window.data());
QTest::touchEvent(window.data(), device).release(4, touch3);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -922,12 +998,14 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
QCOMPARE(touch1rect->property("x").toInt(), mouse1.x());
QCOMPARE(touch1rect->property("y").toInt(), mouse1.y());
QTest::touchEvent(window.data(), device).press(1, touch1);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), mouse1.x());
QCOMPARE(touch1rect->property("y").toInt(), mouse1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch1.x());
QCOMPARE(touch2rect->property("y").toInt(), touch1.y());
QTest::touchEvent(window.data(), device).press(2, touch2).press(3, touch3).press(4, touch4);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), mouse1.x());
QCOMPARE(touch1rect->property("y").toInt(), mouse1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch1.x());
@@ -942,6 +1020,7 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
// Release all
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, mouse1);
QTest::touchEvent(window.data(), device).release(1, touch1).release(2, touch2).release(3, touch3).release(4, touch4);
+ QQuickTouchUtils::flush(window.data());
}
dualmpta->setProperty("mouseEnabled", false);
@@ -964,13 +1043,16 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
QCOMPARE(touch1rect->property("y").toInt(), 10);
QTest::touchEvent(window.data(), device).press(1, touch1);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
touch1.setY(150);
QTest::touchEvent(window.data(), device).move(1, touch1);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QTest::touchEvent(window.data(), device).press(2, touch2);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -979,7 +1061,9 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
// Release all
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, mouse1);
QTest::touchEvent(window.data(), device).release(1, touch1);
+ QQuickTouchUtils::flush(window.data());
QTest::touchEvent(window.data(), device).release(2, touch2);
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -1028,7 +1112,6 @@ void tst_QQuickMultiPointTouchArea::transformedTouchArea_data()
QTest::newRow("3rd point inside")
<< QPoint(140, 260) << QPoint(260, 140) << QPoint(200, 140) << 0 << 0 << 1;
-
QTest::newRow("all points inside")
<< QPoint(200, 140) << QPoint(200, 260) << QPoint(140, 200) << 1 << 2 << 3;
diff --git a/tests/auto/quick/qquickpincharea/qquickpincharea.pro b/tests/auto/quick/qquickpincharea/qquickpincharea.pro
index 970ce48851..fa14afa261 100644
--- a/tests/auto/quick/qquickpincharea/qquickpincharea.pro
+++ b/tests/auto/quick/qquickpincharea/qquickpincharea.pro
@@ -6,6 +6,7 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickpincharea.cpp
include (../../shared/util.pri)
+include (../shared/util.pri)
TESTDATA = data/*
diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
index b9d314b63e..1dbce1b730 100644
--- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
+++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
@@ -48,6 +48,7 @@
#include <QtQuick/qquickview.h>
#include <QtQml/qqmlcontext.h>
#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
class tst_QQuickPinchArea: public QQmlDataTest
{
@@ -232,15 +233,18 @@ void tst_QQuickPinchArea::scale()
{
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
pinchSequence.press(0, p1, window).commit();
+ QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object. Otherwise if we let it
// be destroyed and then start a new sequence, point 0 will default to being
// stationary at 0, 0, and PinchArea will filter out that touchpoint because
// it is outside its bounds.
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(root->property("scale").toReal(), 1.0);
QVERIFY(root->property("pinchActive").toBool());
@@ -248,6 +252,7 @@ void tst_QQuickPinchArea::scale()
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(root->property("scale").toReal(), 1.5);
QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
@@ -260,8 +265,10 @@ void tst_QQuickPinchArea::scale()
{
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(blackRect->scale(), 2.0);
pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
}
QVERIFY(!root->property("pinchActive").toBool());
}
@@ -293,12 +300,15 @@ void tst_QQuickPinchArea::pan()
{
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
pinchSequence.press(0, p1, window).commit();
+ QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object.
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 += QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(root->property("scale").toReal(), 1.0);
QVERIFY(root->property("pinchActive").toBool());
@@ -306,6 +316,7 @@ void tst_QQuickPinchArea::pan()
p1 += QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+ QQuickTouchUtils::flush(window);
}
QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50
@@ -316,11 +327,13 @@ void tst_QQuickPinchArea::pan()
p1 += QPoint(100,100);
p2 += QPoint(100,100);
QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(blackRect->x(), 140.0);
QCOMPARE(blackRect->y(), 160.0);
QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
+ QQuickTouchUtils::flush(window);
QVERIFY(!root->property("pinchActive").toBool());
}
@@ -355,12 +368,15 @@ void tst_QQuickPinchArea::retouch()
{
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
pinchSequence.press(0, p1, window).commit();
+ QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object.
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(root->property("scale").toReal(), 1.0);
QVERIFY(root->property("pinchActive").toBool());
@@ -368,6 +384,7 @@ void tst_QQuickPinchArea::retouch()
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(startedSpy.count(), 1);
@@ -382,6 +399,7 @@ void tst_QQuickPinchArea::retouch()
// Hold down the first finger but release the second one
pinchSequence.stationary(0).release(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(startedSpy.count(), 1);
QCOMPARE(finishedSpy.count(), 0);
@@ -390,9 +408,11 @@ void tst_QQuickPinchArea::retouch()
// Keep holding down the first finger and re-touch the second one, then move them both
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
// Lifting and retouching results in onPinchStarted being called again
QCOMPARE(startedSpy.count(), 2);
@@ -401,6 +421,7 @@ void tst_QQuickPinchArea::retouch()
QCOMPARE(window->rootObject()->property("pointCount").toInt(), 2);
pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QVERIFY(!root->property("pinchActive").toBool());
QCOMPARE(startedSpy.count(), 2);
@@ -456,14 +477,18 @@ void tst_QQuickPinchArea::transformedPinchArea()
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, device);
// start pinch
pinchSequence.press(0, p1, view).commit();
+ QQuickTouchUtils::flush(view);
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object.
pinchSequence.stationary(0).press(1, p2, view).commit();
+ QQuickTouchUtils::flush(view);
pinchSequence.stationary(0).move(1, p2 + QPoint(threshold * 2, 0), view).commit();
+ QQuickTouchUtils::flush(view);
QCOMPARE(pinchArea->property("pinching").toBool(), shouldPinch);
// release pinch
pinchSequence.release(0, p1, view).release(1, p2, view).commit();
+ QQuickTouchUtils::flush(view);
QCOMPARE(pinchArea->property("pinching").toBool(), false);
}
}
diff --git a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
index 75bd468aef..f104154205 100644
--- a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
+++ b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
@@ -59,7 +59,7 @@ class tst_qquickpixmapcache : public QQmlDataTest
{
Q_OBJECT
public:
- tst_qquickpixmapcache() : server(14452) {}
+ tst_qquickpixmapcache() {}
private slots:
void initTestCase();
@@ -116,6 +116,8 @@ void tst_qquickpixmapcache::initTestCase()
{
QQmlDataTest::initTestCase();
+ QVERIFY2(server.listen(14452), qPrintable(server.errorString()));
+
// This avoids a race condition/deadlock bug in network config
// manager when it is accessed by the HTTP server thread before
// anything else. Bug report can be found at:
@@ -379,7 +381,8 @@ void tst_qquickpixmapcache::shrinkcache()
void createNetworkServer()
{
QEventLoop eventLoop;
- TestHTTPServer server(14453);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14453), qPrintable(server.errorString()));
server.serveDirectory(QQmlDataTest::instance()->testFile("http"));
QTimer::singleShot(100, &eventLoop, SLOT(quit()));
eventLoop.exec();
@@ -407,7 +410,8 @@ void tst_qquickpixmapcache::networkCrash()
// QTBUG-22125
void tst_qquickpixmapcache::lockingCrash()
{
- TestHTTPServer server(14453);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(14453), qPrintable(server.errorString()));
server.serveDirectory(testFile("http"), TestHTTPServer::Delay);
{
diff --git a/tests/auto/quick/qquickrepeater/data/invalidContextCrash.qml b/tests/auto/quick/qquickrepeater/data/invalidContextCrash.qml
new file mode 100644
index 0000000000..4a822cf25a
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/invalidContextCrash.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+Item {
+ Repeater {
+ model: badModel
+ delegate: Item {}
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 9fb76f9584..2dc5a65d7d 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -79,6 +79,7 @@ private slots:
void initParent();
void dynamicModelCrash();
void visualItemModelCrash();
+ void invalidContextCrash();
};
class TestObject : public QObject
@@ -744,6 +745,48 @@ void tst_QQuickRepeater::visualItemModelCrash()
delete window;
}
+class BadModel : public QAbstractListModel
+{
+public:
+ ~BadModel()
+ {
+ beginResetModel();
+ endResetModel();
+ }
+
+ QVariant data(const QModelIndex &, int) const { return QVariant(); }
+ int rowCount(const QModelIndex &) const { return 0; }
+};
+
+
+void tst_QQuickRepeater::invalidContextCrash()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("invalidContextCrash.qml"));
+
+ BadModel* model = new BadModel;
+ engine.rootContext()->setContextProperty("badModel", model);
+
+ QScopedPointer<QObject> root(component.create());
+ QCOMPARE(root->children().count(), 1);
+ QObject *repeater = root->children().first();
+
+ // Make sure the model comes first in the child list, so it will be
+ // deleted first and then the repeater. During deletion the QML context
+ // has been deleted already and is invalid.
+ model->setParent(root.data());
+ repeater->setParent(0);
+ repeater->setParent(root.data());
+
+ QCOMPARE(root->children().count(), 2);
+ QVERIFY(root->children().at(0) == model);
+ QVERIFY(root->children().at(1) == repeater);
+
+ // Delete the root object, which will invalidate/delete the QML context
+ // and then delete the child QObjects, which may try to access the context.
+ root.reset(0);
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 0a7c8c9f92..f361c25a05 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -2034,7 +2034,8 @@ void tst_qquicktext::embeddedImages()
QFETCH(QUrl, qmlfile);
QFETCH(QString, error);
- TestHTTPServer server(SERVER_PORT);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(testFile("http"));
if (!error.isEmpty())
@@ -2772,7 +2773,8 @@ void tst_qquicktext::imgTagsBaseUrl()
QFETCH(QUrl, contextUrl);
QFETCH(qreal, imgHeight);
- TestHTTPServer server(SERVER_PORT);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(testFile(""));
QByteArray baseUrlFragment;
@@ -2941,6 +2943,8 @@ void tst_qquicktext::fontSizeMode()
// Font size reduced to fit within the width of the item.
qreal horizontalFitWidth = myText->contentWidth();
qreal horizontalFitHeight = myText->contentHeight();
+ if (QGuiApplication::platformName() == QStringLiteral("windows"))
+ QEXPECT_FAIL("styled", "QTBUG-39961", Abort);
QVERIFY(horizontalFitWidth <= myText->width() + 2); // rounding
QVERIFY(horizontalFitHeight <= myText->height() + 2);
@@ -3445,6 +3449,8 @@ void tst_qquicktext::multilengthStrings()
myText->setSize(QSizeF(mediumWidth, mediumHeight));
QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ if (QGuiApplication::platformName() == QStringLiteral("windows"))
+ QEXPECT_FAIL("Wrap", "QTBUG-39961", Abort);
QCOMPARE(myText->contentWidth(), mediumWidth);
QCOMPARE(myText->contentHeight(), mediumHeight);
QCOMPARE(myText->truncated(), true);
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 1ffd67cbf1..f8fc4c10da 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -2604,7 +2604,8 @@ void tst_qquicktextedit::cursorDelegate()
void tst_qquicktextedit::remoteCursorDelegate()
{
- TestHTTPServer server(SERVER_PORT);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
QQuickView view;
@@ -2741,7 +2742,8 @@ void tst_qquicktextedit::delegateLoading()
QFETCH(QString, qmlfile);
QFETCH(QString, error);
- TestHTTPServer server(SERVER_PORT);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(testFile("httpfail"), TestHTTPServer::Disconnect);
server.serveDirectory(testFile("httpslow"), TestHTTPServer::Delay);
server.serveDirectory(testFile("http"));
@@ -5215,7 +5217,8 @@ void tst_qquicktextedit::embeddedImages()
QFETCH(QUrl, qmlfile);
QFETCH(QString, error);
- TestHTTPServer server(SERVER_PORT);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(testFile("http"));
if (!error.isEmpty())
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index e125c33a56..fc1be16bc8 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -232,6 +232,8 @@ private slots:
void baselineOffset_data();
void baselineOffset();
+ void ensureVisible();
+
private:
void simulateKey(QWindow *, int key);
@@ -2490,7 +2492,7 @@ void tst_qquicktextinput::copyAndPaste()
QCOMPARE(textInput->selectedText(), QString("Hello world!"));
QCOMPARE(textInput->selectedText().length(), 12);
textInput->setCursorPosition(0);
- QVERIFY(textInput->canPaste());
+ QTRY_VERIFY(textInput->canPaste());
textInput->paste();
QCOMPARE(textInput->text(), QString("Hello world!Hello world!"));
QCOMPARE(textInput->text().length(), 24);
@@ -2544,7 +2546,7 @@ void tst_qquicktextinput::copyAndPaste()
QClipboard *clipboard = QGuiApplication::clipboard();
QVERIFY(clipboard);
clipboard->clear();
- QVERIFY(!textInput->canPaste());
+ QTRY_VERIFY(!textInput->canPaste());
// test that copy functionality is disabled
// when echo mode is set to hide text/password mode
@@ -2612,7 +2614,7 @@ void tst_qquicktextinput::copyAndPasteKeySequence()
QClipboard *clipboard = QGuiApplication::clipboard();
QVERIFY(clipboard);
clipboard->clear();
- QVERIFY(!textInput->canPaste());
+ QTRY_VERIFY(!textInput->canPaste());
// test that copy functionality is disabled
// when echo mode is set to hide text/password mode
@@ -2853,7 +2855,8 @@ void tst_qquicktextinput::cursorDelegate()
void tst_qquicktextinput::remoteCursorDelegate()
{
- TestHTTPServer server(SERVER_PORT);
+ TestHTTPServer server;
+ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
QQuickView view;
@@ -6463,6 +6466,50 @@ void tst_qquicktextinput::baselineOffset()
}
}
+void tst_qquicktextinput::ensureVisible()
+{
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\n TextInput {}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QQuickTextInput *input = qobject_cast<QQuickTextInput *>(object.data());
+ QVERIFY(input);
+
+ input->setWidth(QFontMetrics(input->font()).averageCharWidth() * 3);
+ input->setText("Hello World");
+
+ QTextLayout layout;
+ layout.setText(input->text());
+ layout.setFont(input->font());
+
+ if (!qmlDisableDistanceField()) {
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
+ }
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
+
+ input->ensureVisible(0);
+
+ QCOMPARE(input->boundingRect().x(), qreal(0));
+ QCOMPARE(input->boundingRect().y(), qreal(0));
+ QCOMPARE(input->boundingRect().width(), line.naturalTextWidth() + input->cursorRectangle().width());
+ QCOMPARE(input->boundingRect().height(), line.height());
+
+ QSignalSpy cursorSpy(input, SIGNAL(cursorRectangleChanged()));
+ QVERIFY(cursorSpy.isValid());
+
+ input->ensureVisible(input->length());
+
+ QCOMPARE(cursorSpy.count(), 1);
+
+ QCOMPARE(input->boundingRect().x(), input->width() - line.naturalTextWidth());
+ QCOMPARE(input->boundingRect().y(), qreal(0));
+ QCOMPARE(input->boundingRect().width(), line.naturalTextWidth() + input->cursorRectangle().width());
+ QCOMPARE(input->boundingRect().height(), line.height());
+}
+
QTEST_MAIN(tst_qquicktextinput)
#include "tst_qquicktextinput.moc"
diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro
index 6bce209df9..e95b7dbb10 100644
--- a/tests/auto/quick/qquickwindow/qquickwindow.pro
+++ b/tests/auto/quick/qquickwindow/qquickwindow.pro
@@ -3,6 +3,7 @@ TARGET = tst_qquickwindow
SOURCES += tst_qquickwindow.cpp
include (../../shared/util.pri)
+include(../shared/util.pri)
macx:CONFIG -= app_bundle
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index b8f9102775..17773fcfc4 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -50,6 +50,7 @@
#include <QtQuick/private/qquickloader_p.h>
#include "../../shared/util.h"
#include "../shared/visualtestutil.h"
+#include "../shared/viewtestutil.h"
#include <QSignalSpy>
#include <qpa/qwindowsysteminterface.h>
#include <private/qquickwindow_p.h>
@@ -328,6 +329,7 @@ private slots:
void animationsWhileHidden();
void focusObject();
+ void focusReason();
void ignoreUnhandledMouseEvents();
@@ -362,6 +364,9 @@ private slots:
void contentItemSize();
+ void defaultSurfaceFormat();
+ void glslVersion();
+
private:
QTouchDevice *touchDevice;
QTouchDevice *touchDeviceWithVelocity;
@@ -395,7 +400,7 @@ void tst_qquickwindow::aboutToStopSignal()
window.hide();
- QVERIFY(spy.count() > 0);
+ QTRY_VERIFY(spy.count() > 0);
}
//If the item calls update inside updatePaintNode, it should schedule another sync pass
@@ -522,7 +527,7 @@ void tst_qquickwindow::touchEvent_basic()
// press multiple points
QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window)
.press(1, bottomItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
@@ -533,9 +538,9 @@ void tst_qquickwindow::touchEvent_basic()
// touch point on top item moves to bottom item, but top item should still receive the event
QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
@@ -543,9 +548,9 @@ void tst_qquickwindow::touchEvent_basic()
// touch point on bottom item moves to top item, but bottom item should still receive the event
QTest::touchEvent(window, touchDevice).press(0, bottomItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, touchDevice).move(0, topItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
@@ -553,10 +558,10 @@ void tst_qquickwindow::touchEvent_basic()
// a single stationary press on an item shouldn't cause an event
QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, touchDevice).stationary(0)
.press(1, bottomItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); // received press only, not stationary
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
@@ -568,12 +573,13 @@ void tst_qquickwindow::touchEvent_basic()
// Otherwise you will get an assertion failure:
// ASSERT: "itemForTouchPointId.isEmpty()" in file items/qquickwindow.cpp
QTest::touchEvent(window, touchDevice).release(0, pos.toPoint(), window).release(1, pos.toPoint(), window);
+ QQuickTouchUtils::flush(window);
// move touch point from top item to bottom, and release
QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(),window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, window, Qt::TouchPointReleased,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
@@ -582,12 +588,12 @@ void tst_qquickwindow::touchEvent_basic()
// release while another point is pressed
QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window)
.press(1, bottomItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), window);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), window)
.stationary(1);
- QTest::qWait(50);
+ QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
@@ -835,12 +841,15 @@ void tst_qquickwindow::touchEvent_velocity()
tp.area = QRectF(pos, QSizeF(4, 4));
points << tp;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
points[0].state = Qt::TouchPointMoved;
points[0].area.adjust(5, 5, 5, 5);
QVector2D velocity(1.5, 2.5);
points[0].velocity = velocity;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
- QCoreApplication::processEvents();
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
QCOMPARE(item->touchEventCount, 2);
QCOMPARE(item->lastEvent.touchPoints.count(), 1);
QCOMPARE(item->lastVelocity, velocity);
@@ -852,7 +861,8 @@ void tst_qquickwindow::touchEvent_velocity()
QVector2D transformedVelocity = transformMatrix.mapVector(velocity).toVector2D();
points[0].area.adjust(5, 5, 5, 5);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
- QCoreApplication::processEvents();
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
QCOMPARE(item->lastVelocity, transformedVelocity);
QPoint itemLocalPos = item->mapFromScene(window->mapFromGlobal(points[0].area.center().toPoint())).toPoint();
QPoint itemLocalPosFromEvent = item->lastEvent.touchPoints[0].pos().toPoint();
@@ -860,7 +870,8 @@ void tst_qquickwindow::touchEvent_velocity()
points[0].state = Qt::TouchPointReleased;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
- QCoreApplication::processEvents();
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
delete item;
}
@@ -892,14 +903,19 @@ void tst_qquickwindow::mouseFromTouch_basic()
tp.area = QRectF(pos, QSizeF(4, 4));
points << tp;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
points[0].state = Qt::TouchPointMoved;
points[0].area.adjust(5, 5, 5, 5);
QVector2D velocity(1.5, 2.5);
points[0].velocity = velocity;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
points[0].state = Qt::TouchPointReleased;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
- QCoreApplication::processEvents();
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
// The item should have received a mouse press, move, and release.
QCOMPARE(item->mousePressNum, 1);
@@ -918,16 +934,20 @@ void tst_qquickwindow::mouseFromTouch_basic()
points[0].velocity = velocity;
points[0].area = QRectF(pos, QSizeF(4, 4));
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
points[0].state = Qt::TouchPointMoved;
points[0].area.adjust(5, 5, 5, 5);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
- QCoreApplication::processEvents();
+ QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
QCOMPARE(item->lastMousePos.toPoint(), item->mapFromScene(window->mapFromGlobal(points[0].area.center().toPoint())).toPoint());
QCOMPARE(item->lastVelocityFromMouseMove, transformedVelocity);
points[0].state = Qt::TouchPointReleased;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
QCoreApplication::processEvents();
+ QQuickTouchUtils::flush(window);
delete item;
}
@@ -1275,6 +1295,33 @@ void tst_qquickwindow::focusObject()
QCOMPARE(focusObjectSpy.count(), 3);
}
+void tst_qquickwindow::focusReason()
+{
+ QQuickWindow *window = new QQuickWindow;
+ QScopedPointer<QQuickWindow> cleanup(window);
+ window->resize(200, 200);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickItem *firstItem = new QQuickItem;
+ firstItem->setSize(QSizeF(100, 100));
+ firstItem->setParentItem(window->contentItem());
+
+ QQuickItem *secondItem = new QQuickItem;
+ secondItem->setSize(QSizeF(100, 100));
+ secondItem->setParentItem(window->contentItem());
+
+ firstItem->forceActiveFocus(Qt::OtherFocusReason);
+ QCOMPARE(QQuickWindowPrivate::get(window)->lastFocusReason, Qt::OtherFocusReason);
+
+ secondItem->forceActiveFocus(Qt::TabFocusReason);
+ QCOMPARE(QQuickWindowPrivate::get(window)->lastFocusReason, Qt::TabFocusReason);
+
+ firstItem->forceActiveFocus(Qt::BacktabFocusReason);
+ QCOMPARE(QQuickWindowPrivate::get(window)->lastFocusReason, Qt::BacktabFocusReason);
+
+}
+
void tst_qquickwindow::ignoreUnhandledMouseEvents()
{
QQuickWindow *window = new QQuickWindow;
@@ -1851,6 +1898,79 @@ void tst_qquickwindow::contentItemSize()
QCOMPARE(QSizeF(rect->width(), rect->height()), size);
}
+void tst_qquickwindow::defaultSurfaceFormat()
+{
+ // It is quite difficult to verify anything for real since the resulting format after
+ // surface/context creation can be anything, depending on the platform and drivers,
+ // and many options and settings may fail in various configurations, but test at
+ // least using some harmless settings to check that the global, static format is
+ // taken into account in the requested format.
+
+ QSurfaceFormat savedDefaultFormat = QQuickWindow::defaultFormat();
+
+ // Verify that depth and stencil are set, as they should be, unless they are disabled
+ // via environment variables.
+ QVERIFY(savedDefaultFormat.depthBufferSize() >= 16);
+ QVERIFY(savedDefaultFormat.stencilBufferSize() >= 8);
+
+ QSurfaceFormat format = savedDefaultFormat;
+ format.setSwapInterval(0);
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+ format.setProfile(QSurfaceFormat::CompatibilityProfile);
+ format.setOption(QSurfaceFormat::DebugContext);
+ QQuickWindow::setDefaultFormat(format);
+
+ QQuickWindow window;
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ const QSurfaceFormat reqFmt = window.requestedFormat();
+ QCOMPARE(format.swapInterval(), reqFmt.swapInterval());
+ QCOMPARE(format.redBufferSize(), reqFmt.redBufferSize());
+ QCOMPARE(format.greenBufferSize(), reqFmt.greenBufferSize());
+ QCOMPARE(format.blueBufferSize(), reqFmt.blueBufferSize());
+ QCOMPARE(format.profile(), reqFmt.profile());
+ QCOMPARE(int(format.options()), int(reqFmt.options()));
+
+ QQuickWindow::setDefaultFormat(savedDefaultFormat);
+}
+
+void tst_qquickwindow::glslVersion()
+{
+ QQuickWindow window;
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ // Core profile is never requested by default.
+ QVERIFY(!window.glslIsCoreProfile());
+
+ // Get the format from the context, not the window. The actual OpenGL version and
+ // related settings are associated with the context and are only written back to the
+ // context's format.
+ QSurfaceFormat format = window.openglContext()->format();
+
+ if (format.renderableType() == QSurfaceFormat::OpenGL) {
+ if (format.majorVersion() == 2)
+ QCOMPARE(window.glslVersion(), QString());
+ else if (format.majorVersion() == 3)
+ QVERIFY(window.glslVersion().startsWith('3')
+ || window.glslVersion() == QStringLiteral("130")
+ || window.glslVersion() == QStringLiteral("140")
+ || window.glslVersion() == QStringLiteral("150"));
+ else if (format.majorVersion() == 4)
+ QVERIFY(window.glslVersion().startsWith('4'));
+ QVERIFY(!window.glslVersion().contains(QStringLiteral("core")));
+ QVERIFY(!window.glslVersion().contains(QStringLiteral("es")));
+ } else if (format.renderableType() == QSurfaceFormat::OpenGLES) {
+ if (format.majorVersion() == 2)
+ QCOMPARE(window.glslVersion(), QString());
+ else
+ QVERIFY(window.glslVersion().contains(QStringLiteral("es")));
+ }
+}
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"
diff --git a/tests/auto/quick/rendernode/data/matrix.qml b/tests/auto/quick/rendernode/data/matrix.qml
new file mode 100644
index 0000000000..8b721e5075
--- /dev/null
+++ b/tests/auto/quick/rendernode/data/matrix.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import RenderNode 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Item { x: 10; y: 10; width: 10; height: 10;
+ StateRecorder { x: 10; y: 10; objectName: "no-clip; no-rotation"; }
+ }
+
+ Item { x: 10; y: 10; width: 10; height: 10; clip: true
+ StateRecorder { x: 10; y: 10; objectName: "parent-clip; no-rotation"; }
+ }
+
+ Item { x: 10; y: 10; width: 10; height: 10;
+ StateRecorder { x: 10; y: 10; objectName: "self-clip; no-rotation"; clip: true }
+ }
+
+
+ Item { x: 10; y: 10; width: 10; height: 10; rotation: 90
+ StateRecorder { x: 10; y: 10; objectName: "no-clip; parent-rotation"; }
+ }
+
+ Item { x: 10; y: 10; width: 10; height: 10; clip: true; rotation: 90
+ StateRecorder { x: 10; y: 10; objectName: "parent-clip; parent-rotation"; }
+ }
+
+ Item { x: 10; y: 10; width: 10; height: 10; rotation: 90
+ StateRecorder { x: 10; y: 10; objectName: "self-clip; parent-rotation"; clip: true }
+ }
+
+
+ Item { x: 10; y: 10; width: 10; height: 10;
+ StateRecorder { x: 10; y: 10; objectName: "no-clip; self-rotation"; rotation: 90 }
+ }
+
+ Item { x: 10; y: 10; width: 10; height: 10; clip: true;
+ StateRecorder { x: 10; y: 10; objectName: "parent-clip; self-rotation"; rotation: 90}
+ }
+
+ Item { x: 10; y: 10; width: 10; height: 10;
+ StateRecorder { x: 10; y: 10; objectName: "self-clip; self-rotation"; clip: true; rotation: 90 }
+ }
+
+}
diff --git a/tests/auto/quick/rendernode/rendernode.pro b/tests/auto/quick/rendernode/rendernode.pro
index b55b7b0bec..bedcefde86 100644
--- a/tests/auto/quick/rendernode/rendernode.pro
+++ b/tests/auto/quick/rendernode/rendernode.pro
@@ -14,4 +14,6 @@ QT += core-private gui-private qml-private quick-private testlib
OTHER_FILES += \
data/RenderOrder.qml \
data/MessUpState.qml \
+ data/matrix.qml
+
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp
index 06338e09e2..2397392419 100644
--- a/tests/auto/quick/rendernode/tst_rendernode.cpp
+++ b/tests/auto/quick/rendernode/tst_rendernode.cpp
@@ -44,6 +44,7 @@
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglfunctions.h>
#include <QtGui/qscreen.h>
#include <private/qsgrendernode_p.h>
@@ -72,6 +73,7 @@ public:
private slots:
void renderOrder();
void messUpState();
+ void matrix();
};
class ClearNode : public QSGRenderNode
@@ -85,8 +87,8 @@ public:
virtual void render(const RenderState &)
{
// If clip has been set, scissoring will make sure the right area is cleared.
- glClearColor(color.redF(), color.greenF(), color.blueF(), 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+ QOpenGLContext::currentContext()->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), 1.0f);
+ QOpenGLContext::currentContext()->functions()->glClear(GL_COLOR_BUFFER_BIT);
}
QColor color;
@@ -128,9 +130,11 @@ private:
QColor m_color;
};
-class MessUpNode : public QSGRenderNode
+class MessUpNode : public QSGRenderNode, protected QOpenGLFunctions
{
public:
+ MessUpNode() : initialized(false) { }
+
virtual StateFlags changedStates()
{
return StateFlags(DepthState) | StencilState | ScissorState | ColorState | BlendState
@@ -139,17 +143,17 @@ public:
virtual void render(const RenderState &)
{
+ if (!initialized) {
+ initializeOpenGLFunctions();
+ initialized = true;
+ }
// Don't draw anything, just mess up the state
glViewport(10, 10, 10, 10);
glDisable(GL_SCISSOR_TEST);
glDepthMask(true);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_EQUAL);
-#if defined(QT_OPENGL_ES)
glClearDepthf(1);
-#else
- glClearDepth(1);
-#endif
glClearStencil(42);
glClearColor(1.0f, 0.5f, 1.0f, 0.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -162,6 +166,8 @@ public:
glFrontFace(frontFace == GL_CW ? GL_CCW : GL_CW);
glEnable(GL_CULL_FACE);
}
+
+ bool initialized;
};
class MessUpItem : public QQuickItem
@@ -261,6 +267,84 @@ void tst_rendernode::messUpState()
QCOMPARE(fb.pixel(x2, y5), qRgb(0x00, 0x00, 0x00));
}
+class StateRecordingRenderNode : public QSGRenderNode
+{
+public:
+ StateFlags changedStates() { return StateFlags(-1); }
+ void render(const RenderState &) {
+ matrices[name] = *matrix();
+
+ }
+
+ QString name;
+ static QHash<QString, QMatrix4x4> matrices;
+};
+
+QHash<QString, QMatrix4x4> StateRecordingRenderNode::matrices;
+
+class StateRecordingRenderNodeItem : public QQuickItem
+{
+ Q_OBJECT
+public:
+ StateRecordingRenderNodeItem() { setFlag(ItemHasContents, true); }
+ QSGNode *updatePaintNode(QSGNode *r, UpdatePaintNodeData *) {
+ if (r)
+ return r;
+ StateRecordingRenderNode *rn = new StateRecordingRenderNode();
+ rn->name = objectName();
+ return rn;
+ }
+};
+
+void tst_rendernode::matrix()
+{
+ qmlRegisterType<StateRecordingRenderNodeItem>("RenderNode", 1, 0, "StateRecorder");
+ StateRecordingRenderNode::matrices.clear();
+ runTest("matrix.qml");
+
+ QMatrix4x4 noRotateOffset;
+ noRotateOffset.translate(20, 20);
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("no-clip; no-rotation"));
+ QCOMPARE(result, noRotateOffset);
+ }
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("parent-clip; no-rotation"));
+ QCOMPARE(result, noRotateOffset);
+ }
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("self-clip; no-rotation"));
+ QCOMPARE(result, noRotateOffset);
+ }
+
+ QMatrix4x4 parentRotation;
+ parentRotation.translate(10, 10); // parent at x/y: 10
+ parentRotation.translate(5, 5); // rotate 90 around center (width/height: 10)
+ parentRotation.rotate(90, 0, 0, 1);
+ parentRotation.translate(-5, -5);
+ parentRotation.translate(10, 10); // StateRecorder at: x/y: 10
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("no-clip; parent-rotation"));
+ QCOMPARE(result, parentRotation);
+ }
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("parent-clip; parent-rotation"));
+ QCOMPARE(result, parentRotation);
+ }
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("self-clip; parent-rotation"));
+ QCOMPARE(result, parentRotation);
+ }
+
+ QMatrix4x4 selfRotation;
+ selfRotation.translate(10, 10); // parent at x/y: 10
+ selfRotation.translate(10, 10); // StateRecorder at: x/y: 10
+ selfRotation.rotate(90, 0, 0, 1); // rotate 90, width/height: 0
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("no-clip; self-rotation"));
+ QCOMPARE(result, selfRotation);
+ }
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("parent-clip; self-rotation"));
+ QCOMPARE(result, selfRotation);
+ }
+ { QMatrix4x4 result = StateRecordingRenderNode::matrices.value(QStringLiteral("self-clip; self-rotation"));
+ QCOMPARE(result, selfRotation);
+ }
+}
+
QTEST_MAIN(tst_rendernode)
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index 0e3964d52d..aa6d7c4a93 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -47,6 +47,9 @@
#include <QtTest/QTest>
+#include <private/qquickwindow_p.h>
+
+
QQuickView *QQuickViewTestUtil::createView()
{
QQuickView *window = new QQuickView(0);
@@ -341,3 +344,23 @@ QList<QPair<QString,QString> > QQuickViewTestUtil::ListRange::getModelDataValues
return data;
}
+namespace QQuickTouchUtils {
+
+ /* QQuickWindow does event compression and only delivers events just
+ * before it is about to render the next frame. Since some tests
+ * rely on events being delivered immediately AND that no other
+ * event processing has occurred in the meanwhile, we flush the
+ * event manually and immediately.
+ */
+ void flush(QQuickWindow *window) {
+ if (!window)
+ return;
+ QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
+ if (!wd || !wd->delayedTouch)
+ return;
+ wd->reallyDeliverTouchEvent(wd->delayedTouch);
+ delete wd->delayedTouch;
+ wd->delayedTouch = 0;
+ }
+
+}
diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h
index 5b0b10b69c..e10966ddba 100644
--- a/tests/auto/quick/shared/viewtestutil.h
+++ b/tests/auto/quick/shared/viewtestutil.h
@@ -166,6 +166,10 @@ namespace QQuickViewTestUtil
}
}
+namespace QQuickTouchUtils {
+ void flush(QQuickWindow *window);
+}
+
Q_DECLARE_METATYPE(QQuickViewTestUtil::QaimModel*)
Q_DECLARE_METATYPE(QQuickViewTestUtil::ListChange)
Q_DECLARE_METATYPE(QList<QQuickViewTestUtil::ListChange>)
diff --git a/tests/auto/quick/touchmouse/touchmouse.pro b/tests/auto/quick/touchmouse/touchmouse.pro
index 445bee08ae..7d23dfc0ae 100644
--- a/tests/auto/quick/touchmouse/touchmouse.pro
+++ b/tests/auto/quick/touchmouse/touchmouse.pro
@@ -8,6 +8,7 @@ macx:CONFIG -= app_bundle
SOURCES += tst_touchmouse.cpp
include (../../shared/util.pri)
+include (../shared/util.pri)
TESTDATA = data/*
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 5b4ad0ffa3..1d947b4d8c 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -58,6 +58,7 @@
#include <QtQml/qqmlproperty.h>
#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
struct Event
{
@@ -221,12 +222,15 @@ void tst_TouchMouse::simpleTouchEvent()
QPoint p1;
p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 1);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
p1 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 1);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 1);
eventItem1->eventList.clear();
@@ -234,11 +238,14 @@ void tst_TouchMouse::simpleTouchEvent()
eventItem1->acceptTouch = true;
p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 1);
p1 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 3);
eventItem1->eventList.clear();
@@ -251,6 +258,7 @@ void tst_TouchMouse::simpleTouchEvent()
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -268,10 +276,12 @@ void tst_TouchMouse::simpleTouchEvent()
p1 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 4);
QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchUpdate);
QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 6);
QCOMPARE(eventItem1->eventList.at(4).type, QEvent::TouchEnd);
QCOMPARE(eventItem1->eventList.at(5).type, QEvent::MouseButtonRelease);
@@ -286,13 +296,16 @@ void tst_TouchMouse::simpleTouchEvent()
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
p1 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
eventItem1->eventList.clear();
@@ -304,13 +317,16 @@ void tst_TouchMouse::simpleTouchEvent()
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 1);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
p1 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::TouchUpdate);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 3);
QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
eventItem1->eventList.clear();
@@ -376,6 +392,7 @@ void tst_TouchMouse::mouse()
// item 2 doesn't accept anything, thus it sees a touch pass by
QPoint p1 = QPoint(30, 30);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
@@ -412,14 +429,17 @@ void tst_TouchMouse::touchOverMouse()
QCOMPARE(eventItem1->eventList.size(), 0);
QPoint p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 0);
QCOMPARE(eventItem2->eventList.size(), 1);
QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
p1 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem2->eventList.size(), 2);
QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchUpdate);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem2->eventList.size(), 3);
QCOMPARE(eventItem2->eventList.at(2).type, QEvent::TouchEnd);
eventItem2->eventList.clear();
@@ -456,6 +476,7 @@ void tst_TouchMouse::mouseOverTouch()
QPoint p1 = QPoint(20, 20);
QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 0);
QCOMPARE(eventItem2->eventList.size(), 2);
QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
@@ -510,10 +531,12 @@ void tst_TouchMouse::buttonOnFlickable()
QCOMPARE(eventItem1->eventList.size(), 0);
QPoint p1 = QPoint(20, 130);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QTRY_COMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 4);
QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseButtonRelease);
@@ -522,9 +545,11 @@ void tst_TouchMouse::buttonOnFlickable()
// touch button
p1 = QPoint(10, 310);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem2->eventList.size(), 1);
QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem2->eventList.size(), 2);
QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchEnd);
QCOMPARE(eventItem1->eventList.size(), 0);
@@ -536,8 +561,10 @@ void tst_TouchMouse::buttonOnFlickable()
// click above button, no events please
p1 = QPoint(10, 90);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 0);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 0);
eventItem1->eventList.clear();
@@ -548,6 +575,7 @@ void tst_TouchMouse::buttonOnFlickable()
QCOMPARE(eventItem1->eventList.size(), 0);
p1 = QPoint(10, 110);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -560,12 +588,13 @@ void tst_TouchMouse::buttonOnFlickable()
p1 += QPoint(0, -10);
QPoint p2 = p1 + QPoint(0, -10);
QPoint p3 = p2 + QPoint(0, -10);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).move(0, p1, window);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).move(0, p2, window);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).move(0, p3, window);
+ QQuickTouchUtils::flush(window);
// we cannot really know when the events get grabbed away
QVERIFY(eventItem1->eventList.size() >= 4);
@@ -578,6 +607,7 @@ void tst_TouchMouse::buttonOnFlickable()
QVERIFY(flickable->isMovingVertically());
QTest::touchEvent(window, device).release(0, p3, window);
+ QQuickTouchUtils::flush(window);
delete window;
}
@@ -625,6 +655,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
QCOMPARE(eventItem1->eventList.size(), 0);
QPoint p1 = QPoint(10, 110);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
// Flickable initially steals events
QCOMPARE(eventItem1->eventList.size(), 0);
// but we'll get the delayed mouse press after a delay
@@ -641,12 +672,13 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
p1 += QPoint(0, -10);
QPoint p2 = p1 + QPoint(0, -10);
QPoint p3 = p2 + QPoint(0, -10);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).move(0, p1, window);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).move(0, p2, window);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).move(0, p3, window);
+ QQuickTouchUtils::flush(window);
QVERIFY(flickable->isMovingVertically());
// flickable should have the mouse grab, and have moved the itemForTouchPointId
@@ -656,6 +688,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
QCOMPARE(windowPriv->itemForTouchPointId[0], flickable);
QTest::touchEvent(window, device).release(0, p3, window);
+ QQuickTouchUtils::flush(window);
// We should not have received any synthesised mouse events from Qt gui.
QCOMPARE(filteredEventList.count(), 0);
@@ -709,7 +742,9 @@ void tst_TouchMouse::buttonOnTouch()
// Normal touch click
QPoint p1 = QPoint(10, 110);
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(eventItem1->eventList.size(), 4);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -730,7 +765,9 @@ void tst_TouchMouse::buttonOnTouch()
// Start the events after each other
QTest::touchEvent(window, device).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).stationary(0).press(1, p2, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(button1->scale(), 1.0);
@@ -738,20 +775,24 @@ void tst_TouchMouse::buttonOnTouch()
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+ QQuickTouchUtils::flush(window);
// QCOMPARE(button1->scale(), 1.5);
qDebug() << "Button scale: " << button1->scale();
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+ QQuickTouchUtils::flush(window);
// QCOMPARE(button1->scale(), 2.0);
qDebug() << "Button scale: " << button1->scale();
QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
+ QQuickTouchUtils::flush(window);
// QVERIFY(eventItem1->eventList.isEmpty());
// QCOMPARE(button1->scale(), 2.0);
qDebug() << "Button scale: " << button1->scale();
@@ -765,6 +806,7 @@ void tst_TouchMouse::buttonOnTouch()
p1 = QPoint(40, 110);
p2 = QPoint(60, 110);
QTest::touchEvent(window, device).press(0, p1, window).press(1, p2, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(button1->scale(), 1.0);
QCOMPARE(eventItem1->eventList.count(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
@@ -774,20 +816,24 @@ void tst_TouchMouse::buttonOnTouch()
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+ QQuickTouchUtils::flush(window);
//QCOMPARE(button1->scale(), 1.5);
qDebug() << button1->scale();
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+ QQuickTouchUtils::flush(window);
qDebug() << button1->scale();
//QCOMPARE(button1->scale(), 2.0);
QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
+ QQuickTouchUtils::flush(window);
// QCOMPARE(eventItem1->eventList.size(), 99);
qDebug() << button1->scale();
//QCOMPARE(button1->scale(), 2.0);
@@ -816,18 +862,22 @@ void tst_TouchMouse::pinchOnFlickable()
QVERIFY(flickable->contentX() == 0.0);
QPoint p = QPoint(100, 100);
QTest::touchEvent(window, device).press(0, p, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
+ QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
- QTest::qWait(10);
+ QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).release(0, p, window);
+ QQuickTouchUtils::flush(window);
QGuiApplication::processEvents();
QTest::qWait(10);
@@ -840,27 +890,35 @@ void tst_TouchMouse::pinchOnFlickable()
QPoint p2 = QPoint(60, 20);
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
+ QQuickTouchUtils::flush(window);
pinchSequence.press(0, p1, window).commit();
+ QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object. Otherwise if we let it
// be destroyed and then start a new sequence, point 0 will default to being
// stationary at 0, 0, and PinchArea will filter out that touchpoint because
// it is outside its bounds.
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QVERIFY(rect->scale() > 1.0);
}
@@ -885,17 +943,22 @@ void tst_TouchMouse::flickableOnPinch()
QVERIFY(flickable->contentX() == 0.0);
QPoint p = QPoint(100, 100);
QTest::touchEvent(window, device).press(0, p, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
+ QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
+ QQuickTouchUtils::flush(window);
QTest::qWait(1000);
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).release(0, p, window);
+ QQuickTouchUtils::flush(window);
QTest::qWait(1000);
@@ -909,26 +972,33 @@ void tst_TouchMouse::flickableOnPinch()
QPoint p2 = QPoint(60, 20);
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
pinchSequence.press(0, p1, window).commit();
+ QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object. Otherwise if we let it
// be destroyed and then start a new sequence, point 0 will default to being
// stationary at 0, 0, and PinchArea will filter out that touchpoint because
// it is outside its bounds.
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QVERIFY(rect->scale() > 1.0);
}
@@ -953,16 +1023,19 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
QVERIFY(flickable->contentX() == 0.0);
QPoint p = QPoint(100, 100);
QTest::touchEvent(window, device).press(0, p, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
+ QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
- QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p, window);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).release(0, p, window);
- QGuiApplication::processEvents();
+ QQuickTouchUtils::flush(window);
//QVERIFY(flickable->isMovingHorizontally());
@@ -975,26 +1048,33 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
QPoint p2 = QPoint(60, 20);
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
pinchSequence.press(0, p1, window).commit();
+ QQuickTouchUtils::flush(window);
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object. Otherwise if we let it
// be destroyed and then start a new sequence, point 0 will default to being
// stationary at 0, 0, and PinchArea will filter out that touchpoint because
// it is outside its bounds.
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QVERIFY(rect->scale() > 1.0);
// PinchArea should steal the event after flicking started
@@ -1002,14 +1082,18 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
flickable->setContentX(0.0);
p = QPoint(100, 100);
pinchSequence.press(0, p, window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
pinchSequence.move(0, p, window).commit();
+ QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
pinchSequence.move(0, p, window).commit();
+ QQuickTouchUtils::flush(window);
QGuiApplication::processEvents();
p -= QPoint(10, 0);
pinchSequence.move(0, p, window).commit();
+ QQuickTouchUtils::flush(window);
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
qDebug() << "Mouse Grabber: " << windowPriv->mouseGrabberItem << " itemForTouchPointId: " << windowPriv->itemForTouchPointId;
@@ -1019,20 +1103,26 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
p1 = QPoint(40, 100);
p2 = QPoint(60, 100);
pinchSequence.stationary(0).press(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(5, 0);
p2 += QPoint(5, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(5, 0);
p2 += QPoint(5, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
p1 -= QPoint(5, 0);
p2 += QPoint(5, 0);
pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QVERIFY(rect->scale() > 1.0);
pinchSequence.release(0, p, window).commit();
+ QQuickTouchUtils::flush(window);
}
/*
@@ -1066,16 +1156,17 @@ void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne()
// tap the front mouse area (see qml file)
QPoint p1(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
- QTest::qWait(1);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(bottomClickedSpy.count(), 1);
QCOMPARE(bottomDoubleClickedSpy.count(), 0);
- QTest::qWait(15);
QTest::touchEvent(window, device).press(0, p1, window);
- QTest::qWait(1);
+ QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
QCOMPARE(bottomClickedSpy.count(), 1);
QCOMPARE(bottomDoubleClickedSpy.count(), 1);
diff --git a/tests/auto/quickwidgets/qquickwidget/data/animating.qml b/tests/auto/quickwidgets/qquickwidget/data/animating.qml
new file mode 100644
index 0000000000..1f6467aabe
--- /dev/null
+++ b/tests/auto/quickwidgets/qquickwidget/data/animating.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+Rectangle {
+ Rectangle {
+ width: 100
+ height: 100
+ anchors.centerIn: parent
+ color: "red"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+ }
+}
diff --git a/tests/auto/quickwidgets/qquickwidget/data/error1.qml b/tests/auto/quickwidgets/qquickwidget/data/error1.qml
new file mode 100644
index 0000000000..09df679555
--- /dev/null
+++ b/tests/auto/quickwidgets/qquickwidget/data/error1.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+Rectangle {
+ nonExistentProperty: 5
+}
diff --git a/tests/auto/quickwidgets/qquickwidget/data/rectangle.qml b/tests/auto/quickwidgets/qquickwidget/data/rectangle.qml
new file mode 100644
index 0000000000..3b18ba35c1
--- /dev/null
+++ b/tests/auto/quickwidgets/qquickwidget/data/rectangle.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+Rectangle {
+ width: 200
+ height: 200
+
+ color: "red"
+}
+
diff --git a/tests/auto/quickwidgets/qquickwidget/data/resizemodeitem.qml b/tests/auto/quickwidgets/qquickwidget/data/resizemodeitem.qml
new file mode 100644
index 0000000000..225c5711a9
--- /dev/null
+++ b/tests/auto/quickwidgets/qquickwidget/data/resizemodeitem.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+Item {
+ width: 200
+ height: 200
+
+}
+
diff --git a/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro b/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro
new file mode 100644
index 0000000000..069270da3c
--- /dev/null
+++ b/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro
@@ -0,0 +1,19 @@
+CONFIG += testcase
+TARGET = tst_qquickwidget
+SOURCES += tst_qquickwidget.cpp
+
+include (../../shared/util.pri)
+
+osx:CONFIG -= app_bundle
+
+QT += core-private gui-private qml-private quick-private quickwidgets quickwidgets-private widgets-private testlib
+
+TESTDATA = data/*
+
+OTHER_FILES += \
+ animating.qml \
+ error1.qml \
+ rectangle.qml \
+ resizemodeitem.qml
+
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
new file mode 100644
index 0000000000..db2d0e14e4
--- /dev/null
+++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QtTest/QSignalSpy>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickitem.h>
+#include "../../shared/util.h"
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+#include <QtQml/qqmlengine.h>
+
+#include <QtQuickWidgets/QQuickWidget>
+
+class tst_qquickwidget : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_qquickwidget();
+
+private slots:
+ void showHide();
+ void reparentAfterShow();
+ void changeGeometry();
+ void resizemodeitem();
+ void errors();
+ void engine();
+ void readback();
+};
+
+
+tst_qquickwidget::tst_qquickwidget()
+{
+}
+
+void tst_qquickwidget::showHide()
+{
+ QWidget window;
+
+ QQuickWidget *childView = new QQuickWidget(&window);
+ childView->setSource(testFileUrl("rectangle.qml"));
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window, 5000));
+
+ childView->hide();
+}
+
+void tst_qquickwidget::reparentAfterShow()
+{
+ QWidget window;
+
+ QQuickWidget *childView = new QQuickWidget(&window);
+ childView->setSource(testFileUrl("rectangle.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window, 5000));
+
+ QScopedPointer<QQuickWidget> toplevelView(new QQuickWidget);
+ toplevelView->setParent(&window);
+ toplevelView->setSource(testFileUrl("rectangle.qml"));
+ toplevelView->show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window, 5000));
+}
+
+void tst_qquickwidget::changeGeometry()
+{
+ QWidget window;
+
+ QQuickWidget *childView = new QQuickWidget(&window);
+ childView->setSource(testFileUrl("rectangle.qml"));
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window, 5000));
+
+ childView->setGeometry(100,100,100,100);
+}
+
+void tst_qquickwidget::resizemodeitem()
+{
+ QWidget window;
+ window.setGeometry(0, 0, 400, 400);
+
+ QScopedPointer<QQuickWidget> view(new QQuickWidget);
+ view->setParent(&window);
+ view->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ QCOMPARE(QSize(0,0), view->initialSize());
+ view->setSource(testFileUrl("resizemodeitem.qml"));
+ QQuickItem* item = qobject_cast<QQuickItem*>(view->rootObject());
+ QVERIFY(item);
+ window.show();
+
+ view->showNormal();
+ // initial size from root object
+ QCOMPARE(item->width(), 200.0);
+ QCOMPARE(item->height(), 200.0);
+ QCOMPARE(view->size(), QSize(200, 200));
+ QCOMPARE(view->size(), view->sizeHint());
+ QCOMPARE(view->size(), view->initialSize());
+
+ // size update from view
+ view->resize(QSize(80,100));
+
+ QTRY_COMPARE(item->width(), 80.0);
+ QCOMPARE(item->height(), 100.0);
+ QCOMPARE(view->size(), QSize(80, 100));
+ QCOMPARE(view->size(), view->sizeHint());
+
+ view->setResizeMode(QQuickWidget::SizeViewToRootObject);
+
+ // size update from view disabled
+ view->resize(QSize(60,80));
+ QCOMPARE(item->width(), 80.0);
+ QCOMPARE(item->height(), 100.0);
+ QTRY_COMPARE(view->size(), QSize(60, 80));
+
+ // size update from root object
+ item->setWidth(250);
+ item->setHeight(350);
+ QCOMPARE(item->width(), 250.0);
+ QCOMPARE(item->height(), 350.0);
+ QTRY_COMPARE(view->size(), QSize(250, 350));
+ QCOMPARE(view->size(), QSize(250, 350));
+ QCOMPARE(view->size(), view->sizeHint());
+
+ // reset window
+ window.hide();
+ view.reset(new QQuickWidget(&window));
+ view->setResizeMode(QQuickWidget::SizeViewToRootObject);
+ view->setSource(testFileUrl("resizemodeitem.qml"));
+ item = qobject_cast<QQuickItem*>(view->rootObject());
+ QVERIFY(item);
+ window.show();
+
+ view->showNormal();
+
+ // initial size for root object
+ QCOMPARE(item->width(), 200.0);
+ QCOMPARE(item->height(), 200.0);
+ QCOMPARE(view->size(), view->sizeHint());
+ QCOMPARE(view->size(), view->initialSize());
+
+ // size update from root object
+ item->setWidth(80);
+ item->setHeight(100);
+ QCOMPARE(item->width(), 80.0);
+ QCOMPARE(item->height(), 100.0);
+ QTRY_COMPARE(view->size(), QSize(80, 100));
+ QCOMPARE(view->size(), view->sizeHint());
+
+ // size update from root object disabled
+ view->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ item->setWidth(60);
+ item->setHeight(80);
+ QCOMPARE(view->width(), 80);
+ QCOMPARE(view->height(), 100);
+ QCOMPARE(QSize(item->width(), item->height()), view->sizeHint());
+
+ // size update from view
+ view->resize(QSize(200,300));
+ QTRY_COMPARE(item->width(), 200.0);
+ QCOMPARE(item->height(), 300.0);
+ QCOMPARE(view->size(), QSize(200, 300));
+ QCOMPARE(view->size(), view->sizeHint());
+
+ window.hide();
+
+ // if we set a specific size for the view then it should keep that size
+ // for SizeRootObjectToView mode.
+ view.reset(new QQuickWidget(&window));
+ view->resize(300, 300);
+ view->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ QCOMPARE(QSize(0,0), view->initialSize());
+ view->setSource(testFileUrl("resizemodeitem.qml"));
+ view->resize(300, 300);
+ item = qobject_cast<QQuickItem*>(view->rootObject());
+ QVERIFY(item);
+ window.show();
+
+ view->showNormal();
+
+ // initial size from root object
+ QCOMPARE(item->width(), 300.0);
+ QCOMPARE(item->height(), 300.0);
+ QTRY_COMPARE(view->size(), QSize(300, 300));
+ QCOMPARE(view->size(), view->sizeHint());
+ QCOMPARE(view->initialSize(), QSize(200, 200)); // initial object size
+}
+
+void tst_qquickwidget::errors()
+{
+ QQuickWidget *view = new QQuickWidget;
+ QScopedPointer<QQuickWidget> cleanupView(view);
+
+ QQmlTestMessageHandler messageHandler;
+ view->setSource(testFileUrl("error1.qml"));
+ QVERIFY(view->status() == QQuickWidget::Error);
+ QVERIFY(view->errors().count() == 1);
+}
+
+void tst_qquickwidget::engine()
+{
+ QScopedPointer<QQmlEngine> engine(new QQmlEngine);
+ QScopedPointer<QQuickWidget> view(new QQuickWidget(engine.data(), 0));
+ QScopedPointer<QQuickWidget> view2(new QQuickWidget(view->engine(), 0));
+
+ QVERIFY(view->engine());
+ QVERIFY(view2->engine());
+ QCOMPARE(view->engine(), view2->engine());
+}
+
+void tst_qquickwidget::readback()
+{
+#ifdef Q_OS_MAC
+ QSKIP("Skipping due to issues on OS X: QTBUG-39919");
+#endif
+
+ QWidget window;
+
+ QScopedPointer<QQuickWidget> view(new QQuickWidget);
+ view->setSource(testFileUrl("rectangle.qml"));
+
+ view->show();
+ QVERIFY(QTest::qWaitForWindowExposed(view.data(), 5000));
+
+ QImage img = view->grabFramebuffer();
+ QVERIFY(!img.isNull());
+ QCOMPARE(img.width(), view->width());
+ QCOMPARE(img.height(), view->height());
+
+ QRgb pix = img.pixel(5, 5);
+ QCOMPARE(pix, qRgb(255, 0, 0));
+}
+
+QTEST_MAIN(tst_qquickwidget)
+
+#include "tst_qquickwidget.moc"
diff --git a/tests/auto/quickwidgets/quickwidgets.pro b/tests/auto/quickwidgets/quickwidgets.pro
new file mode 100644
index 0000000000..ee8d6077e6
--- /dev/null
+++ b/tests/auto/quickwidgets/quickwidgets.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += qquickwidget
diff --git a/tests/auto/shared/testhttpserver.cpp b/tests/auto/shared/testhttpserver.cpp
index d3de584084..231f22b35b 100644
--- a/tests/auto/shared/testhttpserver.cpp
+++ b/tests/auto/shared/testhttpserver.cpp
@@ -71,7 +71,8 @@ slowFiles/slowMain.qml
\endcode
it can be added like this:
\code
-TestHTTPServer server(14445);
+TestHTTPServer server;
+QVERIFY2(server.listen(14445), qPrintable(server.errorString()));
server.serveDirectory("disconnect", TestHTTPServer::Disconnect);
server.serveDirectory("files");
server.serveDirectory("slowFiles", TestHTTPServer::Delay);
@@ -87,17 +88,21 @@ The following request urls will then result in the appropriate action:
\row \li http://localhost:14445/slowMain.qml \li slowMain.qml returned after 500ms
\endtable
*/
-TestHTTPServer::TestHTTPServer(quint16 port)
+TestHTTPServer::TestHTTPServer()
: m_state(AwaitingHeader)
{
QObject::connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection()));
- server.listen(QHostAddress::LocalHost, port);
}
-bool TestHTTPServer::isValid() const
+bool TestHTTPServer::listen(quint16 port)
{
- return server.isListening();
+ return server.listen(QHostAddress::LocalHost, port);
+}
+
+QString TestHTTPServer::errorString() const
+{
+ return server.errorString();
}
bool TestHTTPServer::serveDirectory(const QString &dir, Mode mode)
diff --git a/tests/auto/shared/testhttpserver.h b/tests/auto/shared/testhttpserver.h
index ae7d137143..a71386ddec 100644
--- a/tests/auto/shared/testhttpserver.h
+++ b/tests/auto/shared/testhttpserver.h
@@ -51,9 +51,10 @@ class TestHTTPServer : public QObject
{
Q_OBJECT
public:
- TestHTTPServer(quint16 port);
+ TestHTTPServer();
- bool isValid() const;
+ bool listen(quint16 port);
+ QString errorString() const;
enum Mode { Normal, Delay, Disconnect };
bool serveDirectory(const QString &, Mode = Normal);