aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/auto.pro11
-rw-r--r--tests/auto/particles/particles.pro3
-rw-r--r--tests/auto/particles/qquickage/tst_qquickage.cpp8
-rw-r--r--tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp2
-rw-r--r--tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp2
-rw-r--r--tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp4
-rw-r--r--tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp2
-rw-r--r--tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp4
-rw-r--r--tests/auto/particles/qquickfriction/tst_qquickfriction.cpp6
-rw-r--r--tests/auto/particles/qquickgravity/tst_qquickgravity.cpp2
-rw-r--r--tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp2
-rw-r--r--tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp12
-rw-r--r--tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp2
-rw-r--r--tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp4
-rw-r--r--tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp2
-rw-r--r--tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp2
-rw-r--r--tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp2
-rw-r--r--tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp2
-rw-r--r--tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp2
-rw-r--r--tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp4
-rw-r--r--tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp2
-rw-r--r--tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp2
-rw-r--r--tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp4
-rw-r--r--tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp2
-rw-r--r--tests/auto/particles/qquickwander/tst_qquickwander.cpp2
-rw-r--r--tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp4
-rw-r--r--tests/auto/qml/debugger/debugger.pro4
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp5
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp7
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml10
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml4
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/javascript.qml8
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/signalSourceLocation.qml8
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/test.qml4
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml10
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp31
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp4
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp186
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp14
-rw-r--r--tests/auto/qml/qml.pro12
-rw-r--r--tests/auto/qml/qmldiskcache/qmldiskcache.pro9
-rw-r--r--tests/auto/qml/qmldiskcache/test.qml4
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp694
-rw-r--r--tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp1
-rw-r--r--tests/auto/qml/qqmlbinding/data/delayed.qml26
-rw-r--r--tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp22
-rw-r--r--tests/auto/qml/qqmlconsole/data/categorized_logging.qml65
-rw-r--r--tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp36
-rw-r--r--tests/auto/qml/qqmlecmascript/data/NullObjectInitializerBase.qml5
-rw-r--r--tests/auto/qml/qqmlecmascript/data/dependenciesWithFunctions.qml12
-rw-r--r--tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.2.qml8
-rw-r--r--tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.qml4
-rw-r--r--tests/auto/qml/qqmlecmascript/qqmlecmascript.pro5
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h3
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp91
-rw-r--r--tests/auto/qml/qqmlengine/data/qtqmlModule.4.qml2
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp15
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/types.qml3
-rw-r--r--tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp2
-rw-r--r--tests/auto/qml/qqmllanguage/data/QtObjectWithChildren.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.12.qml15
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.13.qml16
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.14.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.14.qml17
-rw-r--r--tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml11
-rw-r--r--tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml7
-rw-r--r--tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml15
-rw-r--r--tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml11
-rw-r--r--tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml14
-rw-r--r--tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppnamespace.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/defaultListProperty.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidAlias.11.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidAlias.11.qml10
-rw-r--r--tests/auto/qml/qqmllanguage/data/rootItemIsComponent.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/singletonTest10.error.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/uncreatableTypeAsProperty.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp18
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h73
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp132
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin.2.1/childplugin/childplugin.cpp2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin.2/childplugin/childplugin.cpp2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin/childplugin/childplugin.cpp2
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp65
-rw-r--r--tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp271
-rw-r--r--tests/auto/qml/qqmlqt/data/LaterComponent.qml14
-rw-r--r--tests/auto/qml/qqmlqt/data/LaterComponent2.qml13
-rw-r--r--tests/auto/qml/qqmlqt/data/LaterComponent3.qml14
-rw-r--r--tests/auto/qml/qqmlqt/data/LaterComponent4.qml12
-rw-r--r--tests/auto/qml/qqmlqt/data/exit.qml7
-rw-r--r--tests/auto/qml/qqmlqt/data/later.qml124
-rw-r--r--tests/auto/qml/qqmlqt/data/timeRoundtrip.qml8
-rw-r--r--tests/auto/qml/qqmlqt/tst_qqmlqt.cpp286
-rw-r--r--tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp17
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp3
-rw-r--r--tests/auto/qml/qqmlvaluetypes/data/color_read.qml6
-rw-r--r--tests/auto/qml/qqmlvaluetypes/data/color_write_HSL.qml8
-rw-r--r--tests/auto/qml/qqmlvaluetypes/data/color_write_HSV.qml8
-rw-r--r--tests/auto/qml/qqmlvaluetypes/testtypes.h6
-rw-r--r--tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp54
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect17
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/send_patch.qml68
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/send_patch.reply3
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp21
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp10
-rw-r--r--tests/auto/qml/qv4mm/qv4mm.pro8
-rw-r--r--tests/auto/qml/qv4mm/tst_qv4mm.cpp58
-rw-r--r--tests/auto/qmldevtools/compile/compile.pro2
-rw-r--r--tests/auto/qmldevtools/qmldevtools.pro6
-rw-r--r--tests/auto/qmltest/selftests/tst_tryVerify.qml72
-rw-r--r--tests/auto/quick/examples/tst_examples.cpp12
-rw-r--r--tests/auto/quick/geometry/tst_geometry.cpp6
-rw-r--r--tests/auto/quick/nodes/tst_nodestest.cpp8
-rw-r--r--tests/auto/quick/nokeywords/tst_nokeywords.cpp6
-rw-r--r--tests/auto/quick/qquickaccessible/qquickaccessible.pro7
-rw-r--r--tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp6
-rw-r--r--tests/auto/quick/qquickapplication/tst_qquickapplication.cpp16
-rw-r--r--tests/auto/quick/qquickborderimage/data/mesh.qml22
-rw-r--r--tests/auto/quick/qquickborderimage/data/nonmesh.qml11
-rw-r--r--tests/auto/quick/qquickborderimage/qquickborderimage.pro1
-rw-r--r--tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp24
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml4
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml1
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_image.qml1
-rw-r--r--tests/auto/quick/qquickflickable/data/contentXY.qml6
-rw-r--r--tests/auto/quick/qquickflickable/data/keepGrab.qml22
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp70
-rw-r--r--tests/auto/quick/qquickgraphicsinfo/data/basic.qml14
-rw-r--r--tests/auto/quick/qquickgraphicsinfo/qquickgraphicsinfo.pro14
-rw-r--r--tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp85
-rw-r--r--tests/auto/quick/qquickimage/tst_qquickimage.cpp5
-rw-r--r--tests/auto/quick/qquickitem2/data/layoutmirroring_window.qml7
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp287
-rw-r--r--tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp46
-rw-r--r--tests/auto/quick/qquicklistview/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickloader/data/qmldir1
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp6
-rw-r--r--tests/auto/quick/qquickmousearea/data/qtbug54019.qml21
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp285
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp4
-rw-r--r--tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp16
-rw-r--r--tests/auto/quick/qquickpincharea/data/pinchproperties.qml2
-rw-r--r--tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp66
-rw-r--r--tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp62
-rw-r--r--tests/auto/quick/qquicktext/BLACKLIST2
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp30
-rw-r--r--tests/auto/quick/qquicktextedit/BLACKLIST4
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp69
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp43
-rw-r--r--tests/auto/quick/qquickview/tst_qquickview.cpp33
-rw-r--r--tests/auto/quick/qquickwindow/qquickwindow.pro2
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp267
-rw-r--r--tests/auto/quick/quick.pro24
-rw-r--r--tests/auto/quick/rendernode/tst_rendernode.cpp17
-rw-r--r--tests/auto/quick/scenegraph/scenegraph.pro1
-rw-r--r--tests/auto/quick/scenegraph/tst_scenegraph.cpp89
-rw-r--r--tests/auto/quick/shared/visualtestutil.cpp35
-rw-r--r--tests/auto/quick/shared/visualtestutil.h2
-rw-r--r--tests/auto/quick/touchmouse/data/touchpointdeliveryorder.qml39
-rw-r--r--tests/auto/quick/touchmouse/touchmouse.pro2
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp240
-rw-r--r--tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp23
-rw-r--r--tests/auto/shared/util.cpp11
-rw-r--r--tests/auto/shared/util.h5
-rw-r--r--tests/benchmarks/benchmarks.pro4
-rw-r--r--tests/benchmarks/particles/affectors/tst_affectors.cpp4
-rw-r--r--tests/benchmarks/particles/emission/tst_emission.cpp2
-rw-r--r--tests/benchmarks/qml/animation/tst_animation.cpp4
-rw-r--r--tests/benchmarks/qml/compilation/tst_compilation.cpp4
-rw-r--r--tests/benchmarks/qml/creation/tst_creation.cpp89
-rw-r--r--tests/manual/nodetypes/Animators.qml180
-rw-r--r--tests/manual/nodetypes/Effects.qml221
-rw-r--r--tests/manual/nodetypes/Images.qml97
-rw-r--r--tests/manual/nodetypes/Layers.qml106
-rw-r--r--tests/manual/nodetypes/LotsOfImages.qml73
-rw-r--r--tests/manual/nodetypes/LotsOfRects.qml250
-rw-r--r--tests/manual/nodetypes/Painter.qml84
-rw-r--r--tests/manual/nodetypes/Rects.qml137
-rw-r--r--tests/manual/nodetypes/Text.qml71
-rw-r--r--tests/manual/nodetypes/face-smile.pngbin0 -> 15408 bytes
-rw-r--r--tests/manual/nodetypes/hlslcompile.bat4
-rw-r--r--tests/manual/nodetypes/main.qml83
-rw-r--r--tests/manual/nodetypes/nodetypes.cpp206
-rw-r--r--tests/manual/nodetypes/nodetypes.pro9
-rw-r--r--tests/manual/nodetypes/nodetypes.qrc21
-rw-r--r--tests/manual/nodetypes/ps_shadow1.csobin0 -> 1600 bytes
-rw-r--r--tests/manual/nodetypes/ps_shadow2.csobin0 -> 1436 bytes
-rw-r--r--tests/manual/nodetypes/ps_wobble.csobin0 -> 1272 bytes
-rw-r--r--tests/manual/nodetypes/qt.pngbin0 -> 11917 bytes
-rw-r--r--tests/manual/nodetypes/shadow.pngbin0 -> 425 bytes
-rw-r--r--tests/manual/nodetypes/shadow1.hlsl18
-rw-r--r--tests/manual/nodetypes/shadow2.hlsl22
-rw-r--r--tests/manual/nodetypes/vs_wobble.csobin0 -> 1184 bytes
-rw-r--r--tests/manual/nodetypes/wobble.hlsl32
-rw-r--r--tests/manual/qmlplugindump/tst_qmlplugindump.cpp11
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_ltr.qml14
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_rtl.qml14
-rw-r--r--tests/manual/scenegraph_lancelot/scenegrabber/main.cpp4
-rw-r--r--tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp6
203 files changed, 6072 insertions, 757 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 425e88b983..556f5ddc7a 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -2,16 +2,21 @@ TEMPLATE=subdirs
SUBDIRS=\
qml \
quick \
- particles \
qmltest \
qmldevtools \
cmake \
installed_cmake \
toolsupport
-qtHaveModule(widgets): SUBDIRS += quickwidgets
+qtHaveModule(gui):qtConfig(opengl(es1|es2)?) {
+ SUBDIRS += particles
+ qtHaveModule(widgets): SUBDIRS += quickwidgets
+
+}
+
+# console applications not supported
+uikit: SUBDIRS -= qmltest
qmldevtools.CONFIG = host_build
installed_cmake.depends = cmake
-
diff --git a/tests/auto/particles/particles.pro b/tests/auto/particles/particles.pro
index 265a1eabc7..6ee1290dbb 100644
--- a/tests/auto/particles/particles.pro
+++ b/tests/auto/particles/particles.pro
@@ -25,6 +25,5 @@ PRIVATETESTS += \
qquickturbulence \
qquickwander
-contains(QT_CONFIG, private_tests) {
+qtConfig(private_tests): \
SUBDIRS += $$PRIVATETESTS
-}
diff --git a/tests/auto/particles/qquickage/tst_qquickage.cpp b/tests/auto/particles/qquickage/tst_qquickage.cpp
index 04c6fbd9e4..a233b30043 100644
--- a/tests/auto/particles/qquickage/tst_qquickage.cpp
+++ b/tests/auto/particles/qquickage/tst_qquickage.cpp
@@ -61,7 +61,7 @@ void tst_qquickage::test_kill()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -86,7 +86,7 @@ void tst_qquickage::test_jump()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -112,7 +112,7 @@ void tst_qquickage::test_onceOff()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -138,7 +138,7 @@ void tst_qquickage::test_sustained()
//TODO: Ensure some particles have lived to 0.4s point despite unified timer
//Can't verify size, because particles never die. It will constantly grow.
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp
index 4ff72f159d..b3fc01caa6 100644
--- a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp
+++ b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp
@@ -58,7 +58,7 @@ void tst_qquickangleddirection::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp
index 795fcaf42e..360b222367 100644
--- a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp
+++ b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp
@@ -57,7 +57,7 @@ void tst_qquickcumulativedirection::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
index fb15af4dd1..ee05fb29c9 100644
--- a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
+++ b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
@@ -59,7 +59,7 @@ void tst_qquickcustomaffector::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
//in CI the whole simulation often happens at once, so dead particles end up missing out
@@ -92,7 +92,7 @@ void tst_qquickcustomaffector::test_move()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
if (!d->stillAlive(system))
diff --git a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
index a722508a3e..60c6a37899 100644
--- a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
+++ b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
@@ -60,7 +60,7 @@ void tst_qquickcustomparticle::test_basic()
bool oneNonZero = false;
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp
index ac8e2bac49..a1fe5b225d 100644
--- a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp
+++ b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp
@@ -74,7 +74,7 @@ void tst_qquickellipseextruder::test_basic()
//Filled
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -91,7 +91,7 @@ void tst_qquickellipseextruder::test_basic()
//Just border
QCOMPARE(system->groupData[1]->size(), 500);
- foreach (QQuickParticleData *d, system->groupData[1]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp
index 70e0291330..ab682c591e 100644
--- a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp
+++ b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp
@@ -59,7 +59,7 @@ void tst_qquickfriction::test_basic()
//Default is just slowed a little
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -76,7 +76,7 @@ void tst_qquickfriction::test_basic()
//Nondefault comes to a complete stop within the first half of its life
QCOMPARE(system->groupData[1]->size(), 500);
- foreach (QQuickParticleData *d, system->groupData[1]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -103,7 +103,7 @@ void tst_qquickfriction::test_threshold()
//Velocity capped at 50, but it might take a frame or two to get there
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1.0f)
continue; //Particle data unused
if (myFuzzyGEQ(d->t, ((qreal)system->timeInt/1000.0) - 0.1))
diff --git a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp
index 8ef075dc9b..34566b90eb 100644
--- a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp
+++ b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp
@@ -58,7 +58,7 @@ void tst_qquickgravity::test_basic()
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
float mag = 707.10678f;
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1 || !d->stillAlive(system))
continue; //Particle data unused or dead
diff --git a/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp
index fc270b991f..1228b4cc68 100644
--- a/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp
+++ b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp
@@ -58,7 +58,7 @@ void tst_qquickgroupgoal::test_instantTransition()
ensureAnimTime(600, system->m_animation);
QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450);
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
index cd684ec59b..7e07878d39 100644
--- a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
+++ b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
@@ -72,7 +72,7 @@ void tst_qquickimageparticle::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -116,7 +116,7 @@ void tst_qquickimageparticle::test_colored()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -160,7 +160,7 @@ void tst_qquickimageparticle::test_colorVariance()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -205,7 +205,7 @@ void tst_qquickimageparticle::test_deformed()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -249,7 +249,7 @@ void tst_qquickimageparticle::test_tabled()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -294,7 +294,7 @@ void tst_qquickimageparticle::test_sprite()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp
index 98aac71e93..d9791cdb33 100644
--- a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp
+++ b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp
@@ -60,7 +60,7 @@ void tst_qquickitemparticle::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp
index 1f36874f0f..6baf8539d3 100644
--- a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp
+++ b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp
@@ -57,7 +57,7 @@ void tst_qquicklineextruder::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -73,7 +73,7 @@ void tst_qquicklineextruder::test_basic()
}
QCOMPARE(system->groupData[1]->size(), 500);
- foreach (QQuickParticleData *d, system->groupData[1]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp
index a3d0988019..d8481efc47 100644
--- a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp
+++ b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp
@@ -57,7 +57,7 @@ void tst_qquickmaskextruder::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp
index 8b7224623a..8791d19db6 100644
--- a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp
+++ b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp
@@ -58,7 +58,7 @@ void tst_qquickparticlegroup::test_instantTransition()
//A frame or two worth of particles will be missed, the transition doesn't take effect on the frame it's spawned (QTBUG-21781)
QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450);
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp
index 4a3c5cdc74..5c82b946e5 100644
--- a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp
+++ b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp
@@ -58,7 +58,7 @@ void tst_qquickparticlesystem::test_basic()
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
int stillAlive = 0;
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp
index 99a8530d3a..c0d7d38512 100644
--- a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp
+++ b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp
@@ -57,7 +57,7 @@ void tst_qquickpointattractor::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp
index 0d150fb86d..5cc23e0306 100644
--- a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp
+++ b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp
@@ -57,7 +57,7 @@ void tst_qquickpointdirection::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp
index 24b30bf9ab..414e2d36f7 100644
--- a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp
+++ b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp
@@ -57,7 +57,7 @@ void tst_qquickrectangleextruder::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -76,7 +76,7 @@ void tst_qquickrectangleextruder::test_basic()
}
QCOMPARE(system->groupData[1]->size(), 500);
- foreach (QQuickParticleData *d, system->groupData[1]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp
index 8249159e43..ca5d9171f9 100644
--- a/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp
+++ b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp
@@ -57,7 +57,7 @@ void tst_qquickspritegoal::test_instantTransition()
ensureAnimTime(600, system->m_animation);
QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450);
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp
index 8d9556fdac..2f45263c37 100644
--- a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp
+++ b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp
@@ -57,7 +57,7 @@ void tst_qquicktargetdirection::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
index 99ecd7a06a..27d9bf01c9 100644
--- a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
+++ b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
@@ -57,7 +57,7 @@ void tst_qquicktrailemitter::test_basic()
ensureAnimTime(600, system->m_animation);
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -74,7 +74,7 @@ void tst_qquicktrailemitter::test_basic()
}
QVERIFY(extremelyFuzzyCompare(system->groupData[1]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[1]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp
index c8024470e4..74fafdc1d2 100644
--- a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp
+++ b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp
@@ -59,7 +59,7 @@ void tst_qquickturbulence::test_basic()
//Note that the noise image built-in provides the 'randomness', so this test should be stable so long as it and the size
//of the Turbulence item remain the same
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/particles/qquickwander/tst_qquickwander.cpp b/tests/auto/particles/qquickwander/tst_qquickwander.cpp
index 6e37fc648c..51ef7a272e 100644
--- a/tests/auto/particles/qquickwander/tst_qquickwander.cpp
+++ b/tests/auto/particles/qquickwander/tst_qquickwander.cpp
@@ -61,7 +61,7 @@ void tst_qquickwander::test_basic()
//the 500 was randomly changed from 0.0 in velocity
bool vxChanged = false;
bool vyChanged = false;
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp
index ab8fa8a9ef..476ad2e955 100644
--- a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp
+++ b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp
@@ -63,8 +63,8 @@ private slots:
void tst_QParallelAnimationGroupJob::initTestCase()
{
qRegisterMetaType<QAbstractAnimationJob::State>("QAbstractAnimationJob::State");
-#if defined(Q_OS_MAC) || defined(Q_OS_WINCE)
- // give the mac/wince app start event queue time to clear
+#if defined(Q_OS_DARWIN)
+ // give the Apple application's start event queue time to clear
QTest::qWait(1000);
#endif
}
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index ccb2d71c53..a50411e18b 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -20,6 +20,6 @@ PRIVATETESTS += \
SUBDIRS += $$PUBLICTESTS
-contains(QT_CONFIG, private_tests) {
+qtConfig(private_tests): \
SUBDIRS += $$PRIVATETESTS
-}
+
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
index b800cc3715..d1150be831 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -42,11 +42,6 @@
#include <QtCore/qlibraryinfo.h>
#include <QtQml/qjsengine.h>
-#if defined (Q_OS_WINCE)
-#undef IN
-#undef OUT
-#endif
-
const char *V8REQUEST = "v8request";
const char *V8MESSAGE = "v8message";
const char *SEQ = "seq";
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index 4568d25dc1..40e19d375d 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -1223,16 +1223,15 @@ void tst_QQmlEngineDebugService::queryObjectTree()
int main(int argc, char *argv[])
{
int _argc = argc + 1;
- char **_argv = new char*[_argc];
+ QScopedArrayPointer<char *>_argv(new char*[_argc]);
for (int i = 0; i < argc; ++i)
_argv[i] = argv[i];
char arg[] = "-qmljsdebugger=port:3768,services:QmlDebugger";
_argv[_argc - 1] = arg;
- QGuiApplication app(_argc, _argv);
+ QGuiApplication app(_argc, _argv.data());
tst_QQmlEngineDebugService tc;
- return QTest::qExec(&tc, _argc, _argv);
- delete _argv;
+ return QTest::qExec(&tc, _argc, _argv.data());
}
#include "tst_qqmlenginedebugservice.moc"
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
index d1db2af367..dd7cb2055d 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
@@ -26,10 +26,10 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQml 2.0
-Rectangle {
- Timer {
+QtObject {
+ property var timer: Timer {
running: true
interval: 1
onTriggered: {
@@ -38,7 +38,7 @@ Rectangle {
}
}
- Timer {
+ property var stopTimer: Timer {
id: stopTimer
interval: 1000
onTriggered: {
@@ -47,7 +47,7 @@ Rectangle {
}
}
- Timer {
+ property var endTimer: Timer {
id: endTimer
interval: 1000
onTriggered: Qt.quit();
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
index b250524caa..4236d70ea3 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
@@ -1,6 +1,6 @@
-import QtQuick 2.0
+import QtQml 2.0
-Item {
+QtObject {
Timer {
running: true
interval: 1
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/javascript.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/javascript.qml
index 0555d49652..e25c7524f4 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/javascript.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/javascript.qml
@@ -1,6 +1,6 @@
-import QtQuick 2.0
+import QtQml 2.0
-Rectangle {
+QtObject {
function something(i) {
if (i > 10) {
something(i / 4);
@@ -9,8 +9,8 @@ Rectangle {
}
}
- width: 400
- height: 400
+ property int width: 400
+ property int height: 400
onWidthChanged: something(width);
Component.onCompleted: width = 500;
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/signalSourceLocation.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/signalSourceLocation.qml
index 25e63669c4..0eff9e9030 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/signalSourceLocation.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/signalSourceLocation.qml
@@ -1,8 +1,8 @@
-import QtQuick 2.0
+import QtQml 2.0
-Rectangle {
- width: 400
- height: 400
+QtObject {
+ property int width: 400
+ property int height: 400
onWidthChanged: console.log(width);
Component.onCompleted: width = 500;
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/test.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/test.qml
index 9c36e13c5b..5dd5caf12f 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/test.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/test.qml
@@ -1,5 +1,5 @@
-import QtQuick 2.0
+import QtQml 2.0
-Item {
+QtObject {
}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml
index 18b8947172..4af555a27b 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml
@@ -1,10 +1,10 @@
-import QtQuick 2.0
+import QtQml 2.0
-Rectangle {
- width: 100
- height: 62
+QtObject {
+ property int width: 100
+ property int height: 62
- Timer {
+ property var timer: Timer {
running: true
repeat: true
interval: 50
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index 4f9088d67d..c4b17aa60a 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -64,7 +64,8 @@ class QQmlProfilerTestClient : public QQmlProfilerClient
Q_OBJECT
public:
- QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection) {}
+ QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection),
+ lastTimestamp(-1) {}
QVector<QQmlProfilerData> qmlMessages;
QVector<QQmlProfilerData> javascriptMessages;
@@ -72,6 +73,8 @@ public:
QVector<QQmlProfilerData> asynchronousMessages;
QVector<QQmlProfilerData> pixmapMessages;
+ qint64 lastTimestamp;
+
signals:
void recordingFinished();
@@ -114,6 +117,8 @@ void QQmlProfilerTestClient::traceFinished(qint64 time, int engineId)
void QQmlProfilerTestClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
{
QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
+ QVERIFY(lastTimestamp <= startTime);
+ lastTimestamp = startTime;
QQmlProfilerData data(startTime, QQmlProfilerDefinitions::RangeStart, type);
if (type == QQmlProfilerDefinitions::Javascript)
javascriptMessages.append(data);
@@ -125,6 +130,8 @@ void QQmlProfilerTestClient::rangeData(QQmlProfilerDefinitions::RangeType type,
const QString &string)
{
QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
+ QVERIFY(lastTimestamp <= time);
+ lastTimestamp = time;
QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeData, type, string);
if (type == QQmlProfilerDefinitions::Javascript)
javascriptMessages.append(data);
@@ -137,6 +144,8 @@ void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType ty
{
QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
QVERIFY(location.line >= -2);
+ QVERIFY(lastTimestamp <= time);
+ lastTimestamp = time;
QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeLocation, type, location.filename);
data.line = location.line;
data.column = location.column;
@@ -149,6 +158,8 @@ void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType ty
void QQmlProfilerTestClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
{
QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
+ QVERIFY(lastTimestamp <= endTime);
+ lastTimestamp = endTime;
QQmlProfilerData data(endTime, QQmlProfilerDefinitions::RangeEnd, type);
if (type == QQmlProfilerDefinitions::Javascript)
javascriptMessages.append(data);
@@ -161,6 +172,8 @@ void QQmlProfilerTestClient::animationFrame(qint64 time, int frameRate, int anim
QVERIFY(threadId >= 0);
QVERIFY(frameRate != -1);
QVERIFY(animationCount != -1);
+ QVERIFY(lastTimestamp <= time);
+ lastTimestamp = time;
QQmlProfilerData data(time, QQmlProfilerDefinitions::Event,
QQmlProfilerDefinitions::AnimationFrame);
data.framerate = frameRate;
@@ -178,6 +191,8 @@ void QQmlProfilerTestClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraph
Q_UNUSED(numericData3);
Q_UNUSED(numericData4);
Q_UNUSED(numericData5);
+ QVERIFY(lastTimestamp <= time);
+ lastTimestamp = time;
asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::SceneGraphFrame,
type));
}
@@ -186,6 +201,8 @@ void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEve
qint64 time, const QString &url, int numericData1,
int numericData2)
{
+ QVERIFY(lastTimestamp <= time);
+ lastTimestamp = time;
QQmlProfilerData data(time, QQmlProfilerDefinitions::PixmapCacheEvent, type, url);
switch (type) {
case QQmlProfilerDefinitions::PixmapSizeKnown:
@@ -205,6 +222,8 @@ void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEve
void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
qint64 amount)
{
+ QVERIFY(lastTimestamp <= time);
+ lastTimestamp = time;
QQmlProfilerData data(time, QQmlProfilerDefinitions::MemoryAllocation, type);
data.amount = amount;
jsHeapMessages.append(data);
@@ -213,6 +232,8 @@ void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryTyp
void QQmlProfilerTestClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
int a, int b)
{
+ QVERIFY(lastTimestamp <= time);
+ lastTimestamp = time;
qmlMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, type,
QString::number(a) + QLatin1Char('x') +
QString::number(b)));
@@ -597,7 +618,7 @@ void tst_QQmlProfilerService::scenegraphData()
// if the clocks are acting up.
qint64 contextFrameTime = -1;
qint64 renderFrameTime = -1;
-
+#ifndef QT_NO_OPENGL //Software renderer doesn't have context frames
foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
if (msg.messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
if (msg.detailType == QQmlProfilerDefinitions::SceneGraphContextFrame) {
@@ -608,7 +629,7 @@ void tst_QQmlProfilerService::scenegraphData()
}
QVERIFY(contextFrameTime != -1);
-
+#endif
foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
QVERIFY(msg.time >= contextFrameTime);
@@ -667,11 +688,11 @@ void tst_QQmlProfilerService::signalSourceLocation()
QLatin1String("signalSourceLocation.qml"));
expected.line = 8;
expected.column = 28;
- VERIFY(MessageListQML, 13, expected, CheckAll);
+ VERIFY(MessageListQML, 9, expected, CheckAll);
expected.line = 7;
expected.column = 21;
- VERIFY(MessageListQML, 15, expected, CheckAll);
+ VERIFY(MessageListQML, 11, expected, CheckAll);
}
void tst_QQmlProfilerService::javascript()
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 3f89913f3b..a23b7e37eb 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -326,7 +326,7 @@ private slots:
private:
QV4Debugger *debugger() const
{
- return static_cast<QV4Debugger *>(m_v4->debugger);
+ return static_cast<QV4Debugger *>(m_v4->debugger());
}
void evaluateJavaScript(const QString &script, const QString &fileName, int lineNumber = 1)
{
@@ -444,7 +444,7 @@ void tst_qv4debugger::addBreakPointWhilePaused()
static QV4::ReturnedValue someCall(QV4::CallContext *ctx)
{
- static_cast<QV4Debugger *>(ctx->d()->engine->debugger)
+ static_cast<QV4Debugger *>(ctx->d()->engine->debugger())
->removeBreakPoint("removeBreakPointForNextInstruction", 2);
return QV4::Encode::undefined();
}
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index 6fe5d897e0..1ec0a6513d 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -135,8 +135,6 @@ public:
int lastResponseId;
bool lastResult;
-public slots:
-
void recordResponse(int requestId, bool result)
{
lastResponseId = requestId;
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index e8cff9affe..52df4c0642 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -73,6 +73,7 @@ private slots:
void newQObject();
void newQObject_ownership();
void newQObject_deletedEngine();
+ void newQMetaObject();
void exceptionInSlot();
void globalObjectProperties();
void globalObjectEquals();
@@ -124,6 +125,7 @@ private slots:
void jsIncDecNonObjectProperty();
void JSONparse();
void arraySort();
+ void lookupOnDisappearingProperty();
void qRegExpInport_data();
void qRegExpInport();
@@ -192,6 +194,8 @@ private slots:
void withNoContext();
void holeInPropertyData();
+ void basicBlockMergeAfterLoopPeeling();
+
void malformedExpression();
signals:
@@ -718,6 +722,104 @@ void tst_QJSEngine::newQObject_deletedEngine()
QTRY_VERIFY(spy.count());
}
+class TestQMetaObject : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(int called READ called)
+public:
+ enum Enum1 {
+ Zero = 0,
+ One,
+ Two
+ };
+ enum Enum2 {
+ A = 0,
+ B,
+ C
+ };
+ Q_ENUMS(Enum1 Enum2)
+
+ Q_INVOKABLE TestQMetaObject()
+ : m_called(1) {
+ }
+ Q_INVOKABLE TestQMetaObject(int)
+ : m_called(2) {
+ }
+ Q_INVOKABLE TestQMetaObject(QString)
+ : m_called(3) {
+ }
+ Q_INVOKABLE TestQMetaObject(QString, int)
+ : m_called(4) {
+ }
+ int called() const {
+ return m_called;
+ }
+private:
+ int m_called;
+};
+
+void tst_QJSEngine::newQMetaObject() {
+ {
+ QJSEngine engine;
+ QJSValue metaObject = engine.newQMetaObject(&TestQMetaObject::staticMetaObject);
+ QCOMPARE(metaObject.isNull(), false);
+ QCOMPARE(metaObject.isObject(), true);
+ QCOMPARE(metaObject.isQObject(), false);
+ QCOMPARE(metaObject.isCallable(), true);
+ QCOMPARE(metaObject.isQMetaObject(), true);
+
+ QCOMPARE(metaObject.toQMetaObject(), &TestQMetaObject::staticMetaObject);
+
+ QVERIFY(metaObject.strictlyEquals(engine.newQMetaObject<TestQMetaObject>()));
+
+
+ {
+ auto result = metaObject.callAsConstructor();
+ if (result.isError())
+ qDebug() << result.toString();
+ QCOMPARE(result.isError(), false);
+ QCOMPARE(result.isNull(), false);
+ QCOMPARE(result.isObject(), true);
+ QCOMPARE(result.isQObject(), true);
+ QVERIFY(result.property("constructor").strictlyEquals(metaObject));
+ QVERIFY(result.prototype().strictlyEquals(metaObject));
+
+
+ QCOMPARE(result.property("called").toInt(), 1);
+
+ }
+
+ QJSValue integer(42);
+ QJSValue string("foo");
+
+ {
+ auto result = metaObject.callAsConstructor({integer});
+ QCOMPARE(result.property("called").toInt(), 2);
+ }
+
+ {
+ auto result = metaObject.callAsConstructor({string});
+ QCOMPARE(result.property("called").toInt(), 3);
+ }
+
+ {
+ auto result = metaObject.callAsConstructor({string, integer});
+ QCOMPARE(result.property("called").toInt(), 4);
+ }
+ }
+
+ {
+ QJSEngine engine;
+ QJSValue metaObject = engine.newQMetaObject(&TestQMetaObject::staticMetaObject);
+ QCOMPARE(metaObject.property("Zero").toInt(), 0);
+ QCOMPARE(metaObject.property("One").toInt(), 1);
+ QCOMPARE(metaObject.property("Two").toInt(), 2);
+ QCOMPARE(metaObject.property("A").toInt(), 0);
+ QCOMPARE(metaObject.property("B").toInt(), 1);
+ QCOMPARE(metaObject.property("C").toInt(), 2);
+ }
+
+}
+
void tst_QJSEngine::exceptionInSlot()
{
QJSEngine engine;
@@ -1031,11 +1133,14 @@ void tst_QJSEngine::builtinFunctionNames_data()
QTest::newRow("Math.pow") << QString("Math.pow") << QString("pow");
QTest::newRow("Math.random") << QString("Math.random") << QString("random");
QTest::newRow("Math.round") << QString("Math.round") << QString("round");
+ QTest::newRow("Math.sign") << QString("Math.sign") << QString("sign");
QTest::newRow("Math.sin") << QString("Math.sin") << QString("sin");
QTest::newRow("Math.sqrt") << QString("Math.sqrt") << QString("sqrt");
QTest::newRow("Math.tan") << QString("Math.tan") << QString("tan");
QTest::newRow("Number") << QString("Number") << QString("Number");
+ QTest::newRow("Number.isFinite") << QString("Number.isFinite") << QString("isFinite");
+ QTest::newRow("Number.isNaN") << QString("Number.isNaN") << QString("isNaN");
QTest::newRow("Number.prototype.toString") << QString("Number.prototype.toString") << QString("toString");
QTest::newRow("Number.prototype.toLocaleString") << QString("Number.prototype.toLocaleString") << QString("toLocaleString");
QTest::newRow("Number.prototype.valueOf") << QString("Number.prototype.valueOf") << QString("valueOf");
@@ -1064,6 +1169,8 @@ void tst_QJSEngine::builtinFunctionNames_data()
QTest::newRow("String.prototype.charAt") << QString("String.prototype.charAt") << QString("charAt");
QTest::newRow("String.prototype.charCodeAt") << QString("String.prototype.charCodeAt") << QString("charCodeAt");
QTest::newRow("String.prototype.concat") << QString("String.prototype.concat") << QString("concat");
+ QTest::newRow("String.prototype.endsWith") << QString("String.prototype.endsWith") << QString("endsWith");
+ QTest::newRow("String.prototype.includes") << QString("String.prototype.includes") << QString("includes");
QTest::newRow("String.prototype.indexOf") << QString("String.prototype.indexOf") << QString("indexOf");
QTest::newRow("String.prototype.lastIndexOf") << QString("String.prototype.lastIndexOf") << QString("lastIndexOf");
QTest::newRow("String.prototype.localeCompare") << QString("String.prototype.localeCompare") << QString("localeCompare");
@@ -1072,6 +1179,7 @@ void tst_QJSEngine::builtinFunctionNames_data()
QTest::newRow("String.prototype.search") << QString("String.prototype.search") << QString("search");
QTest::newRow("String.prototype.slice") << QString("String.prototype.slice") << QString("slice");
QTest::newRow("String.prototype.split") << QString("String.prototype.split") << QString("split");
+ QTest::newRow("String.prototype.startsWith") << QString("String.prototype.startsWith") << QString("startsWith");
QTest::newRow("String.prototype.substring") << QString("String.prototype.substring") << QString("substring");
QTest::newRow("String.prototype.toLowerCase") << QString("String.prototype.toLowerCase") << QString("toLowerCase");
QTest::newRow("String.prototype.toLocaleLowerCase") << QString("String.prototype.toLocaleLowerCase") << QString("toLocaleLowerCase");
@@ -1343,6 +1451,7 @@ void tst_QJSEngine::valueConversion_QVariant()
QCOMPARE(qjsvalue_cast<QVariant>(QJSValue(123)), QVariant(123));
QVERIFY(eng.toScriptValue(QVariant(QMetaType::VoidStar, 0)).isNull());
+ QVERIFY(eng.toScriptValue(QVariant::fromValue(nullptr)).isNull());
{
QVariantMap map;
@@ -1924,6 +2033,7 @@ void tst_QJSEngine::jsNumberClass()
QVERIFY(ctor.property("NaN").isNumber());
QVERIFY(ctor.property("NEGATIVE_INFINITY").isNumber());
QVERIFY(ctor.property("POSITIVE_INFINITY").isNumber());
+ QVERIFY(ctor.property("EPSILON").isNumber());
}
QCOMPARE(proto.toNumber(), qreal(0));
QVERIFY(proto.property("constructor").strictlyEquals(ctor));
@@ -1962,6 +2072,50 @@ void tst_QJSEngine::jsNumberClass()
QCOMPARE(ret.toNumber(), qreal(456));
}
+ QVERIFY(ctor.property("isFinite").isCallable());
+ {
+ QJSValue ret = eng.evaluate("Number.isFinite()");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), false);
+ }
+ {
+ QJSValue ret = eng.evaluate("Number.isFinite(NaN)");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), false);
+ }
+ {
+ QJSValue ret = eng.evaluate("Number.isFinite(Infinity)");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), false);
+ }
+ {
+ QJSValue ret = eng.evaluate("Number.isFinite(-Infinity)");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), false);
+ }
+ {
+ QJSValue ret = eng.evaluate("Number.isFinite(123)");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), true);
+ }
+
+ QVERIFY(ctor.property("isNaN").isCallable());
+ {
+ QJSValue ret = eng.evaluate("Number.isNaN()");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), false);
+ }
+ {
+ QJSValue ret = eng.evaluate("Number.isNaN(NaN)");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), true);
+ }
+ {
+ QJSValue ret = eng.evaluate("Number.isNaN(123)");
+ QVERIFY(ret.isBool());
+ QCOMPARE(ret.toBool(), false);
+ }
+
QVERIFY(proto.property("toString").isCallable());
{
QJSValue ret = eng.evaluate("new Number(123).toString()");
@@ -2815,6 +2969,22 @@ void tst_QJSEngine::arraySort()
"crashMe();");
}
+void tst_QJSEngine::lookupOnDisappearingProperty()
+{
+ QJSEngine eng;
+ QJSValue func = eng.evaluate("(function(){\"use strict\"; return eval(\"function(obj) { return obj.someProperty; }\")})()");
+ QVERIFY(func.isCallable());
+
+ QJSValue o = eng.newObject();
+ o.setProperty(QStringLiteral("someProperty"), 42);
+
+ QCOMPARE(func.call(QJSValueList()<< o).toInt(), 42);
+
+ o = eng.newObject();
+ QVERIFY(func.call(QJSValueList()<< o).isUndefined());
+ QVERIFY(func.call(QJSValueList()<< o).isUndefined());
+}
+
static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; }
void tst_QJSEngine::qRegExpInport_data()
@@ -3878,6 +4048,22 @@ void tst_QJSEngine::holeInPropertyData()
QVERIFY(ok.toBool());
}
+void tst_QJSEngine::basicBlockMergeAfterLoopPeeling()
+{
+ QJSEngine engine;
+ QJSValue ok = engine.evaluate(
+ "function crashMe() {\n"
+ " var seen = false;\n"
+ " while (globalVar) {\n"
+ " if (seen)\n"
+ " return;\n"
+ " seen = true;\n"
+ " }\n"
+ "}\n");
+ QVERIFY(!ok.isCallable());
+
+}
+
void tst_QJSEngine::malformedExpression()
{
QJSEngine engine;
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index 58f0344c58..12c33909cf 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -431,6 +431,12 @@ void tst_QJSValue::toString()
QVERIFY(!o.engine());
QCOMPARE(o.toString(), QStringLiteral("1,2,3"));
}
+
+ {
+ QByteArray hello = QByteArrayLiteral("Hello World");
+ QJSValue jsValue = eng.toScriptValue(hello);
+ QCOMPARE(jsValue.toString(), QString::fromUtf8(hello));
+ }
}
void tst_QJSValue::toNumber()
@@ -978,8 +984,8 @@ void tst_QJSValue::toVariant()
QCOMPARE(qjsvalue_cast<QVariant>(undefined), QVariant());
QJSValue null = eng.evaluate("null");
- QCOMPARE(null.toVariant(), QVariant(QMetaType::VoidStar, 0));
- QCOMPARE(qjsvalue_cast<QVariant>(null), QVariant(QMetaType::VoidStar, 0));
+ QCOMPARE(null.toVariant(), QVariant::fromValue(nullptr));
+ QCOMPARE(qjsvalue_cast<QVariant>(null), QVariant::fromValue(nullptr));
{
QJSValue number = eng.toScriptValue(123.0);
@@ -1055,8 +1061,8 @@ void tst_QJSValue::toVariant()
QCOMPARE(qjsvalue_cast<QVariant>(undef), QVariant());
QJSValue nil = QJSValue(QJSValue::NullValue);
- QCOMPARE(nil.toVariant(), QVariant(QMetaType::VoidStar, 0));
- QCOMPARE(qjsvalue_cast<QVariant>(nil), QVariant(QMetaType::VoidStar, 0));
+ QCOMPARE(nil.toVariant(), QVariant::fromValue(nullptr));
+ QCOMPARE(qjsvalue_cast<QVariant>(nil), QVariant::fromValue(nullptr));
}
// array
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index 28f04be5d7..68a2eace19 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -8,7 +8,6 @@ PUBLICTESTS += \
qjsvalueiterator \
qjsonbinding \
qmlmin \
- qmlplugindump \
qqmlcomponent \
qqmlconsole \
qqmlengine \
@@ -61,7 +60,9 @@ PRIVATETESTS += \
v4misc \
qqmltranslation \
qqmlimport \
- qqmlobjectmodel
+ qqmlobjectmodel \
+ qmldiskcache \
+ qv4mm
qtHaveModule(widgets) {
PUBLICTESTS += \
@@ -72,14 +73,13 @@ qtHaveModule(widgets) {
SUBDIRS += $$PUBLICTESTS \
qqmlextensionplugin
SUBDIRS += $$METATYPETESTS
-!winrt { # no QProcess on winrt
+!uikit:!winrt { # no QProcess on uikit/winrt
!contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger
- SUBDIRS += qmllint
+ SUBDIRS += qmllint qmlplugindump
}
-contains(QT_CONFIG, private_tests) {
+qtConfig(private_tests): \
SUBDIRS += $$PRIVATETESTS
-}
qtNomakeTools( \
qmlplugindump \
diff --git a/tests/auto/qml/qmldiskcache/qmldiskcache.pro b/tests/auto/qml/qmldiskcache/qmldiskcache.pro
new file mode 100644
index 0000000000..f98a157b6a
--- /dev/null
+++ b/tests/auto/qml/qmldiskcache/qmldiskcache.pro
@@ -0,0 +1,9 @@
+CONFIG += testcase
+TARGET = tst_qmldiskcache
+osx:CONFIG -= app_bundle
+
+SOURCES += tst_qmldiskcache.cpp
+
+RESOURCES += test.qml
+
+QT += core-private qml-private testlib
diff --git a/tests/auto/qml/qmldiskcache/test.qml b/tests/auto/qml/qmldiskcache/test.qml
new file mode 100644
index 0000000000..d632422616
--- /dev/null
+++ b/tests/auto/qml/qmldiskcache/test.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property int value: 20
+}
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
new file mode 100644
index 0000000000..8af446173d
--- /dev/null
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -0,0 +1,694 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+
+#include <private/qv4compileddata_p.h>
+#include <private/qv4compiler_p.h>
+#include <private/qv4jsir_p.h>
+#include <private/qv4isel_p.h>
+#include <private/qv8engine_p.h>
+#include <private/qv4engine_p.h>
+#include <QQmlComponent>
+#include <QQmlEngine>
+#include <QQmlFileSelector>
+#include <QThread>
+#include <QCryptographicHash>
+#include <QStandardPaths>
+#include <QDirIterator>
+
+class tst_qmldiskcache: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+
+ void regenerateAfterChange();
+ void registerImportForImplicitComponent();
+ void basicVersionChecks();
+ void recompileAfterChange();
+ void fileSelectors();
+ void localAliases();
+ void cacheResources();
+ void stableOrderOfDependentCompositeTypes();
+};
+
+// A wrapper around QQmlComponent to ensure the temporary reference counts
+// on the type data as a result of the main thread <> loader thread communication
+// are dropped. Regular Synchronous loading will leave us with an event posted
+// to the gui thread and an extra refcount that will only be dropped after the
+// event delivery. A plain sendPostedEvents() however is insufficient because
+// we can't be sure that the event is posted after the constructor finished.
+class CleanlyLoadingComponent : public QQmlComponent
+{
+public:
+ CleanlyLoadingComponent(QQmlEngine *engine, const QUrl &url)
+ : QQmlComponent(engine, url, QQmlComponent::Asynchronous)
+ { waitForLoad(); }
+ CleanlyLoadingComponent(QQmlEngine *engine, const QString &fileName)
+ : QQmlComponent(engine, fileName, QQmlComponent::Asynchronous)
+ { waitForLoad(); }
+
+ void waitForLoad()
+ {
+ QTRY_VERIFY(status() == QQmlComponent::Ready || status() == QQmlComponent::Error);
+ }
+};
+
+static void waitForFileSystem()
+{
+ // On macOS with HFS+ the precision of file times is measured in seconds, so to ensure that
+ // the newly written file has a modification date newer than an existing cache file, we must
+ // wait.
+ // Similar effects of lacking precision have been observed on some Linux systems.
+ QThread::sleep(1);
+}
+
+struct TestCompiler
+{
+ TestCompiler(QQmlEngine *engine)
+ : engine(engine)
+ , tempDir()
+ , testFilePath(tempDir.path() + QStringLiteral("/test.qml"))
+ , cacheFilePath(tempDir.path() + QStringLiteral("/test.qmlc"))
+ , mappedFile(cacheFilePath)
+ , currentMapping(nullptr)
+ {
+ }
+
+ bool compile(const QByteArray &contents)
+ {
+ closeMapping();
+ engine->clearComponentCache();
+
+ waitForFileSystem();
+
+ {
+ QFile f(testFilePath);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ lastErrorString = f.errorString();
+ return false;
+ }
+ if (f.write(contents) != contents.size()) {
+ lastErrorString = f.errorString();
+ return false;
+ }
+ }
+
+ CleanlyLoadingComponent component(engine, testFilePath);
+ if (!component.isReady()) {
+ lastErrorString = component.errorString();
+ return false;
+ }
+
+ return true;
+ }
+
+ const QV4::CompiledData::Unit *mapUnit()
+ {
+ if (!mappedFile.open(QIODevice::ReadOnly)) {
+ lastErrorString = mappedFile.errorString();
+ return nullptr;
+ }
+
+ currentMapping = mappedFile.map(/*offset*/0, mappedFile.size());
+ if (!currentMapping) {
+ lastErrorString = mappedFile.errorString();
+ return nullptr;
+ }
+ QV4::CompiledData::Unit *unitPtr;
+ memcpy(&unitPtr, &currentMapping, sizeof(unitPtr));
+ return unitPtr;
+ }
+
+ typedef void (*HeaderTweakFunction)(QV4::CompiledData::Unit *header);
+ bool tweakHeader(HeaderTweakFunction function)
+ {
+ closeMapping();
+
+ QFile f(cacheFilePath);
+ if (!f.open(QIODevice::ReadWrite))
+ return false;
+ QV4::CompiledData::Unit header;
+ if (f.read(reinterpret_cast<char *>(&header), sizeof(header)) != sizeof(header))
+ return false;
+ function(&header);
+ f.seek(0);
+ return f.write(reinterpret_cast<const char *>(&header), sizeof(header)) == sizeof(header);
+ }
+
+ bool verify()
+ {
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
+ return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), v4->iselFactory.data(), &lastErrorString);
+ }
+
+ void closeMapping()
+ {
+ if (currentMapping) {
+ mappedFile.unmap(currentMapping);
+ currentMapping = nullptr;
+ }
+ mappedFile.close();
+ }
+
+ void clearCache()
+ {
+ closeMapping();
+ QFile::remove(cacheFilePath);
+ }
+
+ QQmlEngine *engine;
+ const QTemporaryDir tempDir;
+ const QString testFilePath;
+ const QString cacheFilePath;
+ QString lastErrorString;
+ QFile mappedFile;
+ uchar *currentMapping;
+};
+
+void tst_qmldiskcache::initTestCase()
+{
+ qputenv("QML_FORCE_DISK_CACHE", "1");
+}
+
+void tst_qmldiskcache::regenerateAfterChange()
+{
+ QQmlEngine engine;
+ TestCompiler testCompiler(&engine);
+
+ QVERIFY(testCompiler.tempDir.isValid());
+
+ const QByteArray contents = QByteArrayLiteral("import QtQml 2.0\n"
+ "QtObject {\n"
+ " property string blah: Qt.platform;\n"
+ "}");
+
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+
+ {
+ const QV4::CompiledData::Unit *testUnit = testCompiler.mapUnit();
+ QVERIFY2(testUnit, qPrintable(testCompiler.lastErrorString));
+
+ QCOMPARE(quint32(testUnit->nObjects), quint32(1));
+
+ const QV4::CompiledData::Object *obj = testUnit->objectAt(0);
+ QCOMPARE(quint32(obj->nBindings), quint32(1));
+ QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Script));
+ QCOMPARE(quint32(obj->bindingTable()->value.compiledScriptIndex), quint32(1));
+
+ QCOMPARE(quint32(testUnit->functionTableSize), quint32(2));
+
+ const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(1);
+ QVERIFY(bindingFunction->codeOffset > testUnit->unitSize);
+ }
+
+ {
+ const QByteArray newContents = QByteArrayLiteral("import QtQml 2.0\n"
+ "QtObject {\n"
+ " property string blah: Qt.platform;\n"
+ " property int secondProperty: 42;\n"
+ "}");
+
+ QVERIFY2(testCompiler.compile(newContents), qPrintable(testCompiler.lastErrorString));
+ const QV4::CompiledData::Unit *testUnit = testCompiler.mapUnit();
+ QVERIFY2(testUnit, qPrintable(testCompiler.lastErrorString));
+
+ QCOMPARE(quint32(testUnit->nObjects), quint32(1));
+
+ const QV4::CompiledData::Object *obj = testUnit->objectAt(0);
+ QCOMPARE(quint32(obj->nBindings), quint32(2));
+ QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Number));
+ QCOMPARE(obj->bindingTable()->valueAsNumber(), double(42));
+
+ QCOMPARE(quint32(testUnit->functionTableSize), quint32(2));
+
+ const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(1);
+ QVERIFY(bindingFunction->codeOffset > testUnit->unitSize);
+ }
+}
+
+void tst_qmldiskcache::registerImportForImplicitComponent()
+{
+ QQmlEngine engine;
+
+ TestCompiler testCompiler(&engine);
+ QVERIFY(testCompiler.tempDir.isValid());
+
+ const QByteArray contents = QByteArrayLiteral("import QtQuick 2.0\n"
+ "Loader {\n"
+ " sourceComponent: Item {}\n"
+ "}");
+
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+ {
+ const QV4::CompiledData::Unit *testUnit = testCompiler.mapUnit();
+ QVERIFY2(testUnit, qPrintable(testCompiler.lastErrorString));
+
+ QCOMPARE(quint32(testUnit->nImports), quint32(2));
+ QCOMPARE(testUnit->stringAt(testUnit->importAt(0)->uriIndex), QStringLiteral("QtQuick"));
+
+ QQmlType *componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
+
+ QCOMPARE(testUnit->stringAt(testUnit->importAt(1)->uriIndex), QString(componentType->module()));
+ QCOMPARE(testUnit->stringAt(testUnit->importAt(1)->qualifierIndex), QStringLiteral("QmlInternals"));
+
+ QCOMPARE(quint32(testUnit->nObjects), quint32(3));
+
+ const QV4::CompiledData::Object *obj = testUnit->objectAt(0);
+ QCOMPARE(quint32(obj->nBindings), quint32(1));
+ QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Object));
+
+ const QV4::CompiledData::Object *implicitComponent = testUnit->objectAt(obj->bindingTable()->value.objectIndex);
+ QCOMPARE(testUnit->stringAt(implicitComponent->inheritedTypeNameIndex), QStringLiteral("QmlInternals.") + componentType->elementName());
+ }
+}
+
+void tst_qmldiskcache::basicVersionChecks()
+{
+ QQmlEngine engine;
+
+ TestCompiler testCompiler(&engine);
+ QVERIFY(testCompiler.tempDir.isValid());
+
+ const QByteArray contents = QByteArrayLiteral("import QtQml 2.0\n"
+ "QtObject {\n"
+ " property string blah: Qt.platform;\n"
+ "}");
+
+ {
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+ QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString));
+ }
+
+ {
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+
+ testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
+ header->qtVersion = 0;
+ });
+
+ QVERIFY(!testCompiler.verify());
+ QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("Qt version mismatch. Found 0 expected %1").arg(QT_VERSION, 0, 16));
+ testCompiler.clearCache();
+ }
+
+ {
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+
+ testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
+ header->version = 0;
+ });
+
+ QVERIFY(!testCompiler.verify());
+ QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("V4 data structure version mismatch. Found 0 expected %1").arg(QV4_DATA_STRUCTURE_VERSION, 0, 16));
+ }
+
+ {
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+
+ testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
+ header->architectureIndex = 0;
+ });
+
+ QVERIFY(!testCompiler.verify());
+ QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("Architecture mismatch. Found expected %1").arg(QSysInfo::buildAbi()));
+ }
+
+ {
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+
+ testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
+ header->codeGeneratorIndex = 0;
+ });
+
+ QVERIFY(!testCompiler.verify());
+ QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("Code generator mismatch. Found code generated by but expected %1").arg(QV8Engine::getV4(&engine)->iselFactory->codeGeneratorName));
+ }
+}
+
+class TypeVersion1 : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged);
+public:
+
+
+ int m_value = 0;
+ int value() const { return m_value; }
+ void setValue(int v) { m_value = v; emit valueChanged(); }
+
+signals:
+ void valueChanged();
+};
+
+// Same as TypeVersion1 except the property type changed!
+class TypeVersion2 : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString value READ value WRITE setValue NOTIFY valueChanged);
+public:
+
+
+ QString m_value;
+ QString value() const { return m_value; }
+ void setValue(QString v) { m_value = v; emit valueChanged(); }
+
+signals:
+ void valueChanged();
+};
+
+void tst_qmldiskcache::recompileAfterChange()
+{
+ QQmlEngine engine;
+
+ TestCompiler testCompiler(&engine);
+ QVERIFY(testCompiler.tempDir.isValid());
+
+ const QByteArray contents = QByteArrayLiteral("import TypeTest 1.0\n"
+ "TypeThatWillChange {\n"
+ "}");
+
+ qmlRegisterType<TypeVersion1>("TypeTest", 1, 0, "TypeThatWillChange");
+
+ {
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+ QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString));
+ }
+
+ QDateTime initialCacheTimeStamp = QFileInfo(testCompiler.cacheFilePath).lastModified();
+
+ {
+ CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
+ QScopedPointer<TypeVersion1> obj(qobject_cast<TypeVersion1*>(component.create()));
+ QVERIFY(!obj.isNull());
+ QCOMPARE(QFileInfo(testCompiler.cacheFilePath).lastModified(), initialCacheTimeStamp);
+ }
+
+ engine.clearComponentCache();
+
+ {
+ CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
+ QScopedPointer<TypeVersion1> obj(qobject_cast<TypeVersion1*>(component.create()));
+ QVERIFY(!obj.isNull());
+ QCOMPARE(QFileInfo(testCompiler.cacheFilePath).lastModified(), initialCacheTimeStamp);
+ }
+
+ engine.clearComponentCache();
+ qmlClearTypeRegistrations();
+ qmlRegisterType<TypeVersion2>("TypeTest", 1, 0, "TypeThatWillChange");
+
+ waitForFileSystem();
+
+ {
+ CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
+ QScopedPointer<TypeVersion2> obj(qobject_cast<TypeVersion2*>(component.create()));
+ QVERIFY(!obj.isNull());
+ QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp);
+ }
+}
+
+void tst_qmldiskcache::fileSelectors()
+{
+ QQmlEngine engine;
+
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ const QString testFilePath = tempDir.path() + "/test.qml";
+ {
+ QFile f(testFilePath);
+ QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
+ f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 42 }"));
+ }
+
+ const QString selector = QStringLiteral("testSelector");
+ const QString selectorPath = tempDir.path() + "/+" + selector;
+ const QString selectedTestFilePath = selectorPath + "/test.qml";
+ {
+ QVERIFY(QDir::root().mkpath(selectorPath));
+ QFile f(selectorPath + "/test.qml");
+ QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
+ f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 100 }"));
+ }
+
+ {
+ QQmlComponent component(&engine, testFilePath);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 42);
+
+ QFile cacheFile(testFilePath + "c");
+ QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName()));
+ }
+
+ QQmlFileSelector qmlSelector(&engine);
+ qmlSelector.setExtraSelectors(QStringList() << selector);
+
+ engine.clearComponentCache();
+
+ {
+ QQmlComponent component(&engine, testFilePath);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 100);
+
+ QFile cacheFile(selectedTestFilePath + "c");
+ QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName()));
+ }
+}
+
+void tst_qmldiskcache::localAliases()
+{
+ QQmlEngine engine;
+
+ TestCompiler testCompiler(&engine);
+ QVERIFY(testCompiler.tempDir.isValid());
+
+ const QByteArray contents = QByteArrayLiteral("import QtQml 2.0\n"
+ "QtObject {\n"
+ " id: root\n"
+ " property int prop: 100\n"
+ " property alias dummy1: root.prop\n"
+ " property alias dummy2: root.prop\n"
+ " property alias dummy3: root.prop\n"
+ " property alias dummy4: root.prop\n"
+ " property alias dummy5: root.prop\n"
+ " property alias foo: root.prop\n"
+ " property alias bar: root.foo\n"
+ "}");
+
+ {
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+ QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString));
+ }
+
+ {
+ CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("bar").toInt(), 100);
+ }
+
+ engine.clearComponentCache();
+
+ {
+ CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("bar").toInt(), 100);
+ }
+}
+
+void tst_qmldiskcache::cacheResources()
+{
+ const QString cacheDirectory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ QVERIFY(QDir::root().mkpath(cacheDirectory));
+
+ const QString qmlCacheDirectory = cacheDirectory + QLatin1String("/qmlcache/");
+ QVERIFY(QDir(qmlCacheDirectory).removeRecursively());
+ QVERIFY(QDir::root().mkpath(qmlCacheDirectory));
+ QVERIFY(QDir(qmlCacheDirectory).entryList(QDir::NoDotAndDotDot).isEmpty());
+
+
+ QQmlEngine engine;
+
+ {
+ CleanlyLoadingComponent component(&engine, QUrl("qrc:/test.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 20);
+ }
+
+ const QStringList entries = QDir(qmlCacheDirectory).entryList(QDir::NoDotAndDotDot | QDir::Files);
+ QCOMPARE(entries.count(), 1);
+
+ QDateTime cacheFileTimeStamp;
+
+ {
+ QFile cacheFile(qmlCacheDirectory + QLatin1Char('/') + entries.constFirst());
+ QVERIFY2(cacheFile.open(QIODevice::ReadOnly), qPrintable(cacheFile.errorString()));
+ QV4::CompiledData::Unit unit;
+ QVERIFY(cacheFile.read(reinterpret_cast<char *>(&unit), sizeof(unit)) == sizeof(unit));
+
+ cacheFileTimeStamp = QFileInfo(cacheFile.fileName()).lastModified();
+
+ QDateTime referenceTimeStamp = QFileInfo(":/test.qml").lastModified();
+ if (!referenceTimeStamp.isValid())
+ referenceTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified();
+ QCOMPARE(qint64(unit.sourceTimeStamp), referenceTimeStamp.toMSecsSinceEpoch());
+ }
+
+ waitForFileSystem();
+
+ {
+ CleanlyLoadingComponent component(&engine, QUrl("qrc:///test.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 20);
+ }
+
+ {
+ const QStringList entries = QDir(qmlCacheDirectory).entryList(QDir::NoDotAndDotDot | QDir::Files);
+ QCOMPARE(entries.count(), 1);
+
+ QCOMPARE(QFileInfo(qmlCacheDirectory + QLatin1Char('/') + entries.constFirst()).lastModified().toMSecsSinceEpoch(), cacheFileTimeStamp.toMSecsSinceEpoch());
+ }
+}
+
+void tst_qmldiskcache::stableOrderOfDependentCompositeTypes()
+{
+ QQmlEngine engine;
+
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ {
+ const QString depFilePath = tempDir.path() + "/FirstDependentType.qml";
+ QFile f(depFilePath);
+ QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
+ f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 42 }"));
+ }
+
+ {
+ const QString depFilePath = tempDir.path() + "/SecondDependentType.qml";
+ QFile f(depFilePath);
+ QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
+ f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 100 }"));
+ }
+
+ const QString testFilePath = tempDir.path() + "/main.qml";
+ {
+ QFile f(testFilePath);
+ QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
+ f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject {\n"
+ " property QtObject dep1: FirstDependentType{}\n"
+ " property QtObject dep2: SecondDependentType{}\n"
+ " property int value: dep1.value + dep2.value\n"
+ "}"));
+ }
+
+ QByteArray firstDependentTypeClassName;
+ QByteArray secondDependentTypeClassName;
+
+ {
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 142);
+
+ firstDependentTypeClassName = qvariant_cast<QObject *>(obj->property("dep1"))->metaObject()->className();
+ secondDependentTypeClassName = qvariant_cast<QObject *>(obj->property("dep2"))->metaObject()->className();
+ }
+
+ QVERIFY(firstDependentTypeClassName != secondDependentTypeClassName);
+ QVERIFY2(firstDependentTypeClassName.contains("QMLTYPE"), firstDependentTypeClassName.constData());
+ QVERIFY2(secondDependentTypeClassName.contains("QMLTYPE"), secondDependentTypeClassName.constData());
+
+ const QString testFileCachePath = testFilePath + QLatin1Char('c');
+ QVERIFY(QFile::exists(testFileCachePath));
+ QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();
+
+ engine.clearComponentCache();
+ waitForFileSystem();
+
+ // Creating the test component a second time should load it from the cache (same time stamp),
+ // despite the class names of the dependent composite types differing.
+ {
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 142);
+
+ QVERIFY(qvariant_cast<QObject *>(obj->property("dep1"))->metaObject()->className() != firstDependentTypeClassName);
+ QVERIFY(qvariant_cast<QObject *>(obj->property("dep2"))->metaObject()->className() != secondDependentTypeClassName);
+ }
+
+ {
+ QVERIFY(QFile::exists(testFileCachePath));
+ QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();
+ QCOMPARE(newCacheTimeStamp, initialCacheTimeStamp);
+ }
+
+ // Now change the first dependent QML type and see if we correctly re-generate the
+ // caches.
+ engine.clearComponentCache();
+ waitForFileSystem();
+ {
+ const QString depFilePath = tempDir.path() + "/FirstDependentType.qml";
+ QFile f(depFilePath);
+ QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
+ f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 40 }"));
+ }
+
+ {
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 140);
+ }
+
+ {
+ QVERIFY(QFile::exists(testFileCachePath));
+ QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();
+ QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString()));
+ }
+}
+
+QTEST_MAIN(tst_qmldiskcache)
+
+#include "tst_qmldiskcache.moc"
diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
index ee417bb480..838966e2a0 100644
--- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
+++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
@@ -108,6 +108,7 @@ void tst_qmlplugindump::singleton()
dumper.waitForFinished();
const QString &result = dumper.readAllStandardOutput();
+ qDebug() << "result: " << result;
QVERIFY(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]")));
QVERIFY(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")));
}
diff --git a/tests/auto/qml/qqmlbinding/data/delayed.qml b/tests/auto/qml/qqmlbinding/data/delayed.qml
new file mode 100644
index 0000000000..6f8281cc33
--- /dev/null
+++ b/tests/auto/qml/qqmlbinding/data/delayed.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.8
+
+Item {
+ width: 400
+ height: 400
+
+ property int changeCount: 0
+
+ property string text1
+ property string text2
+
+ function updateText() {
+ text1 = "Hello"
+ text2 = "World"
+ }
+
+ Text {
+ anchors.centerIn: parent
+ Binding on text {
+ value: text1 + " " + text2
+ delayed: true
+ }
+ onTextChanged: ++changeCount
+ }
+}
+
diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
index 3e8dfbdb12..6f1d82eca5 100644
--- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
+++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
@@ -49,6 +49,7 @@ private slots:
void warningOnReadOnlyProperty();
void disabledOnUnknownProperty();
void disabledOnReadonlyProperty();
+ void delayed();
private:
QQmlEngine engine;
@@ -281,6 +282,27 @@ void tst_qqmlbinding::disabledOnReadonlyProperty()
QCOMPARE(messageHandler.messages().count(), 0);
}
+void tst_qqmlbinding::delayed()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("delayed.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+
+ QVERIFY(item != 0);
+ // update on creation
+ QCOMPARE(item->property("changeCount").toInt(), 1);
+
+ QMetaObject::invokeMethod(item, "updateText");
+ // doesn't update immediately
+ QCOMPARE(item->property("changeCount").toInt(), 1);
+
+ QCoreApplication::processEvents();
+ // only updates once (non-delayed would update twice)
+ QCOMPARE(item->property("changeCount").toInt(), 2);
+
+ delete item;
+}
+
QTEST_MAIN(tst_qqmlbinding)
#include "tst_qqmlbinding.moc"
diff --git a/tests/auto/qml/qqmlconsole/data/categorized_logging.qml b/tests/auto/qml/qqmlconsole/data/categorized_logging.qml
new file mode 100644
index 0000000000..d19b6ecc41
--- /dev/null
+++ b/tests/auto/qml/qqmlconsole/data/categorized_logging.qml
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+
+Item {
+ id:root
+
+ LoggingCategory {
+ id: testCategory
+ name: "qt.test"
+ }
+
+ LoggingCategory {
+ id: emptyCategory
+ }
+
+ Component.onCompleted: {
+ console.debug(testCategory, "console.debug");
+ console.log(testCategory, "console.log");
+ console.info(testCategory, "console.info");
+ console.warn(testCategory, "console.warn");
+ console.error(testCategory, "console.error");
+
+ testCategory.name = "qt.test2";
+
+ console.error(emptyCategory, "console.error");
+ }
+}
diff --git a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
index f12656c5fe..f832143935 100644
--- a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
+++ b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
@@ -40,6 +40,7 @@ public:
private slots:
void logging();
+ void categorized_logging();
void tracing();
void profiling();
void testAssert();
@@ -87,6 +88,41 @@ void tst_qqmlconsole::logging()
delete object;
}
+void tst_qqmlconsole::categorized_logging()
+{
+ QUrl testUrl = testFileUrl("categorized_logging.qml");
+ QQmlTestMessageHandler messageHandler;
+ messageHandler.setIncludeCategoriesEnabled(true);
+
+ QLoggingCategory testCategory("qt.test");
+ testCategory.setEnabled(QtDebugMsg, true);
+ QVERIFY(testCategory.isDebugEnabled());
+ QVERIFY(testCategory.isWarningEnabled());
+ QVERIFY(testCategory.isCriticalEnabled());
+
+ QQmlComponent component(&engine, testUrl);
+ QObject *object = component.create();
+ QVERIFY2(object != 0, component.errorString().toUtf8());
+
+ QVERIFY(messageHandler.messages().contains("qt.test: console.info"));
+ QVERIFY(messageHandler.messages().contains("qt.test: console.warn"));
+ QVERIFY(messageHandler.messages().contains("qt.test: console.error"));
+
+ QString emptyCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(50).arg(5) +
+ "QML LoggingCategory: Declaring the name of the LoggingCategory is mandatory and cannot be changed later !";
+ QVERIFY(messageHandler.messages().contains(emptyCategory));
+
+ QString changedCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(45).arg(5) +
+ "QML LoggingCategory: The name of a LoggingCategory cannot be changed after the Item is created";
+ QVERIFY(messageHandler.messages().contains(changedCategory));
+
+ QString useEmptyCategory = "default: " + QString::fromLatin1("%1:%2: ").arg(testUrl.toString()).arg(63) +
+ "Error: A QmlLoggingCatgory was provided without a valid name";
+ QVERIFY(messageHandler.messages().contains(useEmptyCategory));
+
+ delete object;
+}
+
void tst_qqmlconsole::tracing()
{
QUrl testUrl = testFileUrl("tracing.qml");
diff --git a/tests/auto/qml/qqmlecmascript/data/NullObjectInitializerBase.qml b/tests/auto/qml/qqmlecmascript/data/NullObjectInitializerBase.qml
new file mode 100644
index 0000000000..4006a2a782
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/NullObjectInitializerBase.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+QtObject {
+ property Component factory: Component { QtObject {} }
+ property QtObject testProperty: factory.createObject()
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/dependenciesWithFunctions.qml b/tests/auto/qml/qqmlecmascript/data/dependenciesWithFunctions.qml
new file mode 100644
index 0000000000..57d3ae2f14
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/dependenciesWithFunctions.qml
@@ -0,0 +1,12 @@
+import QtQml 2.0
+QtObject {
+ property int value: 100
+ property bool success: {
+ unrelatedFunction();
+ return value == 42;
+ }
+ property int unrelatedValue: 100
+ function unrelatedFunction() {
+ return unrelatedValue;
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.2.qml b/tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.2.qml
new file mode 100644
index 0000000000..d59f8f99f9
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.2.qml
@@ -0,0 +1,8 @@
+import QtQml 2.0
+NullObjectInitializerBase {
+ testProperty: null
+ property bool success: false
+ Component.onCompleted: {
+ success = testProperty === null;
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.qml b/tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.qml
new file mode 100644
index 0000000000..32bc62c9f2
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/nullObjectInitializer.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property QtObject testProperty: null
+}
diff --git a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
index 684e7adb98..101181bba0 100644
--- a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
+++ b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
@@ -13,11 +13,6 @@ RESOURCES += qqmlecmascript.qrc
include (../../shared/util.pri)
-greaterThan(QT_GCC_MAJOR_VERSION, 5) {
- # Our code is bad. Temporary workaround. Fixed in 5.8
- QMAKE_CXXFLAGS += -fno-delete-null-pointer-checks -fno-lifetime-dse
-}
-
# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
# LIBS += -lgcov
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index d4d051443f..47fb2a56e7 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -790,7 +790,8 @@ public:
Q_INVOKABLE void method_QObject(QObject *a) { invoke(13); m_actuals << qVariantFromValue(a); }
Q_INVOKABLE void method_QScriptValue(QJSValue a) { invoke(14); m_actuals << qVariantFromValue(a); }
Q_INVOKABLE void method_intQScriptValue(int a, QJSValue b) { invoke(15); m_actuals << a << qVariantFromValue(b); }
- Q_INVOKABLE QJSValue method_intQJSValue(int a, QJSValue b) { invoke(29); m_actuals << a << qVariantFromValue(b); return b.call(); }
+ Q_INVOKABLE void method_QByteArray(QByteArray value) { invoke(29); m_actuals << value; }
+ Q_INVOKABLE QJSValue method_intQJSValue(int a, QJSValue b) { invoke(30); m_actuals << a << qVariantFromValue(b); return b.call(); }
Q_INVOKABLE QJSValue method_intQJSValue(int a, int b) { m_actuals << a << b; return QJSValue();} // Should never be called.
Q_INVOKABLE void method_overload(int a) { invoke(16); m_actuals << a; }
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 26a15d730c..be04ec2bf3 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -84,6 +84,7 @@ private slots:
void arrayExpressions();
void contextPropertiesTriggerReeval();
void objectPropertiesTriggerReeval();
+ void dependenciesWithFunctions();
void deferredProperties();
void deferredPropertiesErrors();
void deferredPropertiesInComponents();
@@ -210,6 +211,7 @@ private slots:
void dynamicCreationOwnership();
void regExpBug();
void nullObjectBinding();
+ void nullObjectInitializer();
void deletedEngine();
void libraryScriptAssert();
void variantsAssignedUndefined();
@@ -881,6 +883,18 @@ void tst_qqmlecmascript::objectPropertiesTriggerReeval()
}
}
+void tst_qqmlecmascript::dependenciesWithFunctions()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("dependenciesWithFunctions.qml"));
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY2(object, qPrintable(component.errorString()));
+ QVERIFY(!object->property("success").toBool());
+ object->setProperty("value", 42);
+ QVERIFY(object->property("success").toBool());
+}
+
void tst_qqmlecmascript::deferredProperties()
{
QQmlComponent component(&engine, testFileUrl("deferredProperties.qml"));
@@ -2318,7 +2332,7 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
QV4::ScopedCallData d(scope, 1);
d->args[0] = o;
d->thisObject = engine->global();
- function->call(d);
+ function->call(scope, d);
if (scope.engine->hasException) {
scope.engine->catchException();
return true;
@@ -2344,16 +2358,15 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
if (!function)
return false;
- QV4::ScopedValue value(scope);
QV4::ScopedCallData d(scope, 1);
d->args[0] = o;
d->thisObject = engine->global();
- value = function->call(d);
+ function->call(scope, d);
if (scope.engine->hasException) {
scope.engine->catchException();
return false;
}
- return QV4::Runtime::strictEqual(value, result);
+ return QV4::Runtime::method_strictEqual(scope.result, result);
}
static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::Value &o,
@@ -2377,12 +2390,12 @@ static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::Value &o
QV4::ScopedCallData d(scope, 1);
d->args[0] = o;
d->thisObject = engine->global();
- QV4::ScopedValue result(scope, function->call(d));
+ function->call(scope, d);
if (scope.engine->hasException) {
scope.engine->catchException();
return QV4::Encode::undefined();
}
- return result->asReturnedValue();
+ return scope.result.asReturnedValue();
}
#define EVALUATE_ERROR(source) evaluate_error(engine, object, source)
@@ -2946,9 +2959,16 @@ void tst_qqmlecmascript::callQtInvokables()
QCOMPARE(o->actuals().count(), 0);
o->reset();
- QV4::ScopedValue ret(scope, EVALUATE("object.method_intQJSValue(123, function() { return \"Hello world!\";})"));
+ QVERIFY(EVALUATE_VALUE("object.method_QByteArray(\"Hello\")", QV4::Primitive::undefinedValue()));
QCOMPARE(o->error(), false);
QCOMPARE(o->invoked(), 29);
+ QCOMPARE(o->actuals().count(), 1);
+ QCOMPARE(qvariant_cast<QByteArray>(o->actuals().at(0)), QByteArray("Hello"));
+
+ o->reset();
+ QV4::ScopedValue ret(scope, EVALUATE("object.method_intQJSValue(123, function() { return \"Hello world!\";})"));
+ QCOMPARE(o->error(), false);
+ QCOMPARE(o->invoked(), 30);
QVERIFY(ret->isString());
QCOMPARE(ret->toQStringNoThrow(), QString("Hello world!"));
QCOMPARE(o->actuals().count(), 2);
@@ -5707,6 +5727,49 @@ void tst_qqmlecmascript::nullObjectBinding()
delete object;
}
+void tst_qqmlecmascript::nullObjectInitializer()
+{
+ {
+ QQmlComponent component(&engine, testFileUrl("nullObjectInitializer.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ QQmlData *ddata = QQmlData::get(obj.data(), /*create*/false);
+ QVERIFY(ddata);
+
+ {
+ const int propertyIndex = obj->metaObject()->indexOfProperty("testProperty");
+ QVERIFY(propertyIndex > 0);
+ QVERIFY(!ddata->hasBindingBit(propertyIndex));
+ }
+
+ QVariant value = obj->property("testProperty");
+ QVERIFY(value.userType() == qMetaTypeId<QObject*>());
+ QVERIFY(!value.value<QObject*>());
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("nullObjectInitializer.2.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ QQmlData *ddata = QQmlData::get(obj.data(), /*create*/false);
+ QVERIFY(ddata);
+
+ {
+ const int propertyIndex = obj->metaObject()->indexOfProperty("testProperty");
+ QVERIFY(propertyIndex > 0);
+ QVERIFY(ddata->hasBindingBit(propertyIndex));
+ }
+
+ QVERIFY(obj->property("success").toBool());
+
+ QVariant value = obj->property("testProperty");
+ QVERIFY(value.userType() == qMetaTypeId<QObject*>());
+ QVERIFY(!value.value<QObject*>());
+ }
+}
+
// Test that bindings don't evaluate once the engine has been destroyed
void tst_qqmlecmascript::deletedEngine()
{
@@ -5768,7 +5831,7 @@ void tst_qqmlecmascript::variants()
QVERIFY(object != 0);
QCOMPARE(object->property("undefinedVariant").type(), QVariant::Invalid);
- QCOMPARE(int(object->property("nullVariant").type()), int(QMetaType::VoidStar));
+ QCOMPARE(int(object->property("nullVariant").type()), int(QMetaType::Nullptr));
QCOMPARE(object->property("intVariant").type(), QVariant::Int);
QCOMPARE(object->property("doubleVariant").type(), QVariant::Double);
@@ -7196,14 +7259,16 @@ namespace QV4 {
namespace Heap {
struct WeakReferenceSentinel : public Object {
- WeakReferenceSentinel(WeakValue *weakRef, bool *resultPtr)
- : weakRef(weakRef)
- , resultPtr(resultPtr) {
-
+ void init(WeakValue *weakRef, bool *resultPtr)
+ {
+ Object::init();
+ this->weakRef = weakRef;
+ this->resultPtr = resultPtr;
}
- ~WeakReferenceSentinel() {
+ void destroy() {
*resultPtr = weakRef->isNullOrUndefined();
+ Object::destroy();
}
WeakValue *weakRef;
diff --git a/tests/auto/qml/qqmlengine/data/qtqmlModule.4.qml b/tests/auto/qml/qqmlengine/data/qtqmlModule.4.qml
index 9b9b7922da..94ee46ddf0 100644
--- a/tests/auto/qml/qqmlengine/data/qtqmlModule.4.qml
+++ b/tests/auto/qml/qqmlengine/data/qtqmlModule.4.qml
@@ -1,4 +1,4 @@
-import QtQml 2.5
+import QtQml 2.50
QtObject {
}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index 3208745c5c..9c155eda5b 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -275,6 +275,12 @@ void tst_qqmlengine::clearComponentCache()
// Modify qml file
{
+ // On macOS with HFS+ the precision of file times is measured in seconds, so to ensure that
+ // the newly written file has a modification date newer than an existing cache file, we must
+ // wait.
+ // Similar effects of lacking precision have been observed on some Linux systems.
+ QThread::sleep(1);
+
QFile file("temp.qml");
QVERIFY(file.open(QIODevice::WriteOnly));
file.write("import QtQuick 2.0\nQtObject {\nproperty int test: 11\n}\n");
@@ -317,6 +323,11 @@ public:
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
QCoreApplication::processEvents();
+ // There might be JS function objects around that hold a last ref to the compilation unit that's
+ // keeping the type compilation data (CompilationUnit) around. Let's collect them as well so that
+ // trim works well.
+ engine->collectGarbage();
+
engine->trimComponentCache();
}
@@ -615,9 +626,9 @@ void tst_qqmlengine::qtqmlModule_data()
<< QString(testFileUrl("qtqmlModule.3.qml").toString() + QLatin1String(":1 module \"QtQml\" version 1.0 is not installed\n"))
<< QStringList();
- QTest::newRow("import QtQml of incorrect version (2.5)")
+ QTest::newRow("import QtQml of incorrect version (2.50)")
<< testFileUrl("qtqmlModule.4.qml")
- << QString(testFileUrl("qtqmlModule.4.qml").toString() + QLatin1String(":1 module \"QtQml\" version 2.5 is not installed\n"))
+ << QString(testFileUrl("qtqmlModule.4.qml").toString() + QLatin1String(":1 module \"QtQml\" version 2.50 is not installed\n"))
<< QStringList();
QTest::newRow("QtQml 2.0 module provides Component, QtObject, Connections, Binding and Timer")
diff --git a/tests/auto/qml/qqmlenginecleanup/data/types.qml b/tests/auto/qml/qqmlenginecleanup/data/types.qml
index 3d27900744..7282c7dbfb 100644
--- a/tests/auto/qml/qqmlenginecleanup/data/types.qml
+++ b/tests/auto/qml/qqmlenginecleanup/data/types.qml
@@ -29,7 +29,7 @@
import QtQml 2.0
import QtQuick 2.0
import QtQuick.Window 2.0
-import QtQuick.Particles 2.0
+
import Test 2.0
import "."
@@ -37,7 +37,6 @@ QtObject {
//Doesn't create items, just checks that the types are accessible
property TestType tt
property TestTypeCpp ttc
- property ParticleSystem ps
property Window wi
property Item it
}
diff --git a/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp b/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
index bd44bd7c8b..124a107a37 100644
--- a/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
+++ b/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
@@ -109,7 +109,7 @@ void tst_qqmlextensionplugin::iidCheck()
QFETCH(QString, filePath);
QPluginLoader loader(filePath);
- QVERIFY(loader.load());
+ QVERIFY2(loader.load(), qPrintable(loader.errorString()));
QVERIFY(loader.instance() != Q_NULLPTR);
if (qobject_cast<QQmlExtensionPlugin *>(loader.instance())) {
diff --git a/tests/auto/qml/qqmllanguage/data/QtObjectWithChildren.qml b/tests/auto/qml/qqmllanguage/data/QtObjectWithChildren.qml
new file mode 100644
index 0000000000..bb28e22110
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/QtObjectWithChildren.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ default property list<QtObject> myChildren;
+}
diff --git a/tests/auto/qml/qqmllanguage/data/alias.12.qml b/tests/auto/qml/qqmllanguage/data/alias.12.qml
new file mode 100644
index 0000000000..cc17318092
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.12.qml
@@ -0,0 +1,15 @@
+import QtQml 2.0
+
+QtObject {
+ id: root
+ property alias topLevelAlias: subObject.targetProperty
+
+ property QtObject referencingSubObject: QtObject {
+ property alias success: root.topLevelAlias
+ }
+
+ property QtObject foo: QtObject {
+ id: subObject
+ property bool targetProperty: true
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/alias.13.qml b/tests/auto/qml/qqmllanguage/data/alias.13.qml
new file mode 100644
index 0000000000..cff8a72d9a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.13.qml
@@ -0,0 +1,16 @@
+import QtQml 2.0
+
+QtObject {
+ id: root
+ property bool targetProperty: true
+
+ property QtObject foo: QtObject {
+ id: otherSubObject
+ property alias theAlias: root.targetProperty
+ }
+
+ property QtObject referencingSubObject: QtObject {
+ property alias success: otherSubObject.theAlias
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt b/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt
new file mode 100644
index 0000000000..90a3ea4317
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt
@@ -0,0 +1 @@
+10:34:References to other aliases within the same object are not supported at the moment
diff --git a/tests/auto/qml/qqmllanguage/data/alias.14.qml b/tests/auto/qml/qqmllanguage/data/alias.14.qml
new file mode 100644
index 0000000000..ff3c36d990
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.14.qml
@@ -0,0 +1,17 @@
+import QtQml 2.0
+
+QtObject {
+ id: root
+ property bool targetProperty: true
+
+ property QtObject foo: QtObject {
+ id: otherSubObject
+ property alias theAliasOrigin: root.targetProperty
+ property alias theAlias: otherSubObject.theAliasOrigin
+ }
+
+ property QtObject referencingSubObject: QtObject {
+ property alias success: otherSubObject.theAlias
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml
new file mode 100644
index 0000000000..b64a2e23c0
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.7
+import Test 1.0
+
+MyArrayBufferTestClass {
+ property bool ok: false
+ Component.onCompleted: {
+ var data = new Uint8Array([1, 2, 3]);
+ var sum = byteArrayMethod_Sum(data.buffer);
+ ok = sum == 6;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml
new file mode 100644
index 0000000000..9e1c91810a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.7
+import Test 1.0
+
+MyArrayBufferTestClass {
+ property bool ok: false
+ Component.onCompleted: ok = byteArrayMethod_Overloaded(new ArrayBuffer());
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml
new file mode 100644
index 0000000000..5a4f9fec0b
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.7
+import Test 1.0
+
+MyArrayBufferTestClass {
+ property bool ok: false
+ Component.onCompleted: {
+ var buf = byteArrayMethod_CountUp(1, 3);
+ var view = new DataView(buf);
+ ok = buf instanceof ArrayBuffer
+ && buf.byteLength == 3
+ && view.getUint8(0) == 1
+ && view.getUint8(1) == 2
+ && view.getUint8(2) == 3;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml
new file mode 100644
index 0000000000..78ebb1abe1
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml
@@ -0,0 +1,5 @@
+import Test 1.0
+
+MyArrayBufferTestClass {
+ property bool ok: byteArrayProperty instanceof ArrayBuffer
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml
new file mode 100644
index 0000000000..e8a51273ca
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.7
+import Test 1.0
+
+MyArrayBufferTestClass {
+ property bool ok: false
+ onByteArraySignal: ok = byteArrayProperty instanceof ArrayBuffer
+ Component.onCompleted: {
+ byteArrayProperty = new ArrayBuffer(42);
+ ok = byteArrayProperty instanceof ArrayBuffer && byteArrayProperty.byteLength == 42;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml
new file mode 100644
index 0000000000..d9f436e788
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.7
+import Test 1.0
+
+MyArrayBufferTestClass {
+ property bool ok: false
+ onByteArraySignal: {
+ var view = new DataView(arg);
+ ok = arg instanceof ArrayBuffer
+ && arg.byteLength == 2
+ && view.getUint8(0) == 42
+ && view.getUint8(1) == 43;
+ }
+ Component.onCompleted: emitByteArraySignal(42, 2)
+}
diff --git a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt
index 7a75447a62..acf0d1da84 100644
--- a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt
@@ -1,2 +1,2 @@
3:1:Type RegisteredCompositeType2 unavailable
--1:-1:File not found
+-1:-1:No such file or directory
diff --git a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
index e1daf3b78f..efedf2b14a 100644
--- a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
+++ b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
@@ -1,4 +1,5 @@
import Test 1.0
MyNamespacedType {
+ myEnum: MyNamespace.Key5
}
diff --git a/tests/auto/qml/qqmllanguage/data/defaultListProperty.qml b/tests/auto/qml/qqmllanguage/data/defaultListProperty.qml
new file mode 100644
index 0000000000..d68ffd2979
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/defaultListProperty.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+
+QtObjectWithChildren {
+ QtObject {
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidAlias.11.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.errors.txt
new file mode 100644
index 0000000000..b79b660c46
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.errors.txt
@@ -0,0 +1 @@
+5:5:Circular alias reference detected
diff --git a/tests/auto/qml/qqmllanguage/data/invalidAlias.11.qml b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.qml
new file mode 100644
index 0000000000..9b50b48df8
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.qml
@@ -0,0 +1,10 @@
+import QtQml 2.0
+
+QtObject {
+ id: root
+ property alias a: subObject.b
+ property QtObject foo: QtObject {
+ id: subObject
+ property alias b: root.a
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/rootItemIsComponent.qml b/tests/auto/qml/qqmllanguage/data/rootItemIsComponent.qml
new file mode 100644
index 0000000000..dd653352d9
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/rootItemIsComponent.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+Component {
+ QtObject {
+ id: blah
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singletonTest10.error.txt b/tests/auto/qml/qqmllanguage/data/singletonTest10.error.txt
deleted file mode 100644
index 32d2ed857e..0000000000
--- a/tests/auto/qml/qqmllanguage/data/singletonTest10.error.txt
+++ /dev/null
@@ -1 +0,0 @@
-4:1:Composite Singleton Type SingletonType is not creatable.
diff --git a/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt b/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt
index 716cf5709a..b3082d80e6 100644
--- a/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt
+++ b/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt
@@ -1,2 +1,2 @@
5:5:Type RegisteredCompositeType unavailable
-2:1:pragma Singleton used with a non composite singleton type CompositeSingletonTest/RegisteredCompositeType
+-1:-1:pragma Singleton used with a non composite singleton type CompositeSingletonTest/RegisteredCompositeType
diff --git a/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt b/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt
index 77c26df310..ebeab6987b 100644
--- a/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt
+++ b/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt
@@ -1 +1 @@
-2:1:No matching type found, pragma Singleton files cannot be used by QQmlComponent.
+-1:-1:No matching type found, pragma Singleton files cannot be used by QQmlComponent.
diff --git a/tests/auto/qml/qqmllanguage/data/uncreatableTypeAsProperty.qml b/tests/auto/qml/qqmllanguage/data/uncreatableTypeAsProperty.qml
new file mode 100644
index 0000000000..8369ab1eea
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/uncreatableTypeAsProperty.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+import Test 1.0
+
+QtObject {
+ property MyUncreateableBaseClass someProperty;
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 9593bfc940..3af7645ff7 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -27,8 +27,6 @@
****************************************************************************/
#include "testtypes.h"
-#include <private/qqmlcompiler_p.h>
-
static QObject *myTypeObjectSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
@@ -47,6 +45,7 @@ void registerTypes()
qmlRegisterType<MyDotPropertyObject>("Test",1,0,"MyDotPropertyObject");
qmlRegisterType<MyNamespace::MyNamespacedType>("Test",1,0,"MyNamespacedType");
qmlRegisterType<MyNamespace::MySecondNamespacedType>("Test",1,0,"MySecondNamespacedType");
+ qmlRegisterUncreatableMetaObject(MyNamespace::staticMetaObject, "Test", 1, 0, "MyNamespace", "Access to enums & flags only");
qmlRegisterType<MyParserStatus>("Test",1,0,"MyParserStatus");
qmlRegisterType<MyGroupedObject>();
qmlRegisterType<MyRevisionedClass>("Test",1,0,"MyRevisionedClass");
@@ -98,6 +97,8 @@ void registerTypes()
qmlRegisterType<MyCompositeBaseType>("Test", 1, 0, "MyCompositeBaseType");
qmlRegisterSingletonType<MyTypeObjectSingleton>("Test", 1, 0, "MyTypeObjectSingleton", myTypeObjectSingleton);
+
+ qmlRegisterType<MyArrayBufferTestClass>("Test", 1, 0, "MyArrayBufferTestClass");
}
QVariant myCustomVariantTypeConverter(const QString &data)
@@ -108,11 +109,11 @@ QVariant myCustomVariantTypeConverter(const QString &data)
}
-void CustomBindingParser::applyBindings(QObject *object, QQmlCompiledData *cdata, const QList<const QV4::CompiledData::Binding *> &bindings)
+void CustomBindingParser::applyBindings(QObject *object, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
{
CustomBinding *customBinding = qobject_cast<CustomBinding*>(object);
Q_ASSERT(customBinding);
- customBinding->cdata = cdata;
+ customBinding->compilationUnit = compilationUnit;
customBinding->bindings = bindings;
}
@@ -121,17 +122,18 @@ void CustomBinding::componentComplete()
Q_ASSERT(m_target);
foreach (const QV4::CompiledData::Binding *binding, bindings) {
- QString name = cdata->compilationUnit->data->stringAt(binding->propertyNameIndex);
+ QString name = compilationUnit->data->stringAt(binding->propertyNameIndex);
int bindingId = binding->value.compiledScriptIndex;
QQmlContextData *context = QQmlContextData::get(qmlContext(this));
QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this)));
- QV4::ScopedValue function(scope, QV4::FunctionObject::createQmlFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId]));
- QQmlBinding *qmlBinding = new QQmlBinding(function, m_target, context);
+ QV4::ScopedValue function(scope, QV4::FunctionObject::createQmlFunction(context, m_target, compilationUnit->runtimeFunctions[bindingId]));
QQmlProperty property(m_target, name, qmlContext(this));
+ QQmlBinding *qmlBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core,
+ function, m_target, context);
qmlBinding->setTarget(property);
QQmlPropertyPrivate::setBinding(property, qmlBinding);
}
@@ -167,7 +169,7 @@ void EnumSupportingCustomParser::verifyBindings(const QV4::CompiledData::Unit *q
}
}
-void SimpleObjectCustomParser::applyBindings(QObject *object, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &bindings)
+void SimpleObjectCustomParser::applyBindings(QObject *object, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &bindings)
{
SimpleObjectWithCustomParser *o = qobject_cast<SimpleObjectWithCustomParser*>(object);
Q_ASSERT(o);
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 337ba91532..6c62bcf7b9 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -43,7 +43,6 @@
#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);
@@ -731,9 +730,19 @@ private:
namespace MyNamespace {
+ Q_NAMESPACE
+ enum MyNSEnum {
+ Key1 = 1,
+ Key2,
+ Key5 = 5
+ };
+ Q_ENUM_NS(MyNSEnum);
+
class MyNamespacedType : public QObject
{
Q_OBJECT
+ Q_PROPERTY(MyNamespace::MyNSEnum myEnum MEMBER m_myEnum)
+ MyNamespace::MyNSEnum m_myEnum = MyNSEnum::Key1;
};
class MySecondNamespacedType : public QObject
@@ -757,14 +766,14 @@ class MyCustomParserTypeParser : public QQmlCustomParser
{
public:
virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &) {}
- virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
};
class EnumSupportingCustomParser : public QQmlCustomParser
{
public:
virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &);
- virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
};
class MyParserStatus : public QObject, public QQmlParserStatus
@@ -1114,6 +1123,58 @@ public:
static QObject *qmlAttachedProperties(QObject *parent) { return new QObject(parent); }
};
+class MyArrayBufferTestClass : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty NOTIFY byteArrayPropertyChanged)
+
+signals:
+ void byteArrayPropertyChanged();
+ void byteArraySignal(QByteArray arg);
+
+public:
+ QByteArray byteArrayPropertyValue;
+ QByteArray byteArrayProperty() const {
+ return byteArrayPropertyValue;
+ }
+ void setByteArrayProperty(const QByteArray &v) {
+ byteArrayPropertyValue = v;
+ emit byteArrayPropertyChanged();
+ }
+ Q_INVOKABLE void emitByteArraySignal(char begin, char num) {
+ byteArraySignal(byteArrayMethod_CountUp(begin, num));
+ }
+ Q_INVOKABLE int byteArrayMethod_Sum(QByteArray arg) {
+ int sum = 0;
+ for (int i = 0; i < arg.size(); ++i) {
+ sum += arg[i];
+ }
+ return sum;
+ }
+ Q_INVOKABLE QByteArray byteArrayMethod_CountUp(char begin, int num) {
+ QByteArray ret;
+ for (int i = 0; i < num; ++i) {
+ ret.push_back(begin++);
+ }
+ return ret;
+ }
+ Q_INVOKABLE bool byteArrayMethod_Overloaded(QByteArray) {
+ return true;
+ }
+ Q_INVOKABLE bool byteArrayMethod_Overloaded(int) {
+ return false;
+ }
+ Q_INVOKABLE bool byteArrayMethod_Overloaded(QString) {
+ return false;
+ }
+ Q_INVOKABLE bool byteArrayMethod_Overloaded(QJSValue) {
+ return false;
+ }
+ Q_INVOKABLE bool byteArrayMethod_Overloaded(QVariant) {
+ return false;
+ }
+};
+
Q_DECLARE_METATYPE(MyEnum2Class::EnumB)
Q_DECLARE_METATYPE(MyEnum1Class::EnumA)
Q_DECLARE_METATYPE(Qt::TextFormat)
@@ -1142,7 +1203,7 @@ public:
void setTarget(QObject *newTarget) { m_target = newTarget; }
QPointer<QObject> m_target;
- QQmlRefPointer<QQmlCompiledData> cdata;
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
QList<const QV4::CompiledData::Binding*> bindings;
QByteArray m_bindingData;
};
@@ -1150,7 +1211,7 @@ public:
class CustomBindingParser : public QQmlCustomParser
{
virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &) {}
- virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &);
+ virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &);
};
class SimpleObjectWithCustomParser : public QObject
@@ -1196,7 +1257,7 @@ private:
class SimpleObjectCustomParser : public QQmlCustomParser
{
virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &) {}
- virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &);
+ virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, 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 4e4b939e8b..658b4f5852 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -108,6 +108,7 @@ private slots:
void bindTypeToJSValue();
void customParserTypes();
void rootAsQmlComponent();
+ void rootItemIsComponent();
void inlineQmlComponents();
void idProperty();
void autoNotifyConnection();
@@ -188,6 +189,8 @@ private slots:
void subclassedUncreateableRevision_data();
void subclassedUncreateableRevision();
+ void uncreatableTypesAsProperties();
+
void propertyInit();
void remoteLoadCrash();
void signalWithDefaultArg();
@@ -246,10 +249,13 @@ private slots:
void earlyIdObjectAccess();
- void dataAlignment();
-
void deleteSingletons();
+ void arrayBuffer_data();
+ void arrayBuffer();
+
+ void defaultListProperty();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -490,6 +496,7 @@ void tst_qqmllanguage::errors_data()
QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
+ QTest::newRow("invalidAlias.11") << "invalidAlias.11.qml" << "invalidAlias.11.errors.txt" << false;
QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
@@ -1193,6 +1200,19 @@ void tst_qqmllanguage::rootAsQmlComponent()
QCOMPARE(object->getChildren()->count(), 2);
}
+void tst_qqmllanguage::rootItemIsComponent()
+{
+ QQmlComponent component(&engine, testFileUrl("rootItemIsComponent.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(qobject_cast<QQmlComponent*>(root.data()));
+ QScopedPointer<QObject> other(qobject_cast<QQmlComponent*>(root.data())->create());
+ QVERIFY(!other.isNull());
+ QQmlContext *context = qmlContext(other.data());
+ QVERIFY(context);
+ QCOMPARE(context->nameForObject(other.data()), QStringLiteral("blah"));
+}
+
// Tests that components can be specified inline
void tst_qqmllanguage::inlineQmlComponents()
{
@@ -1787,6 +1807,48 @@ void tst_qqmllanguage::aliasProperties()
delete object;
}
+
+ // Nested aliases with a qml file
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.12.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QPointer<QObject> subObject = qvariant_cast<QObject*>(object->property("referencingSubObject"));
+ QVERIFY(!subObject.isNull());
+
+ QVERIFY(subObject->property("success").toBool());
+ }
+
+ // Nested aliases with a qml file with reverse ordering
+ {
+ // This is known to fail at the moment.
+ QQmlComponent component(&engine, testFileUrl("alias.13.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QPointer<QObject> subObject = qvariant_cast<QObject*>(object->property("referencingSubObject"));
+ QVERIFY(!subObject.isNull());
+
+ QVERIFY(subObject->property("success").toBool());
+ }
+
+ // "Nested" aliases within an object that require iterative resolution
+ {
+ // This is known to fail at the moment.
+ QQmlComponent component(&engine, testFileUrl("alias.14.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QPointer<QObject> subObject = qvariant_cast<QObject*>(object->property("referencingSubObject"));
+ QVERIFY(!subObject.isNull());
+
+ QVERIFY(subObject->property("success").toBool());
+ }
}
// QTBUG-13374 Test that alias properties and signals can coexist
@@ -2058,8 +2120,13 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode()
QQmlTypeData *td = eng->typeLoader.getType(url);
Q_ASSERT(td);
- QV4::CompiledData::Unit *qmlUnit = td->compiledData()->compilationUnit->data;
- Q_ASSERT(qmlUnit);
+ const QV4::CompiledData::Unit *readOnlyQmlUnit = td->compilationUnit()->data;
+ Q_ASSERT(readOnlyQmlUnit);
+ QV4::CompiledData::Unit *qmlUnit = reinterpret_cast<QV4::CompiledData::Unit *>(malloc(readOnlyQmlUnit->unitSize));
+ memcpy(qmlUnit, readOnlyQmlUnit, readOnlyQmlUnit->unitSize);
+ qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData;
+ td->compilationUnit()->data = qmlUnit;
+
const QV4::CompiledData::Object *rootObject = qmlUnit->objectAt(qmlUnit->indexOfRootObject);
QCOMPARE(qmlUnit->stringAt(rootObject->inheritedTypeNameIndex), QString("MyTypeObject"));
quint32 i;
@@ -2536,7 +2603,7 @@ void tst_qqmllanguage::basicRemote_data()
QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << "";
QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << "";
- QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << "";
+ QTest::newRow("need qmldir") << QUrl(serverdir+"TestNamed.qml") << "" << "";
}
void tst_qqmllanguage::basicRemote()
@@ -2576,6 +2643,8 @@ void tst_qqmllanguage::importsRemote_data()
<< "";
QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage"
<< "";
+ QTest::newRow("remote import with qualifier") << "import \""+serverdir+"\" as NS\nNS.NamedLocal {}" << "QQuickImage"
+ << "";
QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
<< "WrongTestLocal is not a type";
QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""
@@ -2882,7 +2951,7 @@ void tst_qqmllanguage::importIncorrectCase()
QCOMPARE(errors.count(), 1);
const QString expectedError = isCaseSensitiveFileSystem(dataDirectory()) ?
- QStringLiteral("File not found") :
+ QStringLiteral("No such file or directory") :
QStringLiteral("File name case mismatch");
QCOMPARE(errors.at(0).description(), expectedError);
@@ -3156,6 +3225,14 @@ void tst_qqmllanguage::subclassedUncreateableRevision()
delete obj;
}
+void tst_qqmllanguage::uncreatableTypesAsProperties()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("uncreatableTypeAsProperty.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+}
+
void tst_qqmllanguage::initTestCase()
{
QQmlDataTest::initTestCase();
@@ -3861,12 +3938,11 @@ void tst_qqmllanguage::compositeSingletonInstantiateError()
VERIFY_ERRORS("singletonTest9.error.txt");
}
-// Having a composite singleton type as dynamic property type fails
-// (like C++ singleton)
+// Having a composite singleton type as dynamic property type is allowed
void tst_qqmllanguage::compositeSingletonDynamicPropertyError()
{
QQmlComponent component(&engine, testFile("singletonTest10.qml"));
- VERIFY_ERRORS("singletonTest10.error.txt");
+ VERIFY_ERRORS(0);
}
// Having a composite singleton type as dynamic signal parameter succeeds
@@ -4054,7 +4130,7 @@ void tst_qqmllanguage::preservePropertyCacheOnGroupObjects()
QVERIFY(subCache);
QQmlPropertyData *pd = subCache->property(QStringLiteral("newProperty"), /*object*/0, /*context*/0);
QVERIFY(pd);
- QCOMPARE(pd->propType, qMetaTypeId<int>());
+ QCOMPARE(pd->propType(), qMetaTypeId<int>());
}
void tst_qqmllanguage::propertyCacheInSync()
@@ -4120,14 +4196,6 @@ void tst_qqmllanguage::earlyIdObjectAccess()
QVERIFY(o->property("success").toBool());
}
-void tst_qqmllanguage::dataAlignment()
-{
- QVERIFY(sizeof(QQmlVMEMetaData) % sizeof(int) == 0);
- QVERIFY(sizeof(QQmlVMEMetaData::AliasData) % sizeof(int) == 0);
- QVERIFY(sizeof(QQmlVMEMetaData::PropertyData) % sizeof(int) == 0);
- QVERIFY(sizeof(QQmlVMEMetaData::MethodData) % sizeof(int) == 0);
-}
-
void tst_qqmllanguage::deleteSingletons()
{
QPointer<QObject> singleton;
@@ -4146,6 +4214,34 @@ void tst_qqmllanguage::deleteSingletons()
QVERIFY(singleton.data() == 0);
}
+void tst_qqmllanguage::arrayBuffer_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::newRow("arraybuffer_property_get") << "arraybuffer_property_get.qml";
+ QTest::newRow("arraybuffer_property_set") << "arraybuffer_property_set.qml";
+ QTest::newRow("arraybuffer_signal_arg") << "arraybuffer_signal_arg.qml";
+ QTest::newRow("arraybuffer_method_arg") << "arraybuffer_method_arg.qml";
+ QTest::newRow("arraybuffer_method_return") << "arraybuffer_method_return.qml";
+ QTest::newRow("arraybuffer_method_overload") << "arraybuffer_method_overload.qml";
+}
+
+void tst_qqmllanguage::arrayBuffer()
+{
+ QFETCH(QString, file);
+ QQmlComponent component(&engine, testFile(file));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("ok").toBool(), true);
+}
+
+void tst_qqmllanguage::defaultListProperty()
+{
+ QQmlComponent component(&engine, testFileUrl("defaultListProperty.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/childplugin/childplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/childplugin/childplugin.cpp
index 53247e7912..515d56a3c4 100644
--- a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/childplugin/childplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/childplugin/childplugin.cpp
@@ -53,7 +53,7 @@ private:
class MyChildPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
MyChildPlugin()
diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2/childplugin/childplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/plugin.2/childplugin/childplugin.cpp
index a59347d3a9..56545cfa3c 100644
--- a/tests/auto/qml/qqmlmoduleplugin/plugin.2/childplugin/childplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2/childplugin/childplugin.cpp
@@ -53,7 +53,7 @@ private:
class MyChildPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
MyChildPlugin()
diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin/childplugin/childplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/plugin/childplugin/childplugin.cpp
index 5f4f96f7e4..28490d3d98 100644
--- a/tests/auto/qml/qqmlmoduleplugin/plugin/childplugin/childplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/plugin/childplugin/childplugin.cpp
@@ -52,7 +52,7 @@ private:
class MyChildPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
MyChildPlugin()
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 1d01f69d9b..fe73610bcc 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -157,7 +157,7 @@ void tst_qqmlproperty::qmlmetaproperty()
QObject *obj = new QObject;
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(nullptr, QLatin1String("null"), 0, engine.rootContext()));
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(obj, QObjectPrivate::get(obj)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr);
@@ -194,7 +194,8 @@ void tst_qqmlproperty::qmlmetaproperty()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -398,7 +399,7 @@ void tst_qqmlproperty::qmlmetaproperty_object()
{
QQmlProperty prop(&object);
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr);
@@ -437,7 +438,8 @@ void tst_qqmlproperty::qmlmetaproperty_object()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -445,7 +447,7 @@ void tst_qqmlproperty::qmlmetaproperty_object()
{
QQmlProperty prop(&dobject);
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -487,7 +489,8 @@ void tst_qqmlproperty::qmlmetaproperty_object()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -501,7 +504,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
{
QQmlProperty prop(&object, QString("defaultProperty"));
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr);
@@ -540,7 +543,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -548,7 +552,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
{
QQmlProperty prop(&dobject, QString("defaultProperty"));
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -590,7 +594,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -598,7 +603,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
{
QQmlProperty prop(&dobject, QString("onClicked"));
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -639,7 +644,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -647,7 +653,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
{
QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged"));
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -688,7 +694,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string()
QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -702,7 +709,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_context()
{
QQmlProperty prop(&object, engine.rootContext());
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr);
@@ -741,7 +748,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -749,7 +757,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_context()
{
QQmlProperty prop(&dobject, engine.rootContext());
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -791,7 +799,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -805,7 +814,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
{
QQmlProperty prop(&object, QString("defaultProperty"), engine.rootContext());
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr);
@@ -844,7 +853,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -852,7 +862,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
{
QQmlProperty prop(&dobject, QString("defaultProperty"), engine.rootContext());
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -894,7 +904,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr);
QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -902,7 +913,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
{
QQmlProperty prop(&dobject, QString("onClicked"), engine.rootContext());
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -943,7 +954,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
@@ -951,7 +963,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
{
QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged"), engine.rootContext());
- QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QQmlAbstractBinding::Ptr binding(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, QLatin1String("null"), 0, engine.rootContext()));
static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding);
QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1);
@@ -992,7 +1004,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context()
QVERIFY(!sigExprWatcher.wasDeleted());
QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
- QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
+ QCOMPARE(QQmlPropertyPrivate::propertyIndex(prop).valueTypeIndex(), -1);
+ QVERIFY(!QQmlPropertyPrivate::propertyIndex(prop).hasValueTypeIndex());
delete obj;
}
diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
index 5f15afff85..824fe445c0 100644
--- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
+++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
@@ -30,6 +30,8 @@
#include <private/qqmlpropertycache_p.h>
#include <QtQml/qqmlengine.h>
#include <private/qv8engine_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <QCryptographicHash>
#include "../../shared/util.h"
class tst_qqmlpropertycache : public QObject
@@ -45,6 +47,9 @@ private slots:
void methodsDerived();
void signalHandlers();
void signalHandlersDerived();
+ void metaObjectSize_data();
+ void metaObjectSize();
+ void metaObjectChecksum();
private:
QQmlEngine engine;
@@ -105,17 +110,17 @@ void tst_qqmlpropertycache::properties()
QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject));
QQmlPropertyData *data;
- QVERIFY(data = cacheProperty(cache, "propertyA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyA"));
+ QVERIFY((data = cacheProperty(cache, "propertyA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyA"));
- QVERIFY(data = cacheProperty(cache, "propertyB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyB"));
+ QVERIFY((data = cacheProperty(cache, "propertyB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyB"));
- QVERIFY(data = cacheProperty(cache, "propertyC"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyC"));
+ QVERIFY((data = cacheProperty(cache, "propertyC")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyC"));
- QVERIFY(data = cacheProperty(cache, "propertyD"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyD"));
+ QVERIFY((data = cacheProperty(cache, "propertyD")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyD"));
}
void tst_qqmlpropertycache::propertiesDerived()
@@ -129,17 +134,17 @@ void tst_qqmlpropertycache::propertiesDerived()
QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()));
QQmlPropertyData *data;
- QVERIFY(data = cacheProperty(cache, "propertyA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyA"));
+ QVERIFY((data = cacheProperty(cache, "propertyA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyA"));
- QVERIFY(data = cacheProperty(cache, "propertyB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyB"));
+ QVERIFY((data = cacheProperty(cache, "propertyB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyB"));
- QVERIFY(data = cacheProperty(cache, "propertyC"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyC"));
+ QVERIFY((data = cacheProperty(cache, "propertyC")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyC"));
- QVERIFY(data = cacheProperty(cache, "propertyD"));
- QCOMPARE(data->coreIndex, metaObject->indexOfProperty("propertyD"));
+ QVERIFY((data = cacheProperty(cache, "propertyD")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyD"));
}
void tst_qqmlpropertycache::methods()
@@ -152,29 +157,29 @@ void tst_qqmlpropertycache::methods()
QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject));
QQmlPropertyData *data;
- QVERIFY(data = cacheProperty(cache, "slotA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("slotA()"));
+ QVERIFY((data = cacheProperty(cache, "slotA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("slotA()"));
- QVERIFY(data = cacheProperty(cache, "slotB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("slotB()"));
+ QVERIFY((data = cacheProperty(cache, "slotB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("slotB()"));
- QVERIFY(data = cacheProperty(cache, "signalA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalA()"));
+ QVERIFY((data = cacheProperty(cache, "signalA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalA()"));
- QVERIFY(data = cacheProperty(cache, "signalB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalB()"));
+ QVERIFY((data = cacheProperty(cache, "signalB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalB()"));
- QVERIFY(data = cacheProperty(cache, "propertyAChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyAChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyAChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyAChanged()"));
- QVERIFY(data = cacheProperty(cache, "propertyBChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyBChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyBChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyBChanged()"));
- QVERIFY(data = cacheProperty(cache, "propertyCChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyCChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyCChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyCChanged()"));
- QVERIFY(data = cacheProperty(cache, "propertyDChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyDChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyDChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyDChanged()"));
}
void tst_qqmlpropertycache::methodsDerived()
@@ -188,29 +193,29 @@ void tst_qqmlpropertycache::methodsDerived()
QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()));
QQmlPropertyData *data;
- QVERIFY(data = cacheProperty(cache, "slotA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("slotA()"));
+ QVERIFY((data = cacheProperty(cache, "slotA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("slotA()"));
- QVERIFY(data = cacheProperty(cache, "slotB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("slotB()"));
+ QVERIFY((data = cacheProperty(cache, "slotB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("slotB()"));
- QVERIFY(data = cacheProperty(cache, "signalA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalA()"));
+ QVERIFY((data = cacheProperty(cache, "signalA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalA()"));
- QVERIFY(data = cacheProperty(cache, "signalB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalB()"));
+ QVERIFY((data = cacheProperty(cache, "signalB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalB()"));
- QVERIFY(data = cacheProperty(cache, "propertyAChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyAChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyAChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyAChanged()"));
- QVERIFY(data = cacheProperty(cache, "propertyBChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyBChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyBChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyBChanged()"));
- QVERIFY(data = cacheProperty(cache, "propertyCChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyCChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyCChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyCChanged()"));
- QVERIFY(data = cacheProperty(cache, "propertyDChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyDChanged()"));
+ QVERIFY((data = cacheProperty(cache, "propertyDChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyDChanged()"));
}
void tst_qqmlpropertycache::signalHandlers()
@@ -223,23 +228,23 @@ void tst_qqmlpropertycache::signalHandlers()
QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject));
QQmlPropertyData *data;
- QVERIFY(data = cacheProperty(cache, "onSignalA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalA()"));
+ QVERIFY((data = cacheProperty(cache, "onSignalA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalA()"));
- QVERIFY(data = cacheProperty(cache, "onSignalB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalB()"));
+ QVERIFY((data = cacheProperty(cache, "onSignalB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalB()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyAChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyAChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyAChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyAChanged()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyBChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyBChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyBChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyBChanged()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyCChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyCChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyCChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyCChanged()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyDChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyDChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyDChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyDChanged()"));
}
void tst_qqmlpropertycache::signalHandlersDerived()
@@ -253,25 +258,145 @@ void tst_qqmlpropertycache::signalHandlersDerived()
QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()));
QQmlPropertyData *data;
- QVERIFY(data = cacheProperty(cache, "onSignalA"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalA()"));
+ QVERIFY((data = cacheProperty(cache, "onSignalA")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalA()"));
- QVERIFY(data = cacheProperty(cache, "onSignalB"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("signalB()"));
+ QVERIFY((data = cacheProperty(cache, "onSignalB")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalB()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyAChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyAChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyAChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyAChanged()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyBChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyBChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyBChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyBChanged()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyCChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyCChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyCChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyCChanged()"));
- QVERIFY(data = cacheProperty(cache, "onPropertyDChanged"));
- QCOMPARE(data->coreIndex, metaObject->indexOfMethod("propertyDChanged()"));
+ QVERIFY((data = cacheProperty(cache, "onPropertyDChanged")));
+ QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("propertyDChanged()"));
}
-QTEST_MAIN(tst_qqmlpropertycache)
+class TestClass : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int prop READ prop WRITE setProp NOTIFY propChanged)
+ int m_prop;
+
+public:
+ enum MyEnum {
+ First, Second
+ };
+ Q_ENUM(MyEnum)
+
+ Q_CLASSINFO("Foo", "Bar")
+
+ TestClass() {}
+
+ int prop() const
+ {
+ return m_prop;
+ }
+
+public slots:
+ void setProp(int prop)
+ {
+ if (m_prop == prop)
+ return;
+
+ m_prop = prop;
+ emit propChanged(prop);
+ }
+signals:
+ void propChanged(int prop);
+};
+
+class TestClassWithParameters : public QObject
+{
+ Q_OBJECT
+
+public:
+ Q_INVOKABLE void slotWithArguments(int firstArg) {
+ Q_UNUSED(firstArg);
+ }
+};
+
+class TestClassWithClassInfo : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("Key", "Value")
+};
#include "tst_qqmlpropertycache.moc"
+
+#define ARRAY_SIZE(arr) \
+ int(sizeof(arr) / sizeof(arr[0]))
+
+#define TEST_CLASS(Class) \
+ QTest::newRow(#Class) << &Class::staticMetaObject << ARRAY_SIZE(qt_meta_data_##Class) << ARRAY_SIZE(qt_meta_stringdata_##Class.data)
+
+Q_DECLARE_METATYPE(const QMetaObject*);
+
+void tst_qqmlpropertycache::metaObjectSize_data()
+{
+ QTest::addColumn<const QMetaObject*>("metaObject");
+ QTest::addColumn<int>("expectedFieldCount");
+ QTest::addColumn<int>("expectedStringCount");
+
+ TEST_CLASS(TestClass);
+ TEST_CLASS(TestClassWithParameters);
+ TEST_CLASS(TestClassWithClassInfo);
+}
+
+void tst_qqmlpropertycache::metaObjectSize()
+{
+ QFETCH(const QMetaObject *, metaObject);
+ QFETCH(int, expectedFieldCount);
+ QFETCH(int, expectedStringCount);
+
+ int size = 0;
+ int stringDataSize = 0;
+ bool valid = QQmlPropertyCache::determineMetaObjectSizes(*metaObject, &size, &stringDataSize);
+ QVERIFY(valid);
+
+ QCOMPARE(size, expectedFieldCount - 1); // Remove trailing zero field until fixed in moc.
+ QCOMPARE(stringDataSize, expectedStringCount);
+}
+
+void tst_qqmlpropertycache::metaObjectChecksum()
+{
+ QMetaObjectBuilder builder;
+ builder.setClassName("Test");
+ builder.addClassInfo("foo", "bar");
+
+ QCryptographicHash hash(QCryptographicHash::Md5);
+
+ QScopedPointer<QMetaObject, QScopedPointerPodDeleter> mo(builder.toMetaObject());
+ QVERIFY(!mo.isNull());
+
+ QVERIFY(QQmlPropertyCache::addToHash(hash, *mo.data()));
+ QByteArray initialHash = hash.result();
+ QVERIFY(!initialHash.isEmpty());
+ hash.reset();
+
+ {
+ QVERIFY(QQmlPropertyCache::addToHash(hash, *mo.data()));
+ QByteArray nextHash = hash.result();
+ QVERIFY(!nextHash.isEmpty());
+ hash.reset();
+ QCOMPARE(initialHash, nextHash);
+ }
+
+ builder.addProperty("testProperty", "int", -1);
+
+ mo.reset(builder.toMetaObject());
+ {
+ QVERIFY(QQmlPropertyCache::addToHash(hash, *mo.data()));
+ QByteArray nextHash = hash.result();
+ QVERIFY(!nextHash.isEmpty());
+ hash.reset();
+ QVERIFY(initialHash != nextHash);
+ }
+}
+
+QTEST_MAIN(tst_qqmlpropertycache)
diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent.qml b/tests/auto/qml/qqmlqt/data/LaterComponent.qml
new file mode 100644
index 0000000000..7dbd81d93d
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/LaterComponent.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import LaterImports 1.0
+
+TestElement {
+ id: deleteme
+ function testFn() {
+ gc(); // at this point, obj is deleted.
+ dangerousFunction(); // calling this function will throw an exeption
+ // because this object has been deleted and its context is not available
+
+ // which means that we shouldn't get to this line.
+ row.test10_1 = 1;
+ }
+}
diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent2.qml b/tests/auto/qml/qqmlqt/data/LaterComponent2.qml
new file mode 100644
index 0000000000..56bcc0235b
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/LaterComponent2.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+Item {
+ id: deleteme2
+ function testFn() {
+ // this function shouldn't be called,
+ // since the object will have been deleted.
+ var crashy = Qt.createQmlObject("import QtQuick 2.0; Item { }", deleteme2) // invalid calling context if invoked after gc
+ row.test11_1 = 2;
+ }
+
+ Component.onDestruction: row.test11_1 = 1; // success == the object was deleted, but testFn wasn't called.
+}
diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent3.qml b/tests/auto/qml/qqmlqt/data/LaterComponent3.qml
new file mode 100644
index 0000000000..c6f445253a
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/LaterComponent3.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+import LaterImports 1.0
+
+TestElement {
+ id: deleteme3
+ function testFn() {
+ gc(); // at this point, obj is deleted.
+ dangerousFunction(); // calling this function will throw an exeption
+ // because this object has been deleted and its context is not available
+
+ // which means that we shouldn't get to this line.
+ row.test12_1 = 1;
+ }
+}
diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent4.qml b/tests/auto/qml/qqmlqt/data/LaterComponent4.qml
new file mode 100644
index 0000000000..0c53bd368b
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/LaterComponent4.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Item {
+ id: deleteme4
+ function testFn() {
+ // this function shouldn't be called,
+ // since the object will have been deleted.
+ row.test13_1 = 2;
+ }
+
+ Component.onDestruction: row.test13_1 = 1; // success == the object was deleted, but testFn wasn't called.
+}
diff --git a/tests/auto/qml/qqmlqt/data/exit.qml b/tests/auto/qml/qqmlqt/data/exit.qml
new file mode 100644
index 0000000000..12727d9f04
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/exit.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+
+QtObject {
+ property int returnCode: -1
+ Component.onCompleted: Qt.exit(returnCode)
+}
+
diff --git a/tests/auto/qml/qqmlqt/data/later.qml b/tests/auto/qml/qqmlqt/data/later.qml
new file mode 100644
index 0000000000..a90f3aba9f
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/later.qml
@@ -0,0 +1,124 @@
+import QtQuick 2.0
+import LaterImports 1.0
+
+Row {
+ id: row
+ Repeater {
+ id: repeater
+ model: 5
+ delegate: Item { }
+ }
+
+ property bool test1_1: false
+ property bool test1_2: row.focus
+ property bool test2_1: false
+ property bool test2_2: (firstFunctionCallCounter == 1 && secondFunctionCallCounter == 1 && signalCallCounter == 1)
+
+ property int firstFunctionCallCounter: 0
+ property int secondFunctionCallCounter: 0
+ property int signalCallCounter: 0
+
+ signal testSignal
+ onTestSignal: {
+ signalCallCounter++;
+ }
+
+ onChildrenChanged: {
+ Qt.callLater(row.forceActiveFocus); // built-in function
+ Qt.callLater(row.firstFunction); // JS function
+ Qt.callLater(row.testSignal); // signal
+ }
+
+ function firstFunction() {
+ firstFunctionCallCounter++;
+ }
+
+ function secondFunction() {
+ secondFunctionCallCounter++;
+ }
+
+ Component.onCompleted: {
+ test1_1 = !row.focus;
+ test2_1 = (firstFunctionCallCounter == 0);
+
+ Qt.callLater(secondFunction);
+ Qt.callLater(firstFunction);
+ Qt.callLater(secondFunction);
+ }
+
+ function test2() {
+ repeater.model = 2;
+ }
+
+ function test3() {
+ Qt.callLater(test3_recursive);
+ }
+
+ property int recursion: 0
+ property bool test3_1: (recursion == 1)
+ property bool test3_2: (recursion == 2)
+ property bool test3_3: (recursion == 3)
+ function test3_recursive() {
+ if (recursion < 3) {
+ Qt.callLater(test3_recursive);
+ Qt.callLater(test3_recursive);
+ }
+ recursion++;
+ }
+
+ function test4() {
+ Qt.callLater(functionThatDoesNotExist);
+ }
+
+ property bool test5_1: false
+ function test5() {
+ Qt.callLater(functionWithArguments, "THESE", "ARGS", "WILL", "BE", "OVERWRITTEN")
+ Qt.callLater(functionWithArguments, "firstArg", 2, "thirdArg")
+ }
+
+ function functionWithArguments(firstStr, secondInt, thirdString) {
+ test5_1 = (firstStr == "firstArg" && secondInt == 2 && thirdString == "thirdArg");
+ }
+
+
+ property bool test6_1: (callOrder_Later == "TWO THREE ") // not "THREE TWO "
+ function test6() {
+ Qt.callLater(test6Function1, "ONE");
+ Qt.callLater(test6Function2, "TWO");
+ Qt.callLater(test6Function1, "THREE");
+ }
+
+ property string callOrder_Later
+ function test6Function1(arg) { callOrder_Later += arg + " "; }
+ function test6Function2(arg) { callOrder_Later += arg + " "; }
+
+ property int test9_1: SingletonType.intProp;
+ function test9() {
+ SingletonType.resetIntProp();
+ Qt.callLater(SingletonType.testFunc)
+ Qt.callLater(SingletonType.testFunc)
+ Qt.callLater(SingletonType.testFunc)
+ Qt.callLater(SingletonType.testFunc)
+ // should only get called once.
+ }
+
+ property int test10_1: 0
+ function test10() {
+ var c = Qt.createComponent("LaterComponent.qml");
+ var obj = c.createObject(); // QML ownership.
+ Qt.callLater(obj.testFn);
+ // note: obj will be cleaned up during next gc().
+ }
+
+ property int test11_1: 0
+ function test11() {
+ var c = Qt.createComponent("LaterComponent2.qml");
+ var obj = c.createObject(); // QML ownership.
+ Qt.callLater(obj.testFn);
+ gc(); // this won't actually collect the obj, we need to trigger gc manually in the test.
+ }
+
+ function test14() {
+ Qt.callLater(console.log, "success")
+ }
+}
diff --git a/tests/auto/qml/qqmlqt/data/timeRoundtrip.qml b/tests/auto/qml/qqmlqt/data/timeRoundtrip.qml
new file mode 100644
index 0000000000..9d73640c87
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/timeRoundtrip.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+QtObject {
+ Component.onCompleted: {
+ var t = tp.time;
+ tp.time = t;
+ }
+}
diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
index 2f44c34bc2..0576650d01 100644
--- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
+++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
@@ -46,6 +46,15 @@
#include <QFont>
#include "../../shared/util.h"
+// Copied from tst_qdatetime.cpp
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+# include <time.h>
+# if defined(Q_OS_WINRT)
+# define tzset()
+# endif
+#endif
+
class tst_qqmlqt : public QQmlDataTest
{
Q_OBJECT
@@ -53,6 +62,7 @@ public:
tst_qqmlqt() {}
private slots:
+ void initTestCase();
void enums();
void rgba();
void hsla();
@@ -86,13 +96,74 @@ private slots:
void atob();
void fontFamilies();
void quit();
+ void exit();
void resolvedUrl();
+ void later_data();
+ void later();
void qtObjectContents();
+ void timeRoundtrip_data();
+ void timeRoundtrip();
+
private:
QQmlEngine engine;
};
+// for callLater()
+class TestElement : public QQuickItem
+{
+ Q_OBJECT
+public:
+ TestElement() : m_intptr(new int) {}
+ ~TestElement() { delete m_intptr; }
+
+ Q_INVOKABLE void dangerousFunction() {
+ delete m_intptr;
+ m_intptr = new int;
+ *m_intptr = 5;
+ }
+private:
+ int *m_intptr;
+};
+
+// for callLater()
+class TestModuleApi : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
+
+public:
+ TestModuleApi() : m_int(0) {}
+ ~TestModuleApi() {}
+
+ int intProp() const { return m_int; }
+ void setIntProp(int v) { m_int = v; emit intPropChanged(); }
+
+ Q_INVOKABLE void testFunc() { ++m_int; emit intPropChanged(); }
+ Q_INVOKABLE void resetIntProp() { m_int = 0; emit intPropChanged(); }
+
+signals:
+ void intPropChanged();
+
+private:
+ int m_int;
+};
+
+static QObject *test_module_api_factory(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
+ TestModuleApi *api = new TestModuleApi;
+ return api;
+}
+
+void tst_qqmlqt::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+ qmlRegisterSingletonType<TestModuleApi>("LaterImports", 1, 0, "SingletonType", test_module_api_factory);
+ qmlRegisterType<TestElement>("LaterImports", 1, 0, "TestElement");
+}
+
void tst_qqmlqt::enums()
{
QQmlComponent component(&engine, testFileUrl("enums.qml"));
@@ -814,8 +885,6 @@ void tst_qqmlqt::dateTimeFormattingVariants_data()
QTime time(11, 16, 39, 755);
temporary = QDateTime(QDate(1970,1,1), time);
- QTest::newRow("formatDate, qtime") << "formatDate" << QVariant::fromValue(time) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy"));
- QTest::newRow("formatDateTime, qtime") << "formatDateTime" << QVariant::fromValue(time) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a"));
QTest::newRow("formatTime, qtime") << "formatTime" << QVariant::fromValue(time) << (QStringList() << temporary.time().toString(Qt::DefaultLocaleShortDate) << temporary.time().toString(Qt::DefaultLocaleLongDate) << temporary.time().toString("H:m:s a") << temporary.time().toString("hh:mm:ss.zzz"));
QDate date(2011,5,31);
@@ -922,6 +991,20 @@ void tst_qqmlqt::quit()
delete object;
}
+void tst_qqmlqt::exit()
+{
+ QQmlComponent component(&engine, testFileUrl("exit.qml"));
+
+ QSignalSpy spy(&engine, &QQmlEngine::exit);
+ QObject *object = component.create();
+ QVERIFY(object != Q_NULLPTR);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QVERIFY(arguments.at(0).toInt() == object->property("returnCode").toInt());
+
+ delete object;
+}
+
void tst_qqmlqt::resolvedUrl()
{
QQmlComponent component(&engine, testFileUrl("resolvedUrl.qml"));
@@ -935,6 +1018,107 @@ void tst_qqmlqt::resolvedUrl()
delete object;
}
+void tst_qqmlqt::later_data()
+{
+ QTest::addColumn<QString>("function");
+ QTest::addColumn<QStringList>("expectedWarnings");
+ QTest::addColumn<QStringList>("propNames");
+ QTest::addColumn<QVariantList>("values");
+
+ QVariant vtrue = QVariant(true);
+
+ QTest::newRow("callLater from onCompleted")
+ << QString()
+ << QStringList()
+ << (QStringList() << "test1_1" << "test2_1" << "processEvents" << "test1_2" << "test2_2")
+ << (QVariantList() << vtrue << vtrue << QVariant() << vtrue << vtrue);
+
+ QTest::newRow("trigger Qt.callLater() via repeater")
+ << QString(QLatin1String("test2"))
+ << QStringList()
+ << (QStringList() << "processEvents" << "test2_2")
+ << (QVariantList() << QVariant() << vtrue);
+
+ QTest::newRow("recursive Qt.callLater()")
+ << QString(QLatin1String("test3"))
+ << QStringList()
+ << (QStringList() << "processEvents" << "test3_1" << "processEvents" << "test3_2" << "processEvents" << "test3_3")
+ << (QVariantList() << QVariant() << vtrue << QVariant() << vtrue << QVariant() << vtrue);
+
+ QTest::newRow("nonexistent function")
+ << QString(QLatin1String("test4"))
+ << (QStringList() << QString(testFileUrl("later.qml").toString() + QLatin1String(":70: ReferenceError: functionThatDoesNotExist is not defined")))
+ << QStringList()
+ << QVariantList();
+
+ QTest::newRow("callLater with different args")
+ << QString(QLatin1String("test5"))
+ << QStringList()
+ << (QStringList() << "processEvents" << "test5_1")
+ << (QVariantList() << QVariant() << vtrue);
+
+ QTest::newRow("delayed call ordering")
+ << QString(QLatin1String("test6"))
+ << QStringList()
+ << (QStringList() << "processEvents" << "test6_1")
+ << (QVariantList() << QVariant() << vtrue);
+
+ QTest::newRow("invoke module api invokable")
+ << QString(QLatin1String("test9"))
+ << QStringList()
+ << (QStringList() << "processEvents" << "test9_1" << "processEvents")
+ << (QVariantList() << QVariant() << QVariant(1) << QVariant());
+
+ QTest::newRow("invoke function of deleted QObject via callLater() causing deletion")
+ << QString(QLatin1String("test10"))
+ << (QStringList() << QString(testFileUrl("LaterComponent.qml").toString() + QLatin1String(":8: ReferenceError: dangerousFunction is not defined (exception occurred during delayed function evaluation)")))
+ << (QStringList() << "processEvents" << "test10_1" << "processEvents")
+ << (QVariantList() << QVariant() << QVariant(0) << QVariant());
+
+ QTest::newRow("invoke function of deleted QObject via callLater() after deletion")
+ << QString(QLatin1String("test11"))
+ << QStringList()
+ << (QStringList() << "collectGarbage" << "processEvents" << "test11_1" << "processEvents")
+ << (QVariantList() << QVariant() << QVariant() << QVariant(1) << QVariant());
+
+ QTest::newRow("invoke function which has no script origin")
+ << QString(QLatin1String("test14"))
+ << QStringList()
+ << (QStringList() << "collectGarbage")
+ << (QVariantList() << QVariant());
+}
+
+void tst_qqmlqt::later()
+{
+ QFETCH(QString, function);
+ QFETCH(QStringList, expectedWarnings);
+ QFETCH(QStringList, propNames);
+ QFETCH(QVariantList, values);
+
+ foreach (const QString &w, expectedWarnings)
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w));
+
+ QQmlComponent component(&engine, testFileUrl("later.qml"));
+ QObject *root = component.create();
+ QVERIFY(root != 0);
+
+ if (!function.isEmpty())
+ QMetaObject::invokeMethod(root, qPrintable(function));
+
+ for (int i = 0; i < propNames.size(); ++i) {
+ if (propNames.at(i) == QLatin1String("processEvents")) {
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+ } else if (propNames.at(i) == QLatin1String("collectGarbage")) {
+ engine.collectGarbage();
+ } else {
+ QCOMPARE(root->property(qPrintable(propNames.at(i))), values.at(i));
+ }
+ }
+
+ delete root;
+}
+
void tst_qqmlqt::qtObjectContents()
{
struct StaticQtMetaObject : public QObject
@@ -980,6 +1164,104 @@ void tst_qqmlqt::qtObjectContents()
delete object;
}
+class TimeProvider: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged)
+
+public:
+ TimeProvider(const QTime &t)
+ : m_getTime(t)
+ {}
+
+ QTime time() const { return m_getTime; }
+ void setTime(const QTime &t) { m_putTime = t; emit timeChanged(); }
+
+signals:
+ void timeChanged();
+
+public:
+ QTime m_getTime, m_putTime;
+};
+
+class TimeZoneSwitch
+{
+public:
+ TimeZoneSwitch(const char *newZone)
+ : doChangeZone(qstrcmp(newZone, "localtime") == 0)
+ {
+ if (!doChangeZone)
+ return;
+
+ hadOldZone = qEnvironmentVariableIsSet("TZ");
+ if (hadOldZone) {
+ oldZone = qgetenv("TZ");
+ }
+ qputenv("TZ", newZone);
+ tzset();
+ }
+
+ ~TimeZoneSwitch()
+ {
+ if (!doChangeZone)
+ return;
+
+ if (hadOldZone)
+ qputenv("TZ", oldZone);
+ else
+ qunsetenv("TZ");
+ tzset();
+ }
+
+private:
+ bool doChangeZone;
+ bool hadOldZone;
+ QByteArray oldZone;
+};
+
+void tst_qqmlqt::timeRoundtrip_data()
+{
+ QTest::addColumn<QTime>("time");
+
+ // Local timezone:
+ QTest::newRow("localtime") << QTime(0, 0, 0);
+
+ // No DST:
+ QTest::newRow("UTC") << QTime(0, 0, 0);
+ QTest::newRow("Europe/Amsterdam") << QTime(1, 0, 0);
+ QTest::newRow("Asia/Jakarta") << QTime(7, 0, 0);
+
+ // DST:
+ QTest::newRow("Namibia/Windhoek") << QTime(1, 0, 0);
+ QTest::newRow("Australia/Adelaide") << QTime(10, 0, 0);
+ QTest::newRow("Australia/Hobart") << QTime(10, 0, 0);
+ QTest::newRow("Pacific/Auckland") << QTime(12, 0, 0);
+ QTest::newRow("Pacific/Samoa") << QTime(13, 0, 0);
+}
+
+void tst_qqmlqt::timeRoundtrip()
+{
+#ifdef Q_OS_WIN
+ QSKIP("On Windows, the DateObject doesn't handle DST transitions correctly when the timezone is not localtime."); // I.e.: for this test.
+#endif
+
+ TimeZoneSwitch tzs(QTest::currentDataTag());
+ QFETCH(QTime, time);
+
+ TimeProvider tp(time);
+
+ QQmlEngine eng;
+ eng.rootContext()->setContextProperty(QLatin1String("tp"), &tp);
+ QQmlComponent component(&eng, testFileUrl("timeRoundtrip.qml"));
+ QObject *obj = component.create();
+ QVERIFY(obj != 0);
+
+ // QML reads m_getTime and saves the result as m_putTime; this should come out the same, without
+ // any perturbation (e.g. by DST effects) from converting from QTime to V4's Date and back
+ // again.
+ QCOMPARE(tp.m_getTime, tp.m_putTime);
+}
+
QTEST_MAIN(tst_qqmlqt)
#include "tst_qqmlqt.moc"
diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
index bf255ba6a0..1fc803a395 100644
--- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
+++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
@@ -31,7 +31,6 @@
#include <QQmlComponent>
#include <QTranslator>
#include <QQmlContext>
-#include <private/qqmlcompiler_p.h>
#include <private/qqmlengine_p.h>
#include "../../shared/util.h"
@@ -77,15 +76,15 @@ void tst_qqmltranslation::translation()
QQmlContext *context = qmlContext(object);
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine());
QQmlTypeData *typeData = engine->typeLoader.getType(context->baseUrl());
- QQmlCompiledData *cdata = typeData->compiledData();
- QVERIFY(cdata);
+ QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit();
+ QVERIFY(compilationUnit);
QSet<QString> compiledTranslations;
compiledTranslations << QStringLiteral("basic")
<< QStringLiteral("disambiguation")
<< QStringLiteral("singular") << QStringLiteral("plural");
- const QV4::CompiledData::Unit *unit = cdata->compilationUnit->data;
+ const QV4::CompiledData::Unit *unit = compilationUnit->data;
const QV4::CompiledData::Object *rootObject = unit->objectAt(unit->indexOfRootObject);
const QV4::CompiledData::Binding *binding = rootObject->bindingTable();
for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) {
@@ -96,7 +95,7 @@ void tst_qqmltranslation::translation()
if (expectCompiledTranslation) {
if (binding->type != QV4::CompiledData::Binding::Type_Translation)
qDebug() << "binding for property" << propertyName << "is not a compiled translation";
- QCOMPARE(binding->type, quint32(QV4::CompiledData::Binding::Type_Translation));
+ QCOMPARE(quint32(binding->type), quint32(QV4::CompiledData::Binding::Type_Translation));
} else {
if (binding->type == QV4::CompiledData::Binding::Type_Translation)
qDebug() << "binding for property" << propertyName << "is not supposed to be a compiled translation";
@@ -137,10 +136,10 @@ void tst_qqmltranslation::idTranslation()
QQmlContext *context = qmlContext(object);
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine());
QQmlTypeData *typeData = engine->typeLoader.getType(context->baseUrl());
- QQmlCompiledData *cdata = typeData->compiledData();
- QVERIFY(cdata);
+ QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit();
+ QVERIFY(compilationUnit);
- const QV4::CompiledData::Unit *unit = cdata->compilationUnit->data;
+ const QV4::CompiledData::Unit *unit = compilationUnit->data;
const QV4::CompiledData::Object *rootObject = unit->objectAt(unit->indexOfRootObject);
const QV4::CompiledData::Binding *binding = rootObject->bindingTable();
for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) {
@@ -148,7 +147,7 @@ void tst_qqmltranslation::idTranslation()
if (propertyName == "idTranslation") {
if (binding->type != QV4::CompiledData::Binding::Type_TranslationById)
qDebug() << "binding for property" << propertyName << "is not a compiled translation";
- QCOMPARE(binding->type, quint32(QV4::CompiledData::Binding::Type_TranslationById));
+ QCOMPARE(quint32(binding->type), quint32(QV4::CompiledData::Binding::Type_TranslationById));
} else {
QVERIFY(binding->type != QV4::CompiledData::Binding::Type_Translation);
}
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
index 36350e2d08..3d3a7ff725 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
@@ -32,7 +32,6 @@
#include <QtQuick/qquickitem.h>
#include <QtQml/private/qqmlengine_p.h>
#include <QtQml/private/qqmltypeloader_p.h>
-#include <QtQml/private/qqmlcompiler_p.h>
#include "../../shared/util.h"
class tst_QQMLTypeLoader : public QQmlDataTest
@@ -90,7 +89,7 @@ void tst_QQMLTypeLoader::trimCache()
if (i % 10 == 0) {
// keep ref on data, don't add ref on data->compiledData()
} else if (i % 5 == 0) {
- data->compiledData()->addref();
+ data->compilationUnit()->addref();
data->release();
} else {
data->release();
diff --git a/tests/auto/qml/qqmlvaluetypes/data/color_read.qml b/tests/auto/qml/qqmlvaluetypes/data/color_read.qml
index bc92b1e5f9..73d2b921a7 100644
--- a/tests/auto/qml/qqmlvaluetypes/data/color_read.qml
+++ b/tests/auto/qml/qqmlvaluetypes/data/color_read.qml
@@ -5,5 +5,11 @@ MyTypeObject {
property real v_g: color.g
property real v_b: color.b
property real v_a: color.a
+ property real hsv_h: color.hsvHue
+ property real hsv_s: color.hsvSaturation
+ property real hsv_v: color.hsvValue
+ property real hsl_h: color.hslHue
+ property real hsl_s: color.hslSaturation
+ property real hsl_l: color.hslLightness
property variant copy: color
}
diff --git a/tests/auto/qml/qqmlvaluetypes/data/color_write_HSL.qml b/tests/auto/qml/qqmlvaluetypes/data/color_write_HSL.qml
new file mode 100644
index 0000000000..0034163bbe
--- /dev/null
+++ b/tests/auto/qml/qqmlvaluetypes/data/color_write_HSL.qml
@@ -0,0 +1,8 @@
+import Test 1.0
+
+MyTypeObject {
+ color.hslHue: if (true) 0.43
+ color.hslSaturation: if (true) 0.74
+ color.hslLightness: if (true) 0.54
+ color.a: if (true) 0.7
+}
diff --git a/tests/auto/qml/qqmlvaluetypes/data/color_write_HSV.qml b/tests/auto/qml/qqmlvaluetypes/data/color_write_HSV.qml
new file mode 100644
index 0000000000..1fc47d460e
--- /dev/null
+++ b/tests/auto/qml/qqmlvaluetypes/data/color_write_HSV.qml
@@ -0,0 +1,8 @@
+import Test 1.0
+
+MyTypeObject {
+ color.hsvHue: if (true) 0.43
+ color.hsvSaturation: if (true) 0.77
+ color.hsvValue: if (true) 0.88
+ color.a: if (true) 0.7
+}
diff --git a/tests/auto/qml/qqmlvaluetypes/testtypes.h b/tests/auto/qml/qqmlvaluetypes/testtypes.h
index 77d723fbd4..bcfe4028c6 100644
--- a/tests/auto/qml/qqmlvaluetypes/testtypes.h
+++ b/tests/auto/qml/qqmlvaluetypes/testtypes.h
@@ -194,7 +194,7 @@ class MyOffsetValueInterceptor : public QObject, public QQmlPropertyValueInterce
Q_INTERFACES(QQmlPropertyValueInterceptor)
public:
virtual void setTarget(const QQmlProperty &p) { prop = p; }
- virtual void write(const QVariant &value) { QQmlPropertyPrivate::write(prop, value.toInt() + 13, QQmlPropertyPrivate::BypassInterceptor); }
+ virtual void write(const QVariant &value) { QQmlPropertyPrivate::write(prop, value.toInt() + 13, QQmlPropertyData::BypassInterceptor); }
private:
QQmlProperty prop;
@@ -215,7 +215,7 @@ public:
c.getRgb(&r, &g, &b, &a);
c.setRgb(a, b, g, r);
- QQmlPropertyPrivate::write(prop, c, QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::write(prop, c, QQmlPropertyData::BypassInterceptor);
}
private:
@@ -230,7 +230,7 @@ public:
virtual void setTarget(const QQmlProperty &p) { prop = p; }
virtual void write(const QVariant &)
{
- QQmlPropertyPrivate::write(prop, 0.0f, QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::write(prop, 0.0f, QQmlPropertyData::BypassInterceptor);
}
private:
diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
index 0d9a561378..9e915ac451 100644
--- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
+++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
@@ -30,6 +30,7 @@
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
+#include <QJSValueIterator>
#include <private/qquickvaluetypes_p.h>
#include <private/qqmlglobal_p.h>
#include "../../shared/util.h"
@@ -89,6 +90,7 @@ private slots:
void customValueTypeInQml();
void gadgetInheritance();
void toStringConversion();
+ void enumerableProperties();
void enumProperties();
private:
@@ -906,6 +908,15 @@ void tst_qqmlvaluetypes::color()
QCOMPARE((float)object->property("v_g").toDouble(), (float)0.88);
QCOMPARE((float)object->property("v_b").toDouble(), (float)0.6);
QCOMPARE((float)object->property("v_a").toDouble(), (float)0.34);
+
+ QCOMPARE(qRound(object->property("hsv_h").toDouble() * 100), 43);
+ QCOMPARE(qRound(object->property("hsv_s").toDouble() * 100), 77);
+ QCOMPARE(qRound(object->property("hsv_v").toDouble() * 100), 88);
+
+ QCOMPARE(qRound(object->property("hsl_h").toDouble() * 100), 43);
+ QCOMPARE(qRound(object->property("hsl_s").toDouble() * 100), 74);
+ QCOMPARE(qRound(object->property("hsl_l").toDouble() * 100), 54);
+
QColor comparison;
comparison.setRedF(0.2);
comparison.setGreenF(0.88);
@@ -932,6 +943,30 @@ void tst_qqmlvaluetypes::color()
}
{
+ QQmlComponent component(&engine, testFileUrl("color_write_HSV.qml"));
+ MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QColor newColor;
+ newColor.setHsvF(0.43, 0.77, 0.88, 0.7);
+ QCOMPARE(object->color(), newColor);
+
+ delete object;
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("color_write_HSL.qml"));
+ MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QColor newColor;
+ newColor.setHslF(0.43, 0.74, 0.54, 0.7);
+ QCOMPARE(object->color(), newColor);
+
+ delete object;
+ }
+
+ {
QQmlComponent component(&engine, testFileUrl("color_compare.qml"));
MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
QVERIFY(object != 0);
@@ -1650,6 +1685,25 @@ void tst_qqmlvaluetypes::toStringConversion()
QCOMPARE(stringConversion.toString(), StringLessGadget_to_QString(g));
}
+void tst_qqmlvaluetypes::enumerableProperties()
+{
+ QJSEngine engine;
+ DerivedGadget g;
+ QJSValue value = engine.toScriptValue(g);
+ QSet<QString> names;
+ QJSValueIterator it(value);
+ while (it.hasNext()) {
+ it.next();
+ const QString name = it.name();
+ QVERIFY(!names.contains(name));
+ names.insert(name);
+ }
+
+ QCOMPARE(names.count(), 2);
+ QVERIFY(names.contains(QStringLiteral("baseProperty")));
+ QVERIFY(names.contains(QStringLiteral("derivedProperty")));
+}
+
struct GadgetWithEnum
{
Q_GADGET
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect
new file mode 100644
index 0000000000..8c13977462
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect
@@ -0,0 +1,17 @@
+PATCH /qqmlxmlhttprequest.cpp HTTP/1.1
+Accept-Language: en-US
+If-Match: "ETagNumber"
+Content-Type: application/example
+Content-Length: 247
+Connection: Keep-Alive
+Accept-Encoding: gzip, deflate
+User-Agent: Mozilla/5.0
+Host: {{ServerHostUrl}}
+
+--- a/qqmlxmlhttprequest.cpp
++++ b/qqmlxmlhttprequest.cpp
+@@ -1238,11 +1238,13 @@
+- } else if (m_method == QLatin1String("OPTIONS")) {
++ } else if (m_method == QLatin1String("OPTIONS") ||
++ (m_method == QLatin1String("PATCH"))) {
+
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.qml b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.qml
new file mode 100644
index 0000000000..2abf1c60a8
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Canonical Limited and/or its subsidiary(-ies).
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+QtObject {
+ property string url
+
+ property bool dataOK: false
+ property bool headerOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+ x.open("PATCH", url);
+ x.setRequestHeader("Accept-Language","en-US");
+ x.setRequestHeader("If-Match","\"ETagNumber\"");
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
+ headerOK = (x.getResponseHeader("Content-Location") == "/qqmlxmlhttprequest.cpp") &&
+ (x.getResponseHeader("ETag") == "\"ETagNumber\"") &&
+ (x.status == "204");
+ } else if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText === "");
+ }
+ }
+
+ var body = "--- a/qqmlxmlhttprequest.cpp\n" +
+ "+++ b/qqmlxmlhttprequest.cpp\n" +
+ "@@ -1238,11 +1238,13 @@\n" +
+ "- } else if (m_method == QLatin1String(\"OPTIONS\")) {\n" +
+ "+ } else if (m_method == QLatin1String(\"OPTIONS\") ||\n" +
+ "+ (m_method == QLatin1String(\"PATCH\"))) {\n"
+
+ x.send(body);
+ }
+}
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.reply b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.reply
new file mode 100644
index 0000000000..cece41ced1
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.reply
@@ -0,0 +1,3 @@
+HTTP/1.1 204 No Content
+Content-Location: /qqmlxmlhttprequest.cpp
+ETag: "ETagNumber"
diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
index 425e12677f..1ce07ecdab 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
+++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
@@ -71,6 +71,7 @@ private slots:
void send_withdata_data();
void send_options();
void send_options_data();
+ void send_patch();
void abort();
void abort_unsent();
void abort_opened();
@@ -639,6 +640,26 @@ void tst_qqmlxmlhttprequest::send_options_data()
QTest::newRow("OPTIONS (with data)") << "testdocument.html" << "send_data.10.expect" << "send_data.9.qml" << "send_data.2.reply";
}
+void tst_qqmlxmlhttprequest::send_patch()
+{
+ TestHTTPServer server;
+ QVERIFY2(server.listen(), qPrintable(server.errorString()));
+ QVERIFY(server.wait(testFileUrl("send_patch.expect"),
+ testFileUrl("send_patch.reply"),
+ // the content of response file will be ignored due to 204 status code
+ testFileUrl("testdocument.html")));
+
+ QQmlComponent component(&engine, testFileUrl("send_patch.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QVERIFY(!object.isNull());
+ object->setProperty("url", server.urlString("/qqmlxmlhttprequest.cpp"));
+ component.completeCreate();
+
+ QTRY_VERIFY(object->property("dataOK").toBool());
+ QTRY_VERIFY(object->property("headerOK").toBool());
+}
+
+
// Test abort() has no effect in unsent state
void tst_qqmlxmlhttprequest::abort_unsent()
{
diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
index f3ba3e8971..f19e82032a 100644
--- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
+++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
@@ -56,6 +56,7 @@ public slots:
}
private slots:
+ void initTestCase();
void basicProperties();
void showFiles();
void resetFiltering();
@@ -97,6 +98,15 @@ void tst_qquickfolderlistmodel::checkNoErrors(const QQmlComponent& component)
QVERIFY(!component.isError());
}
+void tst_qquickfolderlistmodel::initTestCase()
+{
+ // The tests rely on a fixed number of files in the directory with the qml files
+ // (the data dir), so disable the disk cache to avoid creating .qmlc files and
+ // confusing the test.
+ qputenv("QML_DISABLE_DISK_CACHE", "1");
+ QQmlDataTest::initTestCase();
+}
+
void tst_qquickfolderlistmodel::basicProperties()
{
QQmlComponent component(&engine, testFileUrl("basic.qml"));
diff --git a/tests/auto/qml/qv4mm/qv4mm.pro b/tests/auto/qml/qv4mm/qv4mm.pro
new file mode 100644
index 0000000000..d9b749af4a
--- /dev/null
+++ b/tests/auto/qml/qv4mm/qv4mm.pro
@@ -0,0 +1,8 @@
+CONFIG += testcase
+TARGET = tst_qv4mm
+osx:CONFIG -= app_bundle
+
+SOURCES += tst_qv4mm.cpp
+
+QT += qml qml-private testlib
+
diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
new file mode 100644
index 0000000000..d4ba363d00
--- /dev/null
+++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 basysKom GmbH.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QQmlEngine>
+#include <private/qv4mm_p.h>
+
+class tst_qv4mm : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void gcStats();
+ void tweaks();
+};
+
+void tst_qv4mm::gcStats()
+{
+ qputenv(QV4_MM_STATS, "1");
+ QQmlEngine engine;
+ engine.collectGarbage();
+}
+
+void tst_qv4mm::tweaks()
+{
+ qputenv(QV4_MM_MAXBLOCK_SHIFT, "5");
+ qputenv(QV4_MM_MAX_CHUNK_SIZE, "65536");
+ QQmlEngine engine;
+}
+
+QTEST_MAIN(tst_qv4mm)
+
+#include "tst_qv4mm.moc"
diff --git a/tests/auto/qmldevtools/compile/compile.pro b/tests/auto/qmldevtools/compile/compile.pro
index 54430eb668..832700698f 100644
--- a/tests/auto/qmldevtools/compile/compile.pro
+++ b/tests/auto/qmldevtools/compile/compile.pro
@@ -5,7 +5,7 @@ force_bootstrap {
!build_pass: CONFIG += release
} else {
QT = core
- !build_pass:contains(QT_CONFIG, debug_and_release): CONFIG += release
+ !build_pass:qtConfig(debug_and_release): CONFIG += release
}
QT += qmldevtools-private
macx:CONFIG -= app_bundle
diff --git a/tests/auto/qmldevtools/qmldevtools.pro b/tests/auto/qmldevtools/qmldevtools.pro
index a0ca1bff87..a9352d4df3 100644
--- a/tests/auto/qmldevtools/qmldevtools.pro
+++ b/tests/auto/qmldevtools/qmldevtools.pro
@@ -1,6 +1,4 @@
TEMPLATE = subdirs
-contains(QT_CONFIG, private_tests) {
- SUBDIRS += \
- compile
-}
+qtConfig(private_tests): \
+ SUBDIRS += compile
diff --git a/tests/auto/qmltest/selftests/tst_tryVerify.qml b/tests/auto/qmltest/selftests/tst_tryVerify.qml
new file mode 100644
index 0000000000..6f29d8643d
--- /dev/null
+++ b/tests/auto/qmltest/selftests/tst_tryVerify.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtTest 1.1
+
+TestCase {
+ name: "tst_tryVerify"
+
+ Item {
+ id: item
+ }
+
+ QtObject {
+ id: itemContainer
+ property Item i
+ }
+
+ Timer {
+ id: timer
+ interval: 100
+ onTriggered: itemContainer.i = item
+ }
+
+ function resetTimer() {
+ itemContainer.i = null;
+ timer.restart();
+ }
+
+ function test_tryVerify() {
+ timer.start();
+ tryVerify(function(){ return itemContainer.i; }, 200, "string");
+ compare(itemContainer.i, item);
+
+ resetTimer();
+ tryVerify(function(){ return itemContainer.i; }, 200);
+ compare(itemContainer.i, item);
+
+ resetTimer();
+ tryVerify(function(){ return itemContainer.i; });
+ compare(itemContainer.i, item);
+
+ resetTimer();
+ tryVerify(function(){ return !itemContainer.i; }, 0, "string");
+ verify(!itemContainer.i);
+ }
+}
diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp
index 233cb33631..872a71011d 100644
--- a/tests/auto/quick/examples/tst_examples.cpp
+++ b/tests/auto/quick/examples/tst_examples.cpp
@@ -103,6 +103,18 @@ tst_examples::tst_examples()
excludedFiles << "views/visualdatamodel/slideshow.qml";
#endif
+#ifdef QT_NO_OPENGL
+ //No support for Particles
+ excludedFiles << "examples/qml/dynamicscene/dynamicscene.qml";
+ excludedFiles << "examples/quick/animation/basics/color-animation.qml";
+ excludedFiles << "examples/quick/particles/affectors/content/age.qml";
+ excludedFiles << "examples/quick/touchinteraction/multipointtouch/bearwhack.qml";
+ excludedFiles << "examples/quick/touchinteraction/multipointtouch/multiflame.qml";
+ excludedDirs << "examples/quick/particles";
+ // No Support for ShaderEffect
+ excludedFiles << "src/quick/doc/snippets/qml/animators.qml";
+#endif
+
}
tst_examples::~tst_examples()
diff --git a/tests/auto/quick/geometry/tst_geometry.cpp b/tests/auto/quick/geometry/tst_geometry.cpp
index 8755e3a1d7..904f85c4c6 100644
--- a/tests/auto/quick/geometry/tst_geometry.cpp
+++ b/tests/auto/quick/geometry/tst_geometry.cpp
@@ -126,9 +126,9 @@ void GeometryTest::testCustomGeometry()
};
static QSGGeometry::Attribute attributes[] = {
- { 0, 2, GL_FLOAT, 0, 0},
- { 1, 4, GL_UNSIGNED_BYTE, 0, 0},
- { 2, 4, GL_FLOAT, 0, 0},
+ QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, false),
+ QSGGeometry::Attribute::create(1, 4, QSGGeometry::UnsignedByteType, false),
+ QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType, false)
};
static QSGGeometry::AttributeSet set = { 4, 6 * sizeof(float) + 4 * sizeof(unsigned char), attributes };
diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp
index 16c1174604..63e0aeb324 100644
--- a/tests/auto/quick/nodes/tst_nodestest.cpp
+++ b/tests/auto/quick/nodes/tst_nodestest.cpp
@@ -31,7 +31,6 @@
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
-
#include <QtQuick/qsgnode.h>
#include <QtQuick/private/qsgbatchrenderer_p.h>
#include <QtQuick/private/qsgnodeupdater_p.h>
@@ -76,7 +75,7 @@ private Q_SLOTS:
private:
QOffscreenSurface *surface;
QOpenGLContext *context;
- QSGRenderContext *renderContext;
+ QSGDefaultRenderContext *renderContext;
};
void NodesTest::initTestCase()
@@ -91,7 +90,8 @@ void NodesTest::initTestCase()
QVERIFY(context->create());
QVERIFY(context->makeCurrent(surface));
- renderContext = renderLoop->createRenderContext(renderLoop->sceneGraphContext());
+ auto rc = renderLoop->createRenderContext(renderLoop->sceneGraphContext());
+ renderContext = static_cast<QSGDefaultRenderContext *>(rc);
QVERIFY(renderContext);
renderContext->initialize(context);
QVERIFY(renderContext->isValid());
@@ -110,7 +110,7 @@ void NodesTest::cleanupTestCase()
class DummyRenderer : public QSGBatchRenderer::Renderer
{
public:
- DummyRenderer(QSGRootNode *root, QSGRenderContext *renderContext)
+ DummyRenderer(QSGRootNode *root, QSGDefaultRenderContext *renderContext)
: QSGBatchRenderer::Renderer(renderContext)
, changedNode(0)
, changedState(0)
diff --git a/tests/auto/quick/nokeywords/tst_nokeywords.cpp b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
index ffe76cc210..6c94b484ae 100644
--- a/tests/auto/quick/nokeywords/tst_nokeywords.cpp
+++ b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
@@ -48,13 +48,15 @@
#include <QtQuick/private/qsgadaptationlayer_p.h>
#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgcontextplugin_p.h>
+#ifndef QT_NO_OPENGL
#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h>
#include <QtQuick/private/qsgdefaultglyphnode_p.h>
-#include <QtQuick/private/qsgdefaultimagenode_p.h>
-#include <QtQuick/private/qsgdefaultrectanglenode_p.h>
+#include <QtQuick/private/qsgdefaultinternalimagenode_p.h>
+#include <QtQuick/private/qsgdefaultinternalrectanglenode_p.h>
#include <QtQuick/private/qsgdepthstencilbuffer_p.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
#include <QtQuick/private/qsgdistancefieldutil_p.h>
+#endif
#include <QtQuick/private/qsggeometry_p.h>
#include <QtQuick/private/qsgnode_p.h>
#include <QtQuick/private/qsgnodeupdater_p.h>
diff --git a/tests/auto/quick/qquickaccessible/qquickaccessible.pro b/tests/auto/quick/qquickaccessible/qquickaccessible.pro
index 02915e8e22..537aad882f 100644
--- a/tests/auto/quick/qquickaccessible/qquickaccessible.pro
+++ b/tests/auto/quick/qquickaccessible/qquickaccessible.pro
@@ -15,10 +15,3 @@ OTHER_FILES += data/checkbuttons.qml \
data/pushbutton.qml \
data/statictext.qml \
data/ignored.qml \
-
-wince*: {
- accessneeded.files = $$QT.widgets.plugins/accessible/*.dll
- accessneeded.path = accessible
- DEPLOYMENT += accessneeded
-}
-
diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
index b34f58f7c4..34b9fb6b07 100644
--- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
+++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
@@ -179,7 +179,11 @@ void tst_qquickanimatedimage::mirror_running()
QImage frame0_expected = frame0.transformed(transform);
QImage frame1_expected = frame1.transformed(transform);
+ if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
+ QSKIP("QTBUG-53823");
QCOMPARE(frame0_flipped, frame0_expected);
+ if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
+ QSKIP("QTBUG-53823");
QCOMPARE(frame1_flipped, frame1_expected);
delete anim;
@@ -212,6 +216,8 @@ void tst_qquickanimatedimage::mirror_notRunning()
screenshot = window.grabWindow();
screenshot.save("screen.png");
+ if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
+ QSKIP("QTBUG-53823");
QCOMPARE(screenshot, expected);
// mirroring should not change the current frame or playing status
diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
index 1bd163fc4a..114f906736 100644
--- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
+++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
@@ -47,6 +47,7 @@ private slots:
void active();
void state();
void layoutDirection();
+ void font();
void inputMethod();
void styleHints();
void cleanup();
@@ -196,6 +197,21 @@ void tst_qquickapplication::layoutDirection()
QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight);
}
+void tst_qquickapplication::font()
+{
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0; Item { property font defaultFont: Qt.application.font }", QUrl::fromLocalFile(""));
+ QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
+ QVERIFY(item);
+ QQuickView view;
+ item->setParentItem(view.rootObject());
+
+ QVariant defaultFontProperty = item->property("defaultFont");
+ QVERIFY(defaultFontProperty.isValid());
+ QCOMPARE(defaultFontProperty.type(), QVariant::Font);
+ QCOMPARE(defaultFontProperty.value<QFont>(), qApp->font());
+}
+
void tst_qquickapplication::inputMethod()
{
// technically not in QQuickApplication, but testing anyway here
diff --git a/tests/auto/quick/qquickborderimage/data/mesh.qml b/tests/auto/quick/qquickborderimage/data/mesh.qml
new file mode 100644
index 0000000000..203bf25867
--- /dev/null
+++ b/tests/auto/quick/qquickborderimage/data/mesh.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.8
+
+Item {
+ width: 300
+ height: 300
+ Image {
+ id: image
+ source: "colors.png"
+ visible: false
+ }
+ ShaderEffect {
+ anchors.fill: parent
+ property variant source: image
+ mesh: BorderImageMesh {
+ border.left: 30
+ border.right: 30
+ border.top: 30
+ border.bottom: 30
+ size: image.sourceSize
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickborderimage/data/nonmesh.qml b/tests/auto/quick/qquickborderimage/data/nonmesh.qml
new file mode 100644
index 0000000000..7a1830a942
--- /dev/null
+++ b/tests/auto/quick/qquickborderimage/data/nonmesh.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.8
+
+BorderImage {
+ width: 300
+ height: 300
+ source: "colors.png"
+ border.left: 30
+ border.right: 30
+ border.top: 30
+ border.bottom: 30
+}
diff --git a/tests/auto/quick/qquickborderimage/qquickborderimage.pro b/tests/auto/quick/qquickborderimage/qquickborderimage.pro
index 3e16063559..ba6c01737a 100644
--- a/tests/auto/quick/qquickborderimage/qquickborderimage.pro
+++ b/tests/auto/quick/qquickborderimage/qquickborderimage.pro
@@ -7,6 +7,7 @@ SOURCES += tst_qquickborderimage.cpp \
../../shared/testhttpserver.cpp
include (../../shared/util.pri)
+include (../shared/util.pri)
TESTDATA = data/*
diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
index c11ae1e8c9..5d242fab9e 100644
--- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
+++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
@@ -44,6 +44,7 @@
#include "../../shared/testhttpserver.h"
#include "../../shared/util.h"
+#include "../shared/visualtestutil.h"
Q_DECLARE_METATYPE(QQuickImageBase::Status)
@@ -75,6 +76,9 @@ private slots:
void statusChanges_data();
void sourceSizeChanges();
void progressAndStatusChanges();
+#ifndef QT_NO_OPENGL
+ void borderImageMesh();
+#endif
private:
QQmlEngine engine;
@@ -242,6 +246,11 @@ void tst_qquickborderimage::mirror()
image->setProperty("mirror", true);
screenshot = window->grabWindow();
+
+ window->show();
+ QTest::qWaitForWindowExposed(window);
+ if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
+ QSKIP("QTBUG-53823");
QCOMPARE(screenshot, srcPixmap);
delete window;
@@ -574,7 +583,22 @@ void tst_qquickborderimage::progressAndStatusChanges()
delete obj;
}
+#ifndef QT_NO_OPENGL
+void tst_qquickborderimage::borderImageMesh()
+{
+ QQuickView *window = new QQuickView;
+ window->setSource(testFileUrl("nonmesh.qml"));
+ window->show();
+ QTest::qWaitForWindowExposed(window);
+ QImage nonmesh = window->grabWindow();
+
+ window->setSource(testFileUrl("mesh.qml"));
+ QImage mesh = window->grabWindow();
+
+ QVERIFY(QQuickVisualTestUtil::compareImages(mesh, nonmesh));
+}
+#endif
QTEST_MAIN(tst_qquickborderimage)
#include "tst_qquickborderimage.moc"
diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
index e49f0ac462..b0fb7fcf8c 100644
--- a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
@@ -31,7 +31,9 @@ TestCase {
}
function createCanvasObject(data) {
- return component.createObject(testCase, data.properties);
+ var canvas = component.createObject(testCase, data.properties);
+ waitForRendering(canvas);
+ return canvas;
}
function comparePixel(ctx,x,y,r,g,b,a, d)
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
index 93f85107a7..565f906fb1 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
@@ -590,6 +590,7 @@ CanvasTestCase {
verify(canvas);
canvas.width = 100;
canvas.height = 100;
+ waitForRendering(canvas);
var ctx = canvas.getContext("2d");
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
index 46a038a13c..1f695d7080 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
@@ -667,6 +667,7 @@ CanvasTestCase {
var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image; renderStrategy:Canvas.Immediate}", canvas);
canvas2.width = 100;
canvas2.height = 50;
+ waitForRendering(canvas2);
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = '#0f0';
ctx2.fillRect(0, 0, 100, 50);
diff --git a/tests/auto/quick/qquickflickable/data/contentXY.qml b/tests/auto/quick/qquickflickable/data/contentXY.qml
new file mode 100644
index 0000000000..8215976949
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/contentXY.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+Flickable {
+ width: 400; height: 400
+ contentWidth: 1e11; contentHeight: 1e11
+}
diff --git a/tests/auto/quick/qquickflickable/data/keepGrab.qml b/tests/auto/quick/qquickflickable/data/keepGrab.qml
new file mode 100644
index 0000000000..32546658d0
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/keepGrab.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.3
+
+Flickable {
+ id: flickable
+ width: 400
+ height: 400
+ contentWidth: 800
+ contentHeight: 800
+
+ Rectangle {
+ x: 200
+ y: 200
+ width: 400
+ height: 400
+ color: "green"
+ MouseArea {
+ id: ma
+ objectName: "ma"
+ anchors.fill: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index d0f015324c..b774481592 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -93,6 +93,8 @@ private slots:
void cleanup();
void contentSize();
void ratios_smallContent();
+ void contentXYNotTruncatedToInt();
+ void keepGrab();
private:
void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
@@ -1223,7 +1225,9 @@ void tst_qquickflickable::flickOnRelease()
QTRY_VERIFY(!flickable->isMoving());
#ifdef Q_OS_MAC
+# ifndef QT_NO_OPENGL
QEXPECT_FAIL("", "QTBUG-26094 stopping on a full pixel doesn't work on OS X", Continue);
+# endif
#endif
// Stop on a full pixel after user interaction
QCOMPARE(flickable->contentY(), (qreal)qRound(flickable->contentY()));
@@ -1966,6 +1970,72 @@ void tst_qquickflickable::ratios_smallContent()
QCOMPARE(obj->property("widthRatioIs").toDouble(), 1.);
}
+// QTBUG-48018
+void tst_qquickflickable::contentXYNotTruncatedToInt()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("contentXY.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable);
+
+ flickable->setContentX(1e10);
+ flick(window.data(), QPoint(200, 100), QPoint(100, 100), 50);
+
+ // make sure we are not clipped at 2^31
+ QVERIFY(flickable->contentX() > qreal(1e10));
+}
+
+void tst_qquickflickable::keepGrab()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("keepGrab.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable);
+
+ QQuickMouseArea *ma = flickable->findChild<QQuickMouseArea*>("ma");
+ QVERIFY(ma);
+ ma->setPreventStealing(true);
+
+ QPoint pos(250, 250);
+ moveAndPress(window.data(), pos);
+ for (int i = 0; i < 6; ++i) {
+ pos += QPoint(10, 10);
+ QTest::mouseMove(window.data(), pos);
+ QTest::qWait(10);
+ }
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(310, 310));
+ QTest::qWait(10);
+
+ QCOMPARE(flickable->contentX(), 0.0);
+ QCOMPARE(flickable->contentY(), 0.0);
+
+ ma->setPreventStealing(false);
+
+ pos = QPoint(250, 250);
+ moveAndPress(window.data(), pos);
+ for (int i = 0; i < 6; ++i) {
+ pos += QPoint(10, 10);
+ QTest::mouseMove(window.data(), pos);
+ QTest::qWait(10);
+ }
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(310, 310));
+ QTest::qWait(10);
+
+ QVERIFY(flickable->contentX() != 0.0);
+ QVERIFY(flickable->contentY() != 0.0);
+}
QTEST_MAIN(tst_qquickflickable)
diff --git a/tests/auto/quick/qquickgraphicsinfo/data/basic.qml b/tests/auto/quick/qquickgraphicsinfo/data/basic.qml
new file mode 100644
index 0000000000..6ff3b82cec
--- /dev/null
+++ b/tests/auto/quick/qquickgraphicsinfo/data/basic.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.8
+
+Item {
+ property int api: GraphicsInfo.api
+
+ property int shaderType: GraphicsInfo.shaderType
+ property int shaderCompilationType: GraphicsInfo.shaderCompilationType
+ property int shaderSourceType: GraphicsInfo.shaderSourceType
+
+ property int majorVersion: GraphicsInfo.majorVersion
+ property int minorVersion: GraphicsInfo.minorVersion
+ property int profile: GraphicsInfo.profile
+ property int renderableType: GraphicsInfo.renderableType
+}
diff --git a/tests/auto/quick/qquickgraphicsinfo/qquickgraphicsinfo.pro b/tests/auto/quick/qquickgraphicsinfo/qquickgraphicsinfo.pro
new file mode 100644
index 0000000000..a4296ad9a2
--- /dev/null
+++ b/tests/auto/quick/qquickgraphicsinfo/qquickgraphicsinfo.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qquickgraphicsinfo
+SOURCES += tst_qquickgraphicsinfo.cpp
+
+TESTDATA = data/*
+include(../../shared/util.pri)
+
+osx:CONFIG -= app_bundle
+
+QT += quick testlib
+
+OTHER_FILES += \
+ data/basic.qml
+
diff --git a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp
new file mode 100644
index 0000000000..256fa43d2e
--- /dev/null
+++ b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qsgrendererinterface.h>
+
+#include "../../shared/util.h"
+
+#ifndef QT_NO_OPENGL
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qsurfaceformat.h>
+#endif
+
+class tst_QQuickGraphicsInfo : public QQmlDataTest
+{
+ Q_OBJECT
+
+private slots:
+ void testProperties();
+};
+
+void tst_QQuickGraphicsInfo::testProperties()
+{
+ QQuickView view;
+ view.setSource(QUrl::fromLocalFile("data/basic.qml"));
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy spy(&view, SIGNAL(sceneGraphInitialized()));
+ spy.wait();
+
+ QObject* obj = view.rootObject();
+ QVERIFY(obj);
+
+ QSGRendererInterface *rif = view.rendererInterface();
+ const int expectedAPI = rif ? rif->graphicsApi() : QSGRendererInterface::Unknown;
+
+ QCOMPARE(obj->property("api").toInt(), expectedAPI);
+
+#ifndef QT_NO_OPENGL
+ if (expectedAPI == QSGRendererInterface::OpenGL) {
+ QCOMPARE(obj->property("shaderType").toInt(), int(QSGRendererInterface::GLSL));
+ QVERIFY(view.openglContext());
+ QSurfaceFormat format = view.openglContext()->format();
+ QCOMPARE(obj->property("majorVersion").toInt(), format.majorVersion());
+ QCOMPARE(obj->property("minorVersion").toInt(), format.minorVersion());
+ QCOMPARE(obj->property("profile").toInt(), static_cast<int>(format.profile()));
+ QCOMPARE(obj->property("renderableType").toInt(), static_cast<int>(format.renderableType()));
+ }
+#endif
+}
+
+QTEST_MAIN(tst_QQuickGraphicsInfo)
+
+#include "tst_qquickgraphicsinfo.moc"
diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
index 9274a1ac9e..d345163db5 100644
--- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp
+++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
@@ -306,6 +306,7 @@ void tst_qquickimage::mirror()
qreal width = 300;
qreal height = 250;
+ qreal devicePixelRatio = 1.0;
foreach (QQuickImage::FillMode fillMode, fillModes) {
#if defined(Q_OS_BLACKBERRY)
@@ -325,13 +326,15 @@ void tst_qquickimage::mirror()
QImage screenshot = window->grabWindow();
screenshots[fillMode] = screenshot;
+ devicePixelRatio = window->devicePixelRatio();
}
foreach (QQuickImage::FillMode fillMode, fillModes) {
QPixmap srcPixmap;
QVERIFY(srcPixmap.load(testFile("pattern.png")));
- QPixmap expected(width, height);
+ QPixmap expected(width * (int)devicePixelRatio, height * (int)devicePixelRatio);
+ expected.setDevicePixelRatio(devicePixelRatio);
expected.fill();
QPainter p_e(&expected);
QTransform transform;
diff --git a/tests/auto/quick/qquickitem2/data/layoutmirroring_window.qml b/tests/auto/quick/qquickitem2/data/layoutmirroring_window.qml
new file mode 100644
index 0000000000..3bac0716e8
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/layoutmirroring_window.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+import QtQuick.Window 2.0
+
+Window {
+ LayoutMirroring.enabled: true
+ LayoutMirroring.childrenInherit: true
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index 438c7bacf1..78322b44a1 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -88,6 +88,7 @@ private slots:
void keyNavigation_focusReason();
void keyNavigation_loop();
void layoutMirroring();
+ void layoutMirroringWindow();
void layoutMirroringIllegalParent();
void smooth();
void antialiasing();
@@ -1776,11 +1777,28 @@ void tst_QQuickItem::layoutMirroring()
delete parentItem2;
}
+void tst_QQuickItem::layoutMirroringWindow()
+{
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("layoutmirroring_window.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(object.data());
+ QVERIFY(window);
+ window->show();
+
+ QQuickItemPrivate *content = QQuickItemPrivate::get(window->contentItem());
+ QCOMPARE(content->effectiveLayoutMirror, true);
+ QCOMPARE(content->inheritedLayoutMirror, true);
+ QCOMPARE(content->isMirrorImplicit, false);
+ QCOMPARE(content->inheritMirrorFromParent, true);
+ QCOMPARE(content->inheritMirrorFromItem, true);
+}
+
void tst_QQuickItem::layoutMirroringIllegalParent()
{
QQmlComponent component(&engine);
component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile(""));
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>:1:21: QML QtObject: LayoutDirection attached property only works with Items");
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>:1:21: QML QtObject: LayoutDirection attached property only works with Items and Windows");
QObject *object = component.create();
QVERIFY(object != 0);
}
@@ -2706,113 +2724,122 @@ void tst_QQuickItem::childrenRectBottomRightCorner()
struct TestListener : public QQuickItemChangeListener
{
- TestListener(bool remove = false) : remove(remove) { reset(); }
-
- void itemGeometryChanged(QQuickItem *, const QRectF &newGeometry, const QRectF &) override { ++itemGeometryChanges; value = newGeometry; }
- void itemSiblingOrderChanged(QQuickItem *) override { ++itemSiblingOrderChanges; }
- void itemVisibilityChanged(QQuickItem *) override { ++itemVisibilityChanges; }
- void itemOpacityChanged(QQuickItem *) override { ++itemOpacityChanges; }
- void itemRotationChanged(QQuickItem *) override { ++itemRotationChanges; }
- void itemImplicitWidthChanged(QQuickItem *) override { ++itemImplicitWidthChanges; }
- void itemImplicitHeightChanged(QQuickItem *) override { ++itemImplicitHeightChanges; }
+ TestListener(bool remove = false) : remove(remove) { }
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &oldGeometry) override
+ {
+ record(item, QQuickItemPrivate::Geometry, oldGeometry);
+ }
+ void itemSiblingOrderChanged(QQuickItem *item) override
+ {
+ record(item, QQuickItemPrivate::SiblingOrder);
+ }
+ void itemVisibilityChanged(QQuickItem *item) override
+ {
+ record(item, QQuickItemPrivate::Visibility);
+ }
+ void itemOpacityChanged(QQuickItem *item) override
+ {
+ record(item, QQuickItemPrivate::Opacity);
+ }
+ void itemRotationChanged(QQuickItem *item) override
+ {
+ record(item, QQuickItemPrivate::Rotation);
+ }
+ void itemImplicitWidthChanged(QQuickItem *item) override
+ {
+ record(item, QQuickItemPrivate::ImplicitWidth);
+ }
+ void itemImplicitHeightChanged(QQuickItem *item) override
+ {
+ record(item, QQuickItemPrivate::ImplicitHeight);
+ }
void itemDestroyed(QQuickItem *item) override
{
- ++itemDestructions;
- // QTBUG-53453
- if (remove)
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
+ record(item, QQuickItemPrivate::Destroyed);
}
void itemChildAdded(QQuickItem *item, QQuickItem *child) override
{
- ++itemChildAdditions;
- value = QVariant::fromValue(child);
- // QTBUG-53453
- if (remove)
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Children);
+ record(item, QQuickItemPrivate::Children, QVariant::fromValue(child));
}
void itemChildRemoved(QQuickItem *item, QQuickItem *child) override
{
- ++itemChildRemovals;
- value = QVariant::fromValue(child);
- // QTBUG-53453
- if (remove)
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Children);
+ record(item, QQuickItemPrivate::Children, QVariant::fromValue(child));
}
void itemParentChanged(QQuickItem *item, QQuickItem *parent) override
{
- ++itemParentChanges;
- value = QVariant::fromValue(parent);
- // QTBUG-53453
- if (remove)
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Parent);
+ record(item, QQuickItemPrivate::Parent, QVariant::fromValue(parent));
}
QQuickAnchorsPrivate *anchorPrivate() override { return nullptr; }
- void reset()
+ void record(QQuickItem *item, QQuickItemPrivate::ChangeType change, const QVariant &value = QVariant())
+ {
+ changes += change;
+ values[change] = value;
+ // QTBUG-54732
+ if (remove)
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, change);
+ }
+
+ int count(QQuickItemPrivate::ChangeType change) const
+ {
+ return changes.count(change);
+ }
+
+ QVariant value(QQuickItemPrivate::ChangeType change) const
{
- value = QVariant();
- itemGeometryChanges = 0;
- itemSiblingOrderChanges = 0;
- itemVisibilityChanges = 0;
- itemOpacityChanges = 0;
- itemDestructions = 0;
- itemChildAdditions = 0;
- itemChildRemovals = 0;
- itemParentChanges = 0;
- itemRotationChanges = 0;
- itemImplicitWidthChanges = 0;
- itemImplicitHeightChanges = 0;
+ return values.value(change);
}
bool remove;
- QVariant value;
- int itemGeometryChanges;
- int itemSiblingOrderChanges;
- int itemVisibilityChanges;
- int itemOpacityChanges;
- int itemDestructions;
- int itemChildAdditions;
- int itemChildRemovals;
- int itemParentChanges;
- int itemRotationChanges;
- int itemImplicitWidthChanges;
- int itemImplicitHeightChanges;
+ QList<QQuickItemPrivate::ChangeType> changes;
+ QHash<QQuickItemPrivate::ChangeType, QVariant> values;
};
void tst_QQuickItem::changeListener()
{
- QQuickItem item;
+ QQuickWindow window;
+ window.show();
+ QTest::qWaitForWindowExposed(&window);
+
+ QQuickItem *item = new QQuickItem;
TestListener itemListener;
- QQuickItemPrivate::get(&item)->addItemChangeListener(&itemListener, QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight |
- QQuickItemPrivate::Opacity | QQuickItemPrivate::Rotation);
+ QQuickItemPrivate::get(item)->addItemChangeListener(&itemListener, QQuickItemPrivate::ChangeTypes(0xffff));
- item.setImplicitWidth(50);
- QCOMPARE(itemListener.itemImplicitWidthChanges, 1);
- QCOMPARE(itemListener.itemGeometryChanges, 1);
- QCOMPARE(itemListener.value, QVariant(QRectF(0,0,50,0)));
+ item->setImplicitWidth(10);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitWidth), 1);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 1);
+ QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,0)));
- item.setImplicitHeight(50);
- QCOMPARE(itemListener.itemImplicitHeightChanges, 1);
- QCOMPARE(itemListener.itemGeometryChanges, 2);
- QCOMPARE(itemListener.value, QVariant(QRectF(0,0,50,50)));
+ item->setImplicitHeight(20);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitHeight), 1);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 2);
+ QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,0)));
- item.setWidth(100);
- QCOMPARE(itemListener.itemGeometryChanges, 3);
- QCOMPARE(itemListener.value, QVariant(QRectF(0,0,100,50)));
+ item->setWidth(item->width() + 30);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 3);
+ QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,20)));
- item.setHeight(100);
- QCOMPARE(itemListener.itemGeometryChanges, 4);
- QCOMPARE(itemListener.value, QVariant(QRectF(0,0,100,100)));
+ item->setHeight(item->height() + 40);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 4);
+ QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,40,20)));
- item.setOpacity(0.5);
- QCOMPARE(itemListener.itemOpacityChanges, 1);
+ item->setOpacity(0.5);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Opacity), 1);
- item.setRotation(90);
- QCOMPARE(itemListener.itemRotationChanges, 1);
+ item->setRotation(90);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Rotation), 1);
- QQuickItem *parent = new QQuickItem;
+ item->setParentItem(window.contentItem());
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Parent), 1);
+
+ item->setVisible(false);
+ QCOMPARE(itemListener.count(QQuickItemPrivate::Visibility), 1);
+
+ QQuickItemPrivate::get(item)->removeItemChangeListener(&itemListener, QQuickItemPrivate::ChangeTypes(0xffff));
+
+ QQuickItem *parent = new QQuickItem(window.contentItem());
TestListener parentListener;
QQuickItemPrivate::get(parent)->addItemChangeListener(&parentListener, QQuickItemPrivate::Children);
@@ -2824,52 +2851,79 @@ void tst_QQuickItem::changeListener()
QQuickItemPrivate::get(child2)->addItemChangeListener(&child2Listener, QQuickItemPrivate::Parent | QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::Destroyed);
child1->setParentItem(parent);
- QCOMPARE(parentListener.itemChildAdditions, 1);
- QCOMPARE(parentListener.value, QVariant::fromValue(child1));
- QCOMPARE(child1Listener.itemParentChanges, 1);
- QCOMPARE(child1Listener.value, QVariant::fromValue(parent));
+ QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 1);
+ QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child1));
+ QCOMPARE(child1Listener.count(QQuickItemPrivate::Parent), 1);
+ QCOMPARE(child1Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue(parent));
child2->setParentItem(parent);
- QCOMPARE(parentListener.itemChildAdditions, 2);
- QCOMPARE(parentListener.value, QVariant::fromValue(child2));
- QCOMPARE(child2Listener.itemParentChanges, 1);
- QCOMPARE(child2Listener.value, QVariant::fromValue(parent));
+ QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 2);
+ QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child2));
+ QCOMPARE(child2Listener.count(QQuickItemPrivate::Parent), 1);
+ QCOMPARE(child2Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue(parent));
child2->stackBefore(child1);
- QCOMPARE(child1Listener.itemSiblingOrderChanges, 1);
- QCOMPARE(child2Listener.itemSiblingOrderChanges, 1);
+ QCOMPARE(child1Listener.count(QQuickItemPrivate::SiblingOrder), 1);
+ QCOMPARE(child2Listener.count(QQuickItemPrivate::SiblingOrder), 1);
child1->setParentItem(nullptr);
- QCOMPARE(parentListener.itemChildRemovals, 1);
- QCOMPARE(parentListener.value, QVariant::fromValue(child1));
- QCOMPARE(child1Listener.itemParentChanges, 2);
- QCOMPARE(child1Listener.value, QVariant::fromValue<QQuickItem *>(nullptr));
+ QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 3);
+ QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child1));
+ QCOMPARE(child1Listener.count(QQuickItemPrivate::Parent), 2);
+ QCOMPARE(child1Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue<QQuickItem *>(nullptr));
delete child1;
- QCOMPARE(child1Listener.itemDestructions, 1);
+ QCOMPARE(child1Listener.count(QQuickItemPrivate::Destroyed), 1);
delete child2;
- QCOMPARE(parentListener.itemChildRemovals, 2);
- QCOMPARE(parentListener.value, QVariant::fromValue(child2));
- QCOMPARE(child2Listener.itemParentChanges, 2);
- QCOMPARE(child2Listener.value, QVariant::fromValue<QQuickItem *>(nullptr));
- QCOMPARE(child2Listener.itemDestructions, 1);
+ QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 4);
+ QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child2));
+ QCOMPARE(child2Listener.count(QQuickItemPrivate::Parent), 2);
+ QCOMPARE(child2Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue<QQuickItem *>(nullptr));
+ QCOMPARE(child2Listener.count(QQuickItemPrivate::Destroyed), 1);
QQuickItemPrivate::get(parent)->removeItemChangeListener(&parentListener, QQuickItemPrivate::Children);
QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
- // QTBUG-53453: all listeners should get invoked even if they remove themselves while iterating the listeners
+ // QTBUG-54732: all listeners should get invoked even if they remove themselves while iterating the listeners
QList<TestListener *> listeners;
for (int i = 0; i < 5; ++i)
listeners << new TestListener(true);
+ // itemVisibilityChanged x 5
+ foreach (TestListener *listener, listeners)
+ QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Visibility);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
+ parent->setVisible(false);
+ foreach (TestListener *listener, listeners)
+ QCOMPARE(listener->count(QQuickItemPrivate::Visibility), 1);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
+
+ // itemRotationChanged x 5
+ foreach (TestListener *listener, listeners)
+ QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Rotation);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
+ parent->setRotation(90);
+ foreach (TestListener *listener, listeners)
+ QCOMPARE(listener->count(QQuickItemPrivate::Rotation), 1);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
+
+ // itemOpacityChanged x 5
+ foreach (TestListener *listener, listeners)
+ QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Opacity);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
+ parent->setOpacity(0.5);
+ foreach (TestListener *listener, listeners)
+ QCOMPARE(listener->count(QQuickItemPrivate::Opacity), 1);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
+
// itemChildAdded() x 5
foreach (TestListener *listener, listeners)
QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Children);
QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
child1 = new QQuickItem(parent);
foreach (TestListener *listener, listeners)
- QCOMPARE(listener->itemChildAdditions, 1);
+ QCOMPARE(listener->count(QQuickItemPrivate::Children), 1);
QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
// itemParentChanged() x 5
@@ -2878,9 +2932,36 @@ void tst_QQuickItem::changeListener()
QCOMPARE(QQuickItemPrivate::get(child1)->changeListeners.count(), listeners.count());
child1->setParentItem(nullptr);
foreach (TestListener *listener, listeners)
- QCOMPARE(listener->itemParentChanges, 1);
+ QCOMPARE(listener->count(QQuickItemPrivate::Parent), 1);
QCOMPARE(QQuickItemPrivate::get(child1)->changeListeners.count(), 0);
+ // itemImplicitWidthChanged() x 5
+ foreach (TestListener *listener, listeners)
+ QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::ImplicitWidth);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
+ parent->setImplicitWidth(parent->implicitWidth() + 1);
+ foreach (TestListener *listener, listeners)
+ QCOMPARE(listener->count(QQuickItemPrivate::ImplicitWidth), 1);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
+
+ // itemImplicitHeightChanged() x 5
+ foreach (TestListener *listener, listeners)
+ QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::ImplicitHeight);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
+ parent->setImplicitHeight(parent->implicitHeight() + 1);
+ foreach (TestListener *listener, listeners)
+ QCOMPARE(listener->count(QQuickItemPrivate::ImplicitHeight), 1);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
+
+ // itemGeometryChanged() x 5
+ foreach (TestListener *listener, listeners)
+ QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Geometry);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
+ parent->setWidth(parent->width() + 1);
+ foreach (TestListener *listener, listeners)
+ QCOMPARE(listener->count(QQuickItemPrivate::Geometry), 1);
+ QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
+
// itemChildRemoved() x 5
child1->setParentItem(parent);
foreach (TestListener *listener, listeners)
@@ -2888,7 +2969,7 @@ void tst_QQuickItem::changeListener()
QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
delete child1;
foreach (TestListener *listener, listeners)
- QCOMPARE(listener->itemChildRemovals, 1);
+ QCOMPARE(listener->count(QQuickItemPrivate::Children), 2);
QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0);
// itemDestroyed() x 5
@@ -2897,7 +2978,7 @@ void tst_QQuickItem::changeListener()
QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count());
delete parent;
foreach (TestListener *listener, listeners)
- QCOMPARE(listener->itemDestructions, 1);
+ QCOMPARE(listener->count(QQuickItemPrivate::Destroyed), 1);
}
// QTBUG-13893
@@ -3223,7 +3304,7 @@ void tst_QQuickItem::grab()
QVERIFY(root);
QQuickItem *item = root->findChild<QQuickItem *>("myItem");
QVERIFY(item);
-
+#ifndef QT_NO_OPENGL
{ // Default size (item is 100x100)
QSharedPointer<QQuickItemGrabResult> result = item->grabToImage();
QSignalSpy spy(result.data(), SIGNAL(ready()));
@@ -3244,7 +3325,7 @@ void tst_QQuickItem::grab()
QCOMPARE(image.pixel(0, 0), qRgb(255, 0, 0));
QCOMPARE(image.pixel(49, 49), qRgb(0, 0, 255));
}
-
+#endif
}
void tst_QQuickItem::isAncestorOf()
diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
index 92b7196919..2576a1b0fc 100644
--- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
+++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
@@ -30,6 +30,7 @@
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
+#include <QtQuick/qsgrendererinterface.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglfunctions.h>
@@ -60,9 +61,10 @@ private slots:
void initTestCase() Q_DECL_OVERRIDE;
void layerEnabled();
void layerSmooth();
+#ifndef QT_NO_OPENGL
void layerMipmap();
void layerEffect();
-
+#endif
void layerVisibility_data();
void layerVisibility();
@@ -90,17 +92,20 @@ private:
bool m_isMesaSoftwareRasterizer;
int m_mesaVersion;
+ bool m_isOpenGLRenderer;
};
tst_QQuickItemLayer::tst_QQuickItemLayer()
: m_isMesaSoftwareRasterizer(false)
, m_mesaVersion(0)
+ , m_isOpenGLRenderer(true)
{
}
void tst_QQuickItemLayer::initTestCase()
{
QQmlDataTest::initTestCase();
+#ifndef QT_NO_OPENGL
QWindow window;
QOpenGLContext context;
window.setSurfaceType(QWindow::OpenGLSurface);
@@ -129,6 +134,13 @@ void tst_QQuickItemLayer::initTestCase()
m_mesaVersion = QT_VERSION_CHECK(major, minor, patch);
}
}
+ window.create();
+#endif
+ QQuickView view;
+ view.showNormal();
+ QTest::qWaitForWindowExposed(&view);
+ if (view.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
+ m_isOpenGLRenderer = false;
}
// The test draws a red and a blue box next to each other and tests that the
@@ -165,8 +177,7 @@ void tst_QQuickItemLayer::layerEnabled()
QVERIFY(fb.pixel(0, 0) != fb.pixel(0, fb.height() - 1));
}
-
-
+#ifndef QT_NO_OPENGL
// The test draws a one pixel wide line and scales it down by more than a a factor 2
// If mipmpping works, the pixels should be gray, not white or black
@@ -192,8 +203,7 @@ void tst_QQuickItemLayer::layerEffect()
QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0));
}
-
-
+#endif
// The test draws a rectangle and verifies that there is padding on each side
// as the source rect spans outside the item. The padding is verified using
@@ -203,6 +213,9 @@ void tst_QQuickItemLayer::layerSourceRect()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QImage fb = runTest("SourceRect.qml");
// Check that the edges are converted to blue
@@ -223,6 +236,10 @@ void tst_QQuickItemLayer::layerIsTextureProvider()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QImage fb = runTest("TextureProvider.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0));
@@ -256,6 +273,9 @@ void tst_QQuickItemLayer::layerVisibility()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QFETCH(bool, visible);
QFETCH(bool, effect);
QFETCH(qreal, opacity);
@@ -304,6 +324,9 @@ void tst_QQuickItemLayer::layerZOrder()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QFETCH(bool, effect);
QQuickView view;
@@ -338,6 +361,9 @@ void tst_QQuickItemLayer::changeZOrder()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QFETCH(bool, layered);
QFETCH(bool, effect);
@@ -405,6 +431,10 @@ void tst_QQuickItemLayer::changeSamplerName()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QImage fb = runTest("SamplerNameChange.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0, 0, 0xff));
}
@@ -413,6 +443,9 @@ void tst_QQuickItemLayer::itemEffect()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QImage fb = runTest("ItemEffect.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
QCOMPARE(fb.pixel(199, 0), qRgb(0xff, 0, 0));
@@ -448,6 +481,9 @@ void tst_QQuickItemLayer::textureMirroring()
{
QFETCH(int, mirroring);
+ if (!m_isOpenGLRenderer)
+ QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
+
QQuickView view;
view.setSource(testFileUrl("TextureMirroring.qml"));
diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST
index 269696ce8c..d259c11219 100644
--- a/tests/auto/quick/qquicklistview/BLACKLIST
+++ b/tests/auto/quick/qquicklistview/BLACKLIST
@@ -2,3 +2,6 @@
*
[enforceRange_withoutHighlight]
osx
+#QTBUG-53863
+[populateTransitions]
+opensuse-42.1
diff --git a/tests/auto/quick/qquickloader/data/qmldir b/tests/auto/quick/qquickloader/data/qmldir
deleted file mode 100644
index bf42b507c0..0000000000
--- a/tests/auto/quick/qquickloader/data/qmldir
+++ /dev/null
@@ -1 +0,0 @@
-# For tst_QDeclarativeLoader::networkRequestUrl; no types needed though.
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index fe22a238b2..77af4796b6 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -213,7 +213,7 @@ void tst_QQuickLoader::sourceOrComponent_data()
QTest::newRow("source with encoded subdir binding") << "source" << "source: encodeURIComponent('subdir/Test.qml')\n" << testFileUrl("subdir/Test.qml") << "";
QTest::newRow("sourceComponent") << "component" << "Component { id: comp; Rectangle { width: 100; height: 50 } }\n sourceComponent: comp\n" << QUrl() << "";
QTest::newRow("invalid source") << "source" << "source: 'IDontExist.qml'\n" << testFileUrl("IDontExist.qml")
- << QString(testFileUrl("IDontExist.qml").toString() + ": File not found");
+ << QString(testFileUrl("IDontExist.qml").toString() + ": No such file or directory");
}
void tst_QQuickLoader::clear()
@@ -748,7 +748,7 @@ void tst_QQuickLoader::initialPropertyValuesError_data()
<< (QStringList() << QString(testFileUrl("initialPropertyValues.error.1.qml").toString() + ":6:5: QML Loader: setSource: value is not an object"));
QTest::newRow("nonexistent source url") << testFileUrl("initialPropertyValues.error.2.qml")
- << (QStringList() << QString(testFileUrl("NonexistentSourceComponent.qml").toString() + ": File not found"));
+ << (QStringList() << QString(testFileUrl("NonexistentSourceComponent.qml").toString() + ": No such file or directory"));
QTest::newRow("invalid source url") << testFileUrl("initialPropertyValues.error.3.qml")
<< (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error"));
@@ -901,7 +901,7 @@ void tst_QQuickLoader::asynchronous_data()
<< QStringList();
QTest::newRow("Non-existent component") << testFileUrl("IDoNotExist.qml")
- << (QStringList() << QString(testFileUrl("IDoNotExist.qml").toString() + ": File not found"));
+ << (QStringList() << QString(testFileUrl("IDoNotExist.qml").toString() + ": No such file or directory"));
QTest::newRow("Invalid component") << testFileUrl("InvalidSourceComponent.qml")
<< (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error"));
diff --git a/tests/auto/quick/qquickmousearea/data/qtbug54019.qml b/tests/auto/quick/qquickmousearea/data/qtbug54019.qml
new file mode 100644
index 0000000000..75cca2691a
--- /dev/null
+++ b/tests/auto/quick/qquickmousearea/data/qtbug54019.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.7
+
+Item {
+ width: 200
+ height: 200
+ MouseArea {
+ id: ma
+ property string str: "foo!"
+ width: 150; height: 150
+ hoverEnabled: true
+
+ Rectangle {
+ anchors.fill: parent
+ color: ma.containsMouse ? "lightsteelblue" : "gray"
+ }
+ Text {
+ text: ma.str
+ textFormat: Text.PlainText // consequently Text does not care about hover events
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 5891e67df6..f22528a8a0 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QtTest>
#include <QtTest/QSignalSpy>
#include <QtQuick/private/qquickdrag_p.h>
+#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickmousearea_p.h>
#include <QtQuick/private/qquickrectangle_p.h>
#include <private/qquickflickable_p.h>
@@ -107,6 +108,7 @@ private slots:
void hoverPropagation();
void hoverVisible();
void hoverAfterPress();
+ void subtreeHoverEnabled();
void disableAfterPress();
void onWheel();
void transformedMouseArea_data();
@@ -124,8 +126,12 @@ private slots:
void containsPress_data();
void containsPress();
void ignoreBySource();
+ void notPressedAfterStolenGrab();
private:
+ int startDragDistance() const {
+ return QGuiApplication::styleHints()->startDragDistance();
+ }
void acceptedButton_data();
void rejectedButton_data();
QTouchDevice *device;
@@ -321,7 +327,8 @@ void tst_QQuickMouseArea::dragging()
QVERIFY(!drag->active());
- QTest::mousePress(&window, button, 0, QPoint(100,100));
+ QPoint p = QPoint(100,100);
+ QTest::mousePress(&window, button, 0, p);
QVERIFY(!drag->active());
QCOMPARE(blackRect->x(), 50.0);
@@ -332,18 +339,32 @@ void tst_QQuickMouseArea::dragging()
// The item is moved relative to the position of the mouse when the drag
// was triggered, this prevents a sudden change in position when the drag
// threshold is exceeded.
- QTest::mouseMove(&window, QPoint(111,111), 50);
- QTest::mouseMove(&window, QPoint(116,116), 50);
- QTest::mouseMove(&window, QPoint(122,122), 50);
+ int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+
+ // move the minimum distance to activate drag
+ p += QPoint(dragThreshold + 1, dragThreshold + 1);
+ QTest::mouseMove(&window, p);
+ QVERIFY(!drag->active());
+
+ // from here on move the item
+ p += QPoint(1, 1);
+ QTest::mouseMove(&window, p);
+ QTRY_VERIFY(drag->active());
+ // on macOS the cursor movement is going through a native event which
+ // means that it can actually take some time to show
+ QTRY_COMPARE(blackRect->x(), 50.0 + 1);
+ QCOMPARE(blackRect->y(), 50.0 + 1);
+
+ p += QPoint(10, 10);
+ QTest::mouseMove(&window, p);
QTRY_VERIFY(drag->active());
QTRY_COMPARE(blackRect->x(), 61.0);
QCOMPARE(blackRect->y(), 61.0);
- QTest::mouseRelease(&window, button, 0, QPoint(122,122));
-
+ QTest::mouseRelease(&window, button, 0, p);
QTRY_VERIFY(!drag->active());
- QCOMPARE(blackRect->x(), 61.0);
+ QTRY_COMPARE(blackRect->x(), 61.0);
QCOMPARE(blackRect->y(), 61.0);
}
@@ -532,15 +553,18 @@ void tst_QQuickMouseArea::cancelDragging()
QVERIFY(!drag->active());
- QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QPoint p = QPoint(100,100);
+ QTest::mousePress(&window, Qt::LeftButton, 0, p);
QVERIFY(!drag->active());
QCOMPARE(blackRect->x(), 50.0);
QCOMPARE(blackRect->y(), 50.0);
- QTest::mouseMove(&window, QPoint(111,111), 50);
- QTest::mouseMove(&window, QPoint(116,116), 50);
- QTest::mouseMove(&window, QPoint(122,122), 50);
+ p += QPoint(startDragDistance() + 1, 0);
+ QTest::mouseMove(&window, p);
+
+ p += QPoint(11, 11);
+ QTest::mouseMove(&window, p);
QTRY_VERIFY(drag->active());
QTRY_COMPARE(blackRect->x(), 61.0);
@@ -575,7 +599,8 @@ void tst_QQuickMouseArea::setDragOnPressed()
QQuickItem *target = mouseArea->findChild<QQuickItem*>("target");
QVERIFY(target);
- QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QPoint p = QPoint(100, 100);
+ QTest::mousePress(&window, Qt::LeftButton, 0, p);
QQuickDrag *drag = mouseArea->drag();
QVERIFY(drag);
@@ -587,19 +612,17 @@ void tst_QQuickMouseArea::setDragOnPressed()
// First move event triggers drag, second is acted upon.
// This is due to possibility of higher stacked area taking precedence.
- QTest::mouseMove(&window, QPoint(111,102));
- QTest::qWait(50);
- QTest::mouseMove(&window, QPoint(122,122));
- QTest::qWait(50);
+ p += QPoint(startDragDistance() + 1, 0);
+ QTest::mouseMove(&window, p);
- QVERIFY(drag->active());
- QCOMPARE(target->x(), 61.0);
+ p += QPoint(11, 0);
+ QTest::mouseMove(&window, p);
+ QTRY_VERIFY(drag->active());
+ QTRY_COMPARE(target->x(), 61.0);
QCOMPARE(target->y(), 50.0);
- QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(122,122));
- QTest::qWait(50);
-
- QVERIFY(!drag->active());
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, p);
+ QTRY_VERIFY(!drag->active());
QCOMPARE(target->x(), 61.0);
QCOMPARE(target->y(), 50.0);
}
@@ -748,7 +771,7 @@ void tst_QQuickMouseArea::onMousePressRejected()
QVERIFY(!window.rootObject()->property("mr1_canceled").toBool());
QVERIFY(window.rootObject()->property("mr2_pressed").toBool());
QVERIFY(!window.rootObject()->property("mr2_released").toBool());
- QVERIFY(window.rootObject()->property("mr2_canceled").toBool());
+ QVERIFY(!window.rootObject()->property("mr2_canceled").toBool());
QTest::qWait(200);
@@ -792,14 +815,14 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
QGuiApplication::sendEvent(&window, &pressEvent);
- QVERIFY(window.rootObject()->property("pressed").toBool());
+ QTRY_VERIFY(window.rootObject()->property("pressed").toBool());
QVERIFY(!window.rootObject()->property("canceled").toBool());
QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
if (doubleClick) {
QGuiApplication::sendEvent(&window, &releaseEvent);
- QVERIFY(!window.rootObject()->property("pressed").toBool());
+ QTRY_VERIFY(!window.rootObject()->property("pressed").toBool());
QVERIFY(!window.rootObject()->property("canceled").toBool());
QCOMPARE(window.rootObject()->property("released").toInt(), ++expectedRelease);
QCOMPARE(window.rootObject()->property("clicked").toInt(), ++expectedClicks);
@@ -808,7 +831,7 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
QMouseEvent pressEvent2(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
QGuiApplication::sendEvent(&window, &pressEvent2);
- QVERIFY(window.rootObject()->property("pressed").toBool());
+ QTRY_VERIFY(window.rootObject()->property("pressed").toBool());
QVERIFY(!window.rootObject()->property("canceled").toBool());
QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
@@ -820,23 +843,21 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
secondWindow->setProperty("visible", true);
QTest::qWaitForWindowExposed(secondWindow);
- QVERIFY(!window.rootObject()->property("pressed").toBool());
+ QTRY_VERIFY(!window.rootObject()->property("pressed").toBool());
QVERIFY(window.rootObject()->property("canceled").toBool());
QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
//press again
QGuiApplication::sendEvent(&window, &pressEvent);
- QVERIFY(window.rootObject()->property("pressed").toBool());
+ QTRY_VERIFY(window.rootObject()->property("pressed").toBool());
QVERIFY(!window.rootObject()->property("canceled").toBool());
QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
- QTest::qWait(200);
-
//release
QGuiApplication::sendEvent(&window, &releaseEvent);
- QVERIFY(!window.rootObject()->property("pressed").toBool());
+ QTRY_VERIFY(!window.rootObject()->property("pressed").toBool());
QVERIFY(!window.rootObject()->property("canceled").toBool());
QCOMPARE(window.rootObject()->property("released").toInt(), ++expectedRelease);
QCOMPARE(window.rootObject()->property("clicked").toInt(), ++expectedClicks);
@@ -994,48 +1015,60 @@ void tst_QQuickMouseArea::preventStealing()
QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
- QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80));
+ QPoint p = QPoint(80, 80);
+ QTest::mousePress(&window, Qt::LeftButton, 0, p);
// Without preventStealing, mouse movement over MouseArea would
// cause the Flickable to steal mouse and trigger content movement.
- QTest::mouseMove(&window,QPoint(69,69));
- QTest::mouseMove(&window,QPoint(58,58));
- QTest::mouseMove(&window,QPoint(47,47));
+ p += QPoint(-startDragDistance() * 2, -startDragDistance() * 2);
+ QTest::mouseMove(&window, p);
+ p += QPoint(-10, -10);
+ QTest::mouseMove(&window, p);
+ p += QPoint(-10, -10);
+ QTest::mouseMove(&window, p);
+ p += QPoint(-10, -10);
+ QTest::mouseMove(&window, p);
- // We should have received all three move events
- QCOMPARE(mousePositionSpy.count(), 3);
+ // We should have received all four move events
+ QTRY_COMPARE(mousePositionSpy.count(), 4);
+ mousePositionSpy.clear();
QVERIFY(mouseArea->pressed());
// Flickable content should not have moved.
QCOMPARE(flickable->contentX(), 0.);
QCOMPARE(flickable->contentY(), 0.);
- QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(47, 47));
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, p);
// Now allow stealing and confirm Flickable does its thing.
window.rootObject()->setProperty("stealing", false);
- QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80));
+ p = QPoint(80, 80);
+ QTest::mousePress(&window, Qt::LeftButton, 0, p);
// Without preventStealing, mouse movement over MouseArea would
// cause the Flickable to steal mouse and trigger content movement.
- QTest::mouseMove(&window,QPoint(69,69));
- QTest::mouseMove(&window,QPoint(58,58));
- QTest::mouseMove(&window,QPoint(47,47));
+ p += QPoint(-startDragDistance() * 2, -startDragDistance() * 2);
+ QTest::mouseMove(&window, p);
+ p += QPoint(-10, -10);
+ QTest::mouseMove(&window, p);
+ p += QPoint(-10, -10);
+ QTest::mouseMove(&window, p);
+ p += QPoint(-10, -10);
+ QTest::mouseMove(&window, p);
// We should only have received the first move event
- QCOMPARE(mousePositionSpy.count(), 4);
+ QTRY_COMPARE(mousePositionSpy.count(), 1);
// Our press should be taken away
QVERIFY(!mouseArea->pressed());
- // Flickable content should have moved.
-
- QCOMPARE(flickable->contentX(), 11.);
- QCOMPARE(flickable->contentY(), 11.);
+ // Flickable swallows the first move, then moves 2*10 px
+ QTRY_COMPARE(flickable->contentX(), 20.);
+ QCOMPARE(flickable->contentY(), 20.);
- QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(50, 50));
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, p);
}
void tst_QQuickMouseArea::clickThrough()
@@ -1280,6 +1313,26 @@ void tst_QQuickMouseArea::hoverAfterPress()
QCOMPARE(mouseArea->hovered(), false);
}
+void tst_QQuickMouseArea::subtreeHoverEnabled()
+{
+ QQuickView window;
+ QByteArray errorMessage;
+ QVERIFY2(initView(window, testFileUrl("qtbug54019.qml"), true, &errorMessage), errorMessage.constData());
+ QQuickItem *root = window.rootObject();
+ QVERIFY(root != 0);
+
+ QQuickMouseArea *mouseArea = root->findChild<QQuickMouseArea*>();
+ QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root);
+ QVERIFY(mouseArea != 0);
+ QTest::mouseMove(&window, QPoint(10, 160));
+ QCOMPARE(mouseArea->hovered(), false);
+ QVERIFY(rootPrivate->subtreeHoverEnabled);
+ QTest::mouseMove(&window, QPoint(10, 10));
+ QCOMPARE(mouseArea->hovered(), true);
+ QTest::mouseMove(&window, QPoint(160, 10));
+ QCOMPARE(mouseArea->hovered(), false);
+}
+
void tst_QQuickMouseArea::disableAfterPress()
{
QQuickView window;
@@ -1304,9 +1357,8 @@ void tst_QQuickMouseArea::disableAfterPress()
QCOMPARE(blackRect, drag->target());
QVERIFY(!drag->active());
-
- QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
-
+ QPoint p = QPoint(100,100);
+ QTest::mousePress(&window, Qt::LeftButton, 0, p);
QTRY_COMPARE(mousePressSpy.count(), 1);
QVERIFY(!drag->active());
@@ -1316,22 +1368,24 @@ void tst_QQuickMouseArea::disableAfterPress()
// First move event triggers drag, second is acted upon.
// This is due to possibility of higher stacked area taking precedence.
- QTest::mouseMove(&window, QPoint(111,111));
- QTest::qWait(50);
- QTest::mouseMove(&window, QPoint(122,122));
+ p += QPoint(startDragDistance() + 1, 0);
+ QTest::mouseMove(&window, p);
+ p += QPoint(11, 11);
+ QTest::mouseMove(&window, p);
QTRY_COMPARE(mousePositionSpy.count(), 2);
- QVERIFY(drag->active());
- QCOMPARE(blackRect->x(), 61.0);
+ QTRY_VERIFY(drag->active());
+ QTRY_COMPARE(blackRect->x(), 61.0);
QCOMPARE(blackRect->y(), 61.0);
mouseArea->setEnabled(false);
// move should still be acted upon
- QTest::mouseMove(&window, QPoint(133,133));
- QTest::qWait(50);
- QTest::mouseMove(&window, QPoint(144,144));
+ p += QPoint(11, 11);
+ QTest::mouseMove(&window, p);
+ p += QPoint(11, 11);
+ QTest::mouseMove(&window, p);
QTRY_COMPARE(mousePositionSpy.count(), 4);
@@ -1342,7 +1396,7 @@ void tst_QQuickMouseArea::disableAfterPress()
QVERIFY(mouseArea->pressed());
QVERIFY(mouseArea->hovered());
- QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(144,144));
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, p);
QTRY_COMPARE(mouseReleaseSpy.count(), 1);
@@ -1599,36 +1653,39 @@ void tst_QQuickMouseArea::changeAxis()
QVERIFY(!drag->active());
// Start a diagonal drag
- QTest::mousePress(&view, Qt::LeftButton, 0, QPoint(100, 100));
+ QPoint p = QPoint(100, 100);
+ QTest::mousePress(&view, Qt::LeftButton, 0, p);
QVERIFY(!drag->active());
QCOMPARE(blackRect->x(), 50.0);
QCOMPARE(blackRect->y(), 50.0);
- QTest::mouseMove(&view, QPoint(111, 111));
- QTest::qWait(50);
- QTest::mouseMove(&view, QPoint(122, 122));
-
+ p += QPoint(startDragDistance() + 1, startDragDistance() + 1);
+ QTest::mouseMove(&view, p);
+ p += QPoint(11, 11);
+ QTest::mouseMove(&view, p);
QTRY_VERIFY(drag->active());
- QCOMPARE(blackRect->x(), 61.0);
+ QTRY_COMPARE(blackRect->x(), 61.0);
QCOMPARE(blackRect->y(), 61.0);
QCOMPARE(drag->axis(), QQuickDrag::XAndYAxis);
/* When blackRect.x becomes bigger than 75, the drag axis is changed to
* Drag.YAxis by the QML code. Verify that this happens, and that the drag
* movement is effectively constrained to the Y axis. */
- QTest::mouseMove(&view, QPoint(144, 144));
+ p += QPoint(22, 22);
+ QTest::mouseMove(&view, p);
QTRY_COMPARE(blackRect->x(), 83.0);
QTRY_COMPARE(blackRect->y(), 83.0);
QTRY_COMPARE(drag->axis(), QQuickDrag::YAxis);
- QTest::mouseMove(&view, QPoint(155, 155));
+ p += QPoint(11, 11);
+ QTest::mouseMove(&view, p);
QTRY_COMPARE(blackRect->y(), 94.0);
QCOMPARE(blackRect->x(), 83.0);
- QTest::mouseRelease(&view, Qt::LeftButton, 0, QPoint(155, 155));
+ QTest::mouseRelease(&view, Qt::LeftButton, 0, p);
QTRY_VERIFY(!drag->active());
QCOMPARE(blackRect->x(), 83.0);
@@ -1678,11 +1735,17 @@ void tst_QQuickMouseArea::moveAndReleaseWithoutPress()
QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ // the press was not accepted, make sure there is no move or release event
QTest::mouseMove(&window, QPoint(110,110), 50);
- QTRY_COMPARE(root->property("hadMove").toBool(), false);
+
+ // use qwait here because we want to make sure an event does NOT happen
+ // the test fails if the default state changes, while it shouldn't
+ QTest::qWait(100);
+ QCOMPARE(root->property("hadMove").toBool(), false);
QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(110,110));
- QTRY_COMPARE(root->property("hadRelease").toBool(), false);
+ QTest::qWait(100);
+ QCOMPARE(root->property("hadRelease").toBool(), false);
}
void tst_QQuickMouseArea::nestedStopAtBounds_data()
@@ -1926,33 +1989,43 @@ void tst_QQuickMouseArea::ignoreBySource()
QVERIFY(flickable);
// MouseArea should grab the press because it's interested in non-synthesized mouse events
- QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80));
- QVERIFY(window.mouseGrabberItem() == mouseArea);
+ QPoint p = QPoint(80, 80);
+ QTest::mousePress(&window, Qt::LeftButton, 0, p);
+ QCOMPARE(window.mouseGrabberItem(), mouseArea);
// That was a real mouse event
- QVERIFY(root->property("lastEventSource").toInt() == Qt::MouseEventNotSynthesized);
+ QCOMPARE(root->property("lastEventSource").toInt(), int(Qt::MouseEventNotSynthesized));
// Flickable content should not move
- QTest::mouseMove(&window,QPoint(69,69));
- QTest::mouseMove(&window,QPoint(58,58));
- QTest::mouseMove(&window,QPoint(47,47));
+ p -= QPoint(startDragDistance() + 1, startDragDistance() + 1);
+ QTest::mouseMove(&window, p);
+ p -= QPoint(11, 11);
+ QTest::mouseMove(&window, p);
+ p -= QPoint(11, 11);
+ QTest::mouseMove(&window, p);
QCOMPARE(flickable->contentX(), 0.);
QCOMPARE(flickable->contentY(), 0.);
- QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(47, 47));
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, p);
+ QCOMPARE(window.mouseGrabberItem(), nullptr);
// Now try touch events and confirm that MouseArea ignores them, while Flickable does its thing
-
- QTest::touchEvent(&window, device).press(0, QPoint(80, 80), &window);
+ p = QPoint(80, 80);
+ QTest::touchEvent(&window, device).press(0, p, &window);
QQuickTouchUtils::flush(&window);
- QVERIFY(window.mouseGrabberItem() != mouseArea);
+ QCOMPARE(window.mouseGrabberItem(), flickable);
+
// That was a fake mouse event
QCOMPARE(root->property("lastEventSource").toInt(), int(Qt::MouseEventSynthesizedByQt));
- QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window);
- QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window);
- QTest::touchEvent(&window, device).move(0, QPoint(47,47), &window);
+ p -= QPoint(startDragDistance() + 1, startDragDistance() + 1);
+ QTest::touchEvent(&window, device).move(0, p, &window);
+ p -= QPoint(11, 11);
+ QTest::touchEvent(&window, device).move(0, p, &window);
+ p -= QPoint(11, 11);
+ QTest::touchEvent(&window, device).move(0, p, &window);
+
QQuickTouchUtils::flush(&window);
QCOMPARE(window.mouseGrabberItem(), flickable);
- QTest::touchEvent(&window, device).release(0, QPoint(47,47), &window);
+ QTest::touchEvent(&window, device).release(0, p, &window);
QQuickTouchUtils::flush(&window);
// Flickable content should have moved
@@ -1967,15 +2040,19 @@ void tst_QQuickMouseArea::ignoreBySource()
// MouseArea should ignore the press because it's interested in synthesized mouse events
- QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80));
+ p = QPoint(80, 80);
+ QTest::mousePress(&window, Qt::LeftButton, 0, p);
QVERIFY(window.mouseGrabberItem() != mouseArea);
// That was a real mouse event
QVERIFY(root->property("lastEventSource").toInt() == Qt::MouseEventNotSynthesized);
// Flickable content should move
- QTest::mouseMove(&window,QPoint(69,69));
- QTest::mouseMove(&window,QPoint(58,58));
- QTest::mouseMove(&window,QPoint(47,47));
+ p -= QPoint(startDragDistance() + 1, startDragDistance() + 1);
+ QTest::mouseMove(&window, p);
+ p -= QPoint(11, 11);
+ QTest::mouseMove(&window, p);
+ p -= QPoint(11, 11);
+ QTest::mouseMove(&window, p);
QTRY_VERIFY(flickable->contentX() > 1);
QVERIFY(flickable->contentY() > 1);
@@ -1984,13 +2061,16 @@ void tst_QQuickMouseArea::ignoreBySource()
flickable->setContentY(0);
// Now try touch events and confirm that MouseArea gets them, while Flickable doesn't
-
- QTest::touchEvent(&window, device).press(0, QPoint(80, 80), &window);
+ p = QPoint(80, 80);
+ QTest::touchEvent(&window, device).press(0, p, &window);
QQuickTouchUtils::flush(&window);
QCOMPARE(window.mouseGrabberItem(), mouseArea);
- QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window);
- QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window);
- QTest::touchEvent(&window, device).move(0, QPoint(47,47), &window);
+ p -= QPoint(startDragDistance() + 1, startDragDistance() + 1);
+ QTest::touchEvent(&window, device).move(0, p, &window);
+ p -= QPoint(11, 11);
+ QTest::touchEvent(&window, device).move(0, p, &window);
+ p -= QPoint(11, 11);
+ QTest::touchEvent(&window, device).move(0, p, &window);
QQuickTouchUtils::flush(&window);
QCOMPARE(window.mouseGrabberItem(), mouseArea);
QTest::touchEvent(&window, device).release(0, QPoint(47,47), &window);
@@ -2001,6 +2081,23 @@ void tst_QQuickMouseArea::ignoreBySource()
QCOMPARE(flickable->contentY(), 0.);
}
+void tst_QQuickMouseArea::notPressedAfterStolenGrab()
+{
+ QQuickWindow window;
+ window.resize(200, 200);
+ window.show();
+ QTest::qWaitForWindowExposed(&window);
+
+ QQuickMouseArea *ma = new QQuickMouseArea(window.contentItem());
+ ma->setSize(window.size());
+ QObject::connect(ma,
+ static_cast<void (QQuickMouseArea::*)(QQuickMouseEvent*)>(&QQuickMouseArea::pressed),
+ [&]() { window.contentItem()->grabMouse(); });
+
+ QTest::mouseClick(&window, Qt::LeftButton);
+ QVERIFY(!ma->pressed());
+}
+
QTEST_MAIN(tst_QQuickMouseArea)
#include "tst_qquickmousearea.moc"
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index c3981c466f..2872556a94 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -915,13 +915,13 @@ 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);
+ QTest::touchEvent(window.data(), device).move(1, touch1).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());
QCOMPARE(touch2rect->property("y").toInt(), touch2.y());
- QTest::touchEvent(window.data(), device).release(1, touch1);
+ QTest::touchEvent(window.data(), device).release(1, touch1).move(2, touch2);
touch1.setY(20);
QTest::mousePress(window.data(), Qt::LeftButton, 0, touch1);
QQuickTouchUtils::flush(window.data());
diff --git a/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp b/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp
index 1a04526f61..44d7b40ed9 100644
--- a/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp
+++ b/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp
@@ -32,8 +32,11 @@
#include <QtQuick/qquickview.h>
#include <private/qquickitem_p.h>
+#ifndef QT_NO_OPENGL
#include <private/qsgdefaultpainternode_p.h>
-
+#else
+#include <private/qsgsoftwarepainternode_p.h>
+#endif
class tst_QQuickPaintedItem: public QObject
{
Q_OBJECT
@@ -70,7 +73,7 @@ public:
++paintRequests;
clipRect = painter->clipBoundingRect();
}
-
+#ifndef QT_NO_OPENGL
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
{
paintNode = static_cast<QSGDefaultPainterNode *>(QQuickPaintedItem::updatePaintNode(oldNode, data));
@@ -78,6 +81,15 @@ public:
}
QSGDefaultPainterNode *paintNode;
+#else
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+ {
+ paintNode = static_cast<QSGSoftwarePainterNode *>(QQuickPaintedItem::updatePaintNode(oldNode, data));
+ return paintNode;
+ }
+
+ QSGSoftwarePainterNode *paintNode;
+#endif
int paintRequests;
QRectF clipRect;
};
diff --git a/tests/auto/quick/qquickpincharea/data/pinchproperties.qml b/tests/auto/quick/qquickpincharea/data/pinchproperties.qml
index 37d706fc8e..c5daf6cbfe 100644
--- a/tests/auto/quick/qquickpincharea/data/pinchproperties.qml
+++ b/tests/auto/quick/qquickpincharea/data/pinchproperties.qml
@@ -2,7 +2,7 @@ import QtQuick 2.0
Rectangle {
id: whiteRect
property variant center
- property real scale
+ property real scale: -1.0
property int pointCount: 0
property bool pinchActive: false
width: 240; height: 320
diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
index aee35b4b90..c1a51fd659 100644
--- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
+++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
@@ -286,6 +286,7 @@ void tst_QQuickPinchArea::pan()
QPoint p1(80, 80);
QPoint p2(100, 100);
{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
pinchSequence.press(0, p1, window).commit();
QQuickTouchUtils::flush(window);
@@ -293,23 +294,63 @@ void tst_QQuickPinchArea::pan()
// 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();
+ QVERIFY(!root->property("pinchActive").toBool());
+ QCOMPARE(root->property("scale").toReal(), -1.0);
+
+ p1 += QPoint(dragThreshold - 1, 0);
+ p2 += QPoint(dragThreshold - 1, 0);
+ pinchSequence.move(0, p1, window).move(1, p2, window).commit();
QQuickTouchUtils::flush(window);
+ // movement < dragThreshold: pinch not yet active
+ QVERIFY(!root->property("pinchActive").toBool());
+ QCOMPARE(root->property("scale").toReal(), -1.0);
- QCOMPARE(root->property("scale").toReal(), 1.0);
+ // exactly the dragThreshold: pinch starts
+ p1 += QPoint(1, 0);
+ p2 += QPoint(1, 0);
+ pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
QVERIFY(root->property("pinchActive").toBool());
+ QCOMPARE(root->property("scale").toReal(), 1.0);
- p1 += QPoint(10,10);
- p2 += QPoint(10,10);
- pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+ // Calculation of the center point is tricky at first:
+ // center point of the two touch points in item coordinates:
+ // scene coordinates: (80, 80) + (dragThreshold, 0), (100, 100) + (dragThreshold, 0)
+ // = ((180+dT)/2, 180/2) = (90+dT, 90)
+ // item coordinates: (scene) - (50, 50) = (40+dT, 40)
+ QCOMPARE(root->property("center").toPointF(), QPointF(40 + dragThreshold, 40));
+ // pan started, but no actual movement registered yet:
+ // blackrect starts at 50,50
+ QCOMPARE(blackRect->x(), 50.0);
+ QCOMPARE(blackRect->y(), 50.0);
+
+ p1 += QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, window).move(1, p2, window).commit();
QQuickTouchUtils::flush(window);
- }
+ QCOMPARE(root->property("center").toPointF(), QPointF(40 + 10 + dragThreshold, 40));
+ QCOMPARE(blackRect->x(), 60.0);
+ QCOMPARE(blackRect->y(), 50.0);
- QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50
- QCOMPARE(blackRect->x(), 60.0);
- QCOMPARE(blackRect->y(), 60.0);
+ p1 += QPoint(0, 10);
+ p2 += QPoint(0, 10);
+ pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
+ // next big surprise: the center is in item local coordinates and the item was just
+ // moved 10 to the right... which offsets the center point 10 to the left
+ QCOMPARE(root->property("center").toPointF(), QPointF(40 + 10 - 10 + dragThreshold, 40 + 10));
+ QCOMPARE(blackRect->x(), 60.0);
+ QCOMPARE(blackRect->y(), 60.0);
+
+ p1 += QPoint(10, 10);
+ p2 += QPoint(10, 10);
+ pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ QQuickTouchUtils::flush(window);
+ // now the item moved again, thus the center point of the touch is moved in total by (10, 10)
+ QCOMPARE(root->property("center").toPointF(), QPointF(50 + dragThreshold, 50));
+ QCOMPARE(blackRect->x(), 70.0);
+ QCOMPARE(blackRect->y(), 70.0);
+ }
// pan x beyond bound
p1 += QPoint(100,100);
@@ -318,7 +359,7 @@ void tst_QQuickPinchArea::pan()
QQuickTouchUtils::flush(window);
QCOMPARE(blackRect->x(), 140.0);
- QCOMPARE(blackRect->y(), 160.0);
+ QCOMPARE(blackRect->y(), 170.0);
QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
QQuickTouchUtils::flush(window);
@@ -470,6 +511,7 @@ void tst_QQuickPinchArea::cancel()
QCOMPARE(blackRect->scale(), 1.5);
QTouchEvent cancelEvent(QEvent::TouchCancel);
+ cancelEvent.setDevice(device);
QCoreApplication::sendEvent(window, &cancelEvent);
QQuickTouchUtils::flush(window);
diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
index 483cdf7a41..fe33dbd4d8 100644
--- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
+++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
@@ -30,16 +30,16 @@
#include <QList>
#include <QByteArray>
-#include <private/qquickshadereffect_p.h>
-
+#include <private/qquickopenglshadereffect_p.h>
+#include <QMatrix4x4>
#include <QtQuick/QQuickView>
+#include <QtQml/QQmlEngine>
#include "../../shared/util.h"
-
class TestShaderEffect : public QQuickShaderEffect
{
Q_OBJECT
- Q_PROPERTY(QVariant source READ dummyRead NOTIFY dummyChanged)
+ Q_PROPERTY(QVariant source READ dummyRead NOTIFY sourceChanged)
Q_PROPERTY(QVariant _0aA9zZ READ dummyRead NOTIFY dummyChanged)
Q_PROPERTY(QVariant x86 READ dummyRead NOTIFY dummyChanged)
Q_PROPERTY(QVariant X READ dummyRead NOTIFY dummyChanged)
@@ -48,17 +48,18 @@ class TestShaderEffect : public QQuickShaderEffect
public:
QMatrix4x4 mat4x4Read() const { return QMatrix4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1); }
QVariant dummyRead() const { return QVariant(); }
- bool isConnected(const QMetaMethod &signal) const { return m_signals.contains(signal); }
+
+ int signalsConnected = 0;
protected:
- void connectNotify(const QMetaMethod &signal) { m_signals.append(signal); }
- void disconnectNotify(const QMetaMethod &signal) { m_signals.removeOne(signal); }
+ void connectNotify(const QMetaMethod &) { ++signalsConnected; }
+ void disconnectNotify(const QMetaMethod &) { --signalsConnected; }
signals:
void dummyChanged();
+ void sourceChanged();
private:
- QList<QMetaMethod> m_signals;
};
class tst_qquickshadereffect : public QQmlDataTest
@@ -84,12 +85,13 @@ private:
TexCoordPresent = 0x02,
MatrixPresent = 0x04,
OpacityPresent = 0x08,
- PropertyPresent = 0x10
+ SourcePresent = 0x10
};
};
tst_qquickshadereffect::tst_qquickshadereffect()
{
+ qmlRegisterType<TestShaderEffect>("ShaderEffectTest", 1, 0, "TestShaderEffect");
}
void tst_qquickshadereffect::initTestCase()
@@ -122,7 +124,7 @@ void tst_qquickshadereffect::lookThroughShaderCode_data()
"void main() { \n"
" gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; \n"
"}")
- << (VertexPresent | TexCoordPresent | MatrixPresent | OpacityPresent | PropertyPresent);
+ << (VertexPresent | TexCoordPresent | MatrixPresent | OpacityPresent | SourcePresent);
QTest::newRow("empty")
<< QByteArray(" ") // one space -- if completely empty, default will be used instead.
@@ -135,14 +137,14 @@ void tst_qquickshadereffect::lookThroughShaderCode_data()
"attribute highp vec4 qt_Vertex;\n"
"// attribute highp vec2 qt_MultiTexCoord0;")
<< QByteArray("uniform int source; // uniform lowp float qt_Opacity;")
- << (VertexPresent | PropertyPresent);
+ << (VertexPresent | SourcePresent);
QTest::newRow("inside block comments")
<< QByteArray("/*uniform highp mat4 qt_Matrix;\n"
"*/attribute highp vec4 qt_Vertex;\n"
"/*/attribute highp vec2 qt_MultiTexCoord0;//**/")
<< QByteArray("/**/uniform int source; /* uniform lowp float qt_Opacity; */")
- << (VertexPresent | PropertyPresent);
+ << (VertexPresent | SourcePresent);
QTest::newRow("inside preprocessor directive")
<< QByteArray("#define uniform\nhighp mat4 qt_Matrix;\n"
@@ -150,7 +152,7 @@ void tst_qquickshadereffect::lookThroughShaderCode_data()
"#if\\\nattribute highp vec2 qt_MultiTexCoord0;")
<< QByteArray("uniform int source;\n"
" # undef uniform lowp float qt_Opacity;")
- << (VertexPresent | PropertyPresent);
+ << (VertexPresent | SourcePresent);
QTest::newRow("line comments between")
@@ -158,21 +160,21 @@ void tst_qquickshadereffect::lookThroughShaderCode_data()
"attribute//\nhighp//\nvec4//\nqt_Vertex;\n"
" //*/ uniform \n attribute //\\ \n highp //// \n vec2 //* \n qt_MultiTexCoord0;")
<< QByteArray("uniform// lowp float qt_Opacity;\nsampler2D source;")
- << (VertexPresent | TexCoordPresent | MatrixPresent | PropertyPresent);
+ << (VertexPresent | TexCoordPresent | MatrixPresent | SourcePresent);
QTest::newRow("block comments between")
<< QByteArray("uniform/*foo*/highp/*/bar/*/mat4/**//**/qt_Matrix;\n"
"attribute/**/highp/**/vec4/**/qt_Vertex;\n"
" /* * */ attribute /*///*/ highp /****/ vec2 /**/ qt_MultiTexCoord0;")
<< QByteArray("uniform/*/ uniform//lowp/*float qt_Opacity;*/sampler2D source;")
- << (VertexPresent | TexCoordPresent | MatrixPresent | PropertyPresent);
+ << (VertexPresent | TexCoordPresent | MatrixPresent | SourcePresent);
QTest::newRow("preprocessor directive between")
<< QByteArray("uniform\n#foo\nhighp\n#bar\nmat4\n#baz\\\nblimey\nqt_Matrix;\n"
"attribute\n#\nhighp\n#\nvec4\n#\nqt_Vertex;\n"
" #uniform \n attribute \n # foo \n highp \n # bar \n vec2 \n#baz \n qt_MultiTexCoord0;")
<< QByteArray("uniform\n#if lowp float qt_Opacity;\nsampler2D source;")
- << (VertexPresent | TexCoordPresent | MatrixPresent | PropertyPresent);
+ << (VertexPresent | TexCoordPresent | MatrixPresent | SourcePresent);
QTest::newRow("newline between")
<< QByteArray("uniform\nhighp\nmat4\nqt_Matrix\n;\n"
@@ -180,7 +182,7 @@ void tst_qquickshadereffect::lookThroughShaderCode_data()
" \n attribute \n highp \n vec2 \n qt_Multi\nTexCoord0 \n ;")
<< QByteArray("uniform\nsampler2D\nsource;"
"uniform lowp float qt_Opacity;")
- << (VertexPresent | MatrixPresent | OpacityPresent | PropertyPresent);
+ << (VertexPresent | MatrixPresent | OpacityPresent | SourcePresent);
QTest::newRow("extra characters #1")
@@ -221,28 +223,28 @@ void tst_qquickshadereffect::lookThroughShaderCode_data()
"attribute highp qt_MultiTexCoord0;\n")
<< QByteArray("uniform lowp float qt_Opacity;\n"
"uniform mediump float source;\n")
- << (MatrixPresent | OpacityPresent | PropertyPresent);
+ << (MatrixPresent | OpacityPresent | SourcePresent);
QTest::newRow("property name #1")
<< QByteArray("uniform highp vec3 _0aA9zZ;")
<< QByteArray(" ")
- << int(PropertyPresent);
+ << int(SourcePresent);
QTest::newRow("property name #2")
<< QByteArray("uniform mediump vec2 x86;")
<< QByteArray(" ")
- << int(PropertyPresent);
+ << int(SourcePresent);
QTest::newRow("property name #3")
<< QByteArray("uniform lowp float X;")
<< QByteArray(" ")
- << int(PropertyPresent);
+ << int(SourcePresent);
QTest::newRow("property name #4")
<< QByteArray("uniform highp mat4 mat4x4;")
<< QByteArray(" ")
- << int(PropertyPresent);
+ << int(SourcePresent);
}
void tst_qquickshadereffect::lookThroughShaderCode()
@@ -251,9 +253,11 @@ void tst_qquickshadereffect::lookThroughShaderCode()
QFETCH(QByteArray, fragmentShader);
QFETCH(int, presenceFlags);
- TestShaderEffect item;
- QMetaMethod dummyChangedSignal = QMetaMethod::fromSignal(&TestShaderEffect::dummyChanged);
- QVERIFY(!item.isConnected(dummyChangedSignal)); // Nothing connected yet.
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nimport ShaderEffectTest 1.0\nTestShaderEffect {}", QUrl());
+ QScopedPointer<TestShaderEffect> item(qobject_cast<TestShaderEffect*>(component.create()));
+ QCOMPARE(item->signalsConnected, 1);
QString expected;
if ((presenceFlags & VertexPresent) == 0)
@@ -265,12 +269,12 @@ void tst_qquickshadereffect::lookThroughShaderCode()
if ((presenceFlags & OpacityPresent) == 0)
expected += "Warning: Shaders are missing reference to \'qt_Opacity\'.\n";
- item.setVertexShader(vertexShader);
- item.setFragmentShader(fragmentShader);
- QCOMPARE(item.parseLog(), expected);
+ item->setVertexShader(vertexShader);
+ item->setFragmentShader(fragmentShader);
+ QCOMPARE(item->parseLog(), expected);
// If the uniform was successfully parsed, the notify signal has been connected to an update slot.
- QCOMPARE(item.isConnected(dummyChangedSignal), (presenceFlags & PropertyPresent) != 0);
+ QCOMPARE(item->signalsConnected, (presenceFlags & SourcePresent) ? 2 : 1);
}
void tst_qquickshadereffect::deleteSourceItem()
diff --git a/tests/auto/quick/qquicktext/BLACKLIST b/tests/auto/quick/qquicktext/BLACKLIST
index c2e7ef03c0..531d981159 100644
--- a/tests/auto/quick/qquicktext/BLACKLIST
+++ b/tests/auto/quick/qquicktext/BLACKLIST
@@ -2,3 +2,5 @@
*
[lineLaidOutRelayout]
msvc-2015
+[fontSizeMode]
+opensuse-42.1
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index f31859ee49..2032f72e26 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -147,8 +147,9 @@ private slots:
void padding();
- void zeroWidthAndElidedDoesntRender();
+ void hintingPreference();
+ void zeroWidthAndElidedDoesntRender();
void hAlignWidthDependsOnImplicitWidth_data();
void hAlignWidthDependsOnImplicitWidth();
@@ -4165,6 +4166,33 @@ void tst_qquicktext::padding()
delete root;
}
+void tst_qquicktext::hintingPreference()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferDefaultHinting);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.hintingPreference: Font.PreferNoHinting }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferNoHinting);
+
+ delete textObject;
+ }
+}
+
+
void tst_qquicktext::zeroWidthAndElidedDoesntRender()
{
// Tests QTBUG-34990
diff --git a/tests/auto/quick/qquicktextedit/BLACKLIST b/tests/auto/quick/qquicktextedit/BLACKLIST
deleted file mode 100644
index 5f3208f848..0000000000
--- a/tests/auto/quick/qquicktextedit/BLACKLIST
+++ /dev/null
@@ -1,4 +0,0 @@
-[undo]
-*
-[undo_keypressevents]
-*
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index fa5a0a254d..5d30cc8c94 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -108,6 +108,7 @@ private slots:
void selectionOnFocusOut();
void focusOnPress();
void selection();
+ void overwriteMode();
void isRightToLeft_data();
void isRightToLeft();
void keySelection();
@@ -1468,6 +1469,74 @@ void tst_qquicktextedit::selection()
QVERIFY(textEditObject->selectedText().isNull());
}
+void tst_qquicktextedit::overwriteMode()
+{
+ QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true; }";
+ QQmlComponent textEditComponent(&engine);
+ textEditComponent.setData(componentStr.toLatin1(), QUrl());
+ QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+ QVERIFY(textEdit != 0);
+
+ QSignalSpy spy(textEdit, SIGNAL(overwriteModeChanged(bool)));
+
+ QQuickWindow window;
+ textEdit->setParentItem(window.contentItem());
+ window.show();
+ window.requestActivate();
+ QTest::qWaitForWindowActive(&window);
+
+ QVERIFY(textEdit->hasActiveFocus());
+
+ textEdit->setOverwriteMode(true);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(true, textEdit->overwriteMode());
+ textEdit->setOverwriteMode(false);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(false, textEdit->overwriteMode());
+
+ QVERIFY(!textEdit->overwriteMode());
+ QString insertString = "Some first text";
+ for (int j = 0; j < insertString.length(); j++)
+ QTest::keyClick(&window, insertString.at(j).toLatin1());
+
+ QCOMPARE(textEdit->text(), QString("Some first text"));
+
+ textEdit->setOverwriteMode(true);
+ QCOMPARE(spy.count(), 3);
+ textEdit->setCursorPosition(5);
+
+ insertString = "shiny";
+ for (int j = 0; j < insertString.length(); j++)
+ QTest::keyClick(&window, insertString.at(j).toLatin1());
+ QCOMPARE(textEdit->text(), QString("Some shiny text"));
+
+ textEdit->setCursorPosition(textEdit->text().length());
+ QTest::keyClick(&window, Qt::Key_Enter);
+
+ textEdit->setOverwriteMode(false);
+ QCOMPARE(spy.count(), 4);
+
+ insertString = "Second paragraph";
+
+ for (int j = 0; j < insertString.length(); j++)
+ QTest::keyClick(&window, insertString.at(j).toLatin1());
+ QCOMPARE(textEdit->lineCount(), 2);
+
+ textEdit->setCursorPosition(15);
+
+ QCOMPARE(textEdit->cursorPosition(), 15);
+
+ textEdit->setOverwriteMode(true);
+ QCOMPARE(spy.count(), 5);
+
+ insertString = " blah";
+ for (int j = 0; j < insertString.length(); j++)
+ QTest::keyClick(&window, insertString.at(j).toLatin1());
+ QCOMPARE(textEdit->lineCount(), 2);
+
+ QCOMPARE(textEdit->text(), QString("Some shiny text blah\nSecond paragraph"));
+}
+
void tst_qquicktextedit::isRightToLeft_data()
{
QTest::addColumn<QString>("text");
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index ea88f9dadb..8dc3053d89 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -105,6 +105,7 @@ private slots:
void wrap();
void selection();
void persistentSelection();
+ void overwriteMode();
void isRightToLeft_data();
void isRightToLeft();
void moveCursorSelection_data();
@@ -782,6 +783,48 @@ void tst_qquicktextinput::persistentSelection()
QCOMPARE(input->property("selected").toString(), QLatin1String("ell"));
}
+void tst_qquicktextinput::overwriteMode()
+{
+ QString componentStr = "import QtQuick 2.0\nTextInput { focus: true; }";
+ QQmlComponent textInputComponent(&engine);
+ textInputComponent.setData(componentStr.toLatin1(), QUrl());
+ QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create());
+ QVERIFY(textInput != 0);
+
+ QSignalSpy spy(textInput, SIGNAL(overwriteModeChanged(bool)));
+
+ QQuickWindow window;
+ textInput->setParentItem(window.contentItem());
+ window.show();
+ window.requestActivate();
+ QTest::qWaitForWindowActive(&window);
+
+ QVERIFY(textInput->hasActiveFocus());
+
+ textInput->setOverwriteMode(true);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(true, textInput->overwriteMode());
+ textInput->setOverwriteMode(false);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(false, textInput->overwriteMode());
+
+ QVERIFY(!textInput->overwriteMode());
+ QString insertString = "Some first text";
+ for (int j = 0; j < insertString.length(); j++)
+ QTest::keyClick(&window, insertString.at(j).toLatin1());
+
+ QCOMPARE(textInput->text(), QString("Some first text"));
+
+ textInput->setOverwriteMode(true);
+ QCOMPARE(spy.count(), 3);
+ textInput->setCursorPosition(5);
+
+ insertString = "shiny";
+ for (int j = 0; j < insertString.length(); j++)
+ QTest::keyClick(&window, insertString.at(j).toLatin1());
+ QCOMPARE(textInput->text(), QString("Some shiny text"));
+}
+
void tst_qquicktextinput::isRightToLeft_data()
{
QTest::addColumn<QString>("text");
diff --git a/tests/auto/quick/qquickview/tst_qquickview.cpp b/tests/auto/quick/qquickview/tst_qquickview.cpp
index 05922ae20f..fa9192edb4 100644
--- a/tests/auto/quick/qquickview/tst_qquickview.cpp
+++ b/tests/auto/quick/qquickview/tst_qquickview.cpp
@@ -36,6 +36,30 @@
#include <QtCore/QDebug>
#include <QtQml/qqmlengine.h>
+class SizeChangesListener : public QObject, public QVector<QSize>
+{
+ Q_OBJECT
+public:
+ explicit SizeChangesListener(QQuickItem *item);
+private slots:
+ void onSizeChanged();
+private:
+ QQuickItem *item;
+
+};
+
+SizeChangesListener::SizeChangesListener(QQuickItem *item) :
+ item(item)
+{
+ connect(item, &QQuickItem::widthChanged, this, &SizeChangesListener::onSizeChanged);
+ connect(item, &QQuickItem::heightChanged, this, &SizeChangesListener::onSizeChanged);
+}
+
+void SizeChangesListener::onSizeChanged()
+{
+ append(QSize(item->width(), item->height()));
+}
+
class tst_QQuickView : public QQmlDataTest
{
Q_OBJECT
@@ -127,7 +151,6 @@ void tst_QQuickView::resizemodeitem()
QCOMPARE(item->width(), 80.0);
QCOMPARE(item->height(), 100.0);
QTRY_COMPARE(view->size(), QSize(80, 100));
- QCOMPARE(view->size(), QSize(80, 100));
QCOMPARE(view->size(), view->sizeHint());
// size update from root object disabled
@@ -139,8 +162,16 @@ void tst_QQuickView::resizemodeitem()
QCOMPARE(QSize(item->width(), item->height()), view->sizeHint());
// size update from view
+ QCoreApplication::processEvents(); // make sure the last resize events are gone
+ SizeChangesListener sizeListener(item);
view->resize(QSize(200,300));
QTRY_COMPARE(item->width(), 200.0);
+
+ for (int i = 0; i < sizeListener.count(); ++i) {
+ // Check that we have the correct geometry on all signals
+ QCOMPARE(sizeListener.at(i), view->size());
+ }
+
QCOMPARE(item->height(), 300.0);
QCOMPARE(view->size(), QSize(200, 300));
QCOMPARE(view->size(), view->sizeHint());
diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro
index f0d287f30f..05093ba8e0 100644
--- a/tests/auto/quick/qquickwindow/qquickwindow.pro
+++ b/tests/auto/quick/qquickwindow/qquickwindow.pro
@@ -7,7 +7,7 @@ include(../shared/util.pri)
macx:CONFIG -= app_bundle
-QT += core-private gui-private qml-private quick-private testlib
+QT += core-private qml-private quick-private testlib
TESTDATA = data/*
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 1365e8b751..acccac8eca 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -40,10 +40,11 @@
#include "../shared/visualtestutil.h"
#include "../shared/viewtestutil.h"
#include <QSignalSpy>
-#include <qpa/qwindowsysteminterface.h>
#include <private/qquickwindow_p.h>
#include <private/qguiapplication_p.h>
#include <QRunnable>
+#include <QOpenGLFunctions>
+#include <QSGRendererInterface>
struct TouchEventData {
QEvent::Type type;
@@ -156,6 +157,7 @@ public:
lastVelocity = lastVelocityFromMouseMove = QVector2D();
lastMousePos = QPointF();
lastMouseCapabilityFlags = 0;
+ touchEventCount = 0;
}
static void clearMousePressCounter()
@@ -273,25 +275,18 @@ class tst_qquickwindow : public QQmlDataTest
Q_OBJECT
public:
tst_qquickwindow()
+ : touchDevice(QTest::createTouchDevice())
+ , touchDeviceWithVelocity(QTest::createTouchDevice())
{
QQuickWindow::setDefaultAlphaBuffer(true);
+ touchDeviceWithVelocity->setCapabilities(QTouchDevice::Position | QTouchDevice::Velocity);
}
private slots:
- void initTestCase()
- {
- QQmlDataTest::initTestCase();
- touchDevice = new QTouchDevice;
- touchDevice->setType(QTouchDevice::TouchScreen);
- QWindowSystemInterface::registerTouchDevice(touchDevice);
- touchDeviceWithVelocity = new QTouchDevice;
- touchDeviceWithVelocity->setType(QTouchDevice::TouchScreen);
- touchDeviceWithVelocity->setCapabilities(QTouchDevice::Position | QTouchDevice::Velocity);
- QWindowSystemInterface::registerTouchDevice(touchDeviceWithVelocity);
- }
void cleanup();
-
+#ifndef QT_NO_OPENGL
void openglContextCreatedSignal();
+#endif
void aboutToStopSignal();
void constantUpdates();
@@ -308,6 +303,9 @@ private slots:
void touchEvent_reentrant();
void touchEvent_velocity();
+ void mergeTouchPointLists_data();
+ void mergeTouchPointLists();
+
void mouseFromTouch_basic();
void clearWindow();
@@ -368,18 +366,21 @@ private slots:
void testHoverChildMouseEventFilter();
void testHoverTimestamp();
+
+ void pointerEventTypeAndPointCount();
+
private:
QTouchDevice *touchDevice;
QTouchDevice *touchDeviceWithVelocity;
};
-
+#ifndef QT_NO_OPENGL
Q_DECLARE_METATYPE(QOpenGLContext *);
-
+#endif
void tst_qquickwindow::cleanup()
{
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
}
-
+#ifndef QT_NO_OPENGL
void tst_qquickwindow::openglContextCreatedSignal()
{
qRegisterMetaType<QOpenGLContext *>();
@@ -391,12 +392,15 @@ void tst_qquickwindow::openglContextCreatedSignal()
window.show();
QTest::qWaitForWindowExposed(&window);
+ if (window.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
+ QSKIP("Skipping OpenGL context test due to not running with OpenGL");
+
QVERIFY(spy.size() > 0);
QVariant ctx = spy.at(0).at(0);
QCOMPARE(qvariant_cast<QOpenGLContext *>(ctx), window.openglContext());
}
-
+#endif
void tst_qquickwindow::aboutToStopSignal()
{
QQuickWindow window;
@@ -438,8 +442,7 @@ void tst_qquickwindow::constantUpdatesOnWindow_data()
window.setGeometry(100, 100, 300, 200);
window.show();
QTest::qWaitForWindowExposed(&window);
- bool threaded = window.openglContext()->thread() != QGuiApplication::instance()->thread();
-
+ const bool threaded = QQuickWindowPrivate::get(&window)->context->thread() != QGuiApplication::instance()->thread();
if (threaded) {
QTest::newRow("blocked, beforeRender") << true << QByteArray(SIGNAL(beforeRendering()));
QTest::newRow("blocked, afterRender") << true << QByteArray(SIGNAL(afterRendering()));
@@ -525,9 +528,8 @@ void tst_qquickwindow::touchEvent_basic()
// press single point
QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window);
- QTest::qWait(50);
-
- QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+ QQuickTouchUtils::flush(window);
+ QTRY_COMPARE(topItem->lastEvent.touchPoints.count(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
@@ -535,9 +537,10 @@ void tst_qquickwindow::touchEvent_basic()
// would put the decorated window at that position rather than the window itself.
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
topItem->reset();
+ QTest::touchEvent(window, touchDevice).release(0, topItem->mapToScene(pos).toPoint(), window);
// press multiple points
- QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window)
+ QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window)
.press(1, bottomItem->mapToScene(pos).toPoint(), window);
QQuickTouchUtils::flush(window);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
@@ -547,6 +550,7 @@ void tst_qquickwindow::touchEvent_basic()
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
topItem->reset();
bottomItem->reset();
+ QTest::touchEvent(window, touchDevice).release(0, topItem->mapToScene(pos).toPoint(), window).release(1, bottomItem->mapToScene(pos).toPoint(), window);
// 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);
@@ -557,6 +561,7 @@ void tst_qquickwindow::touchEvent_basic()
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
topItem->reset();
+ QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), window);
// 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);
@@ -567,6 +572,7 @@ void tst_qquickwindow::touchEvent_basic()
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
bottomItem->reset();
+ QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), window);
// a single stationary press on an item shouldn't cause an event
QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window);
@@ -671,6 +677,7 @@ void tst_qquickwindow::touchEvent_propagation()
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed,
makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))));
+ QTest::touchEvent(window, touchDevice).release(0, pointInTopItem, window);
// touch top and middle items, middle item should get both events
QTest::touchEvent(window, touchDevice).press(0, pointInTopItem, window)
@@ -682,6 +689,8 @@ void tst_qquickwindow::touchEvent_propagation()
COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed,
(QList<QTouchEvent::TouchPoint>() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))
<< makeTouchPoint(middleItem, pos) )));
+ QTest::touchEvent(window, touchDevice).release(0, pointInTopItem, window)
+ .release(1, pointInMiddleItem, window);
middleItem->reset();
// disable middleItem as well
@@ -706,6 +715,8 @@ void tst_qquickwindow::touchEvent_propagation()
bottomItem->acceptTouchEvents = acceptTouchEvents;
bottomItem->setEnabled(enableItem);
bottomItem->setVisible(showItem);
+ QTest::touchEvent(window, touchDevice).release(0, pointInTopItem, window)
+ .release(1, pointInMiddleItem, window);
// no events should be received
QTest::touchEvent(window, touchDevice).press(0, pointInTopItem, window)
@@ -715,7 +726,9 @@ void tst_qquickwindow::touchEvent_propagation()
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
-
+ QTest::touchEvent(window, touchDevice).release(0, pointInTopItem, window)
+ .release(1, pointInMiddleItem, window)
+ .release(2, pointInBottomItem, window);
topItem->reset();
middleItem->reset();
bottomItem->reset();
@@ -741,6 +754,7 @@ void tst_qquickwindow::touchEvent_propagation()
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed,
makeTouchPoint(topItem, pos)));
}
+ QTest::touchEvent(window, touchDevice).release(0, pointInTopItem, window);
delete topItem;
delete middleItem;
@@ -859,6 +873,8 @@ void tst_qquickwindow::touchEvent_velocity()
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
+ QCOMPARE(item->touchEventCount, 1);
+
points[0].state = Qt::TouchPointMoved;
points[0].area.adjust(5, 5, 5, 5);
QVector2D velocity(1.5, 2.5);
@@ -891,6 +907,67 @@ void tst_qquickwindow::touchEvent_velocity()
delete item;
}
+void tst_qquickwindow::mergeTouchPointLists_data()
+{
+ QTest::addColumn<QVector<QQuickItem*>>("list1");
+ QTest::addColumn<QVector<QQuickItem*>>("list2");
+ QTest::addColumn<QVector<QQuickItem*>>("expected");
+ QTest::addColumn<bool>("showItem");
+
+ // FIXME: do not leak all these items
+ auto item1 = new QQuickItem();
+ auto item2 = new QQuickItem();
+ auto item3 = new QQuickItem();
+ auto item4 = new QQuickItem();
+ auto item5 = new QQuickItem();
+
+ QTest::newRow("empty") << QVector<QQuickItem*>() << QVector<QQuickItem*>() << QVector<QQuickItem*>();
+ QTest::newRow("single list left")
+ << (QVector<QQuickItem*>() << item1 << item2 << item3)
+ << QVector<QQuickItem*>()
+ << (QVector<QQuickItem*>() << item1 << item2 << item3);
+ QTest::newRow("single list right")
+ << QVector<QQuickItem*>()
+ << (QVector<QQuickItem*>() << item1 << item2 << item3)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3);
+ QTest::newRow("two lists identical")
+ << (QVector<QQuickItem*>() << item1 << item2 << item3)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3);
+ QTest::newRow("two lists 1")
+ << (QVector<QQuickItem*>() << item1 << item2 << item5)
+ << (QVector<QQuickItem*>() << item3 << item4 << item5)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
+ QTest::newRow("two lists 2")
+ << (QVector<QQuickItem*>() << item1 << item2 << item5)
+ << (QVector<QQuickItem*>() << item3 << item4 << item5)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
+ QTest::newRow("two lists 3")
+ << (QVector<QQuickItem*>() << item1 << item2 << item3)
+ << (QVector<QQuickItem*>() << item1 << item4 << item5)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
+ QTest::newRow("two lists 4")
+ << (QVector<QQuickItem*>() << item1 << item3 << item4)
+ << (QVector<QQuickItem*>() << item2 << item3 << item5)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
+ QTest::newRow("two lists 5")
+ << (QVector<QQuickItem*>() << item1 << item2 << item4)
+ << (QVector<QQuickItem*>() << item1 << item3 << item4)
+ << (QVector<QQuickItem*>() << item1 << item2 << item3 << item4);
+}
+
+void tst_qquickwindow::mergeTouchPointLists()
+{
+ QFETCH(QVector<QQuickItem*>, list1);
+ QFETCH(QVector<QQuickItem*>, list2);
+ QFETCH(QVector<QQuickItem*>, expected);
+
+ QQuickWindow win;
+ auto windowPrivate = QQuickWindowPrivate::get(&win);
+ auto targetList = windowPrivate->mergePointerTargets(list1, list2);
+ QCOMPARE(targetList, expected);
+}
+
void tst_qquickwindow::mouseFromTouch_basic()
{
// Turn off accepting touch events with acceptTouchEvents. This
@@ -1229,13 +1306,14 @@ void tst_qquickwindow::headless()
QVERIFY(QTest::qWaitForWindowExposed(window));
QVERIFY(window->isVisible());
- bool threaded = window->openglContext()->thread() != QThread::currentThread();
-
+ const bool threaded = QQuickWindowPrivate::get(window)->context->thread() != QThread::currentThread();
QSignalSpy initialized(window, SIGNAL(sceneGraphInitialized()));
QSignalSpy invalidated(window, SIGNAL(sceneGraphInvalidated()));
// Verify that the window is alive and kicking
- QVERIFY(window->openglContext() != 0);
+ QVERIFY(window->isSceneGraphInitialized());
+
+ const bool isGL = window->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL;
// Store the visual result
QImage originalContent = window->grabWindow();
@@ -1245,15 +1323,16 @@ void tst_qquickwindow::headless()
window->releaseResources();
if (threaded) {
- QTRY_COMPARE(invalidated.size(), 1);
- QVERIFY(!window->openglContext());
+ QTRY_VERIFY(invalidated.size() >= 1);
+ if (isGL)
+ QVERIFY(!window->isSceneGraphInitialized());
}
-
+#ifndef QT_NO_OPENGL
if (QGuiApplication::platformName() == QLatin1String("windows")
&& QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
QSKIP("Crashes on Windows/ANGLE, QTBUG-42967");
}
-
+#endif
// Destroy the native windowing system buffers
window->destroy();
QVERIFY(!window->handle());
@@ -1264,7 +1343,8 @@ void tst_qquickwindow::headless()
if (threaded)
QTRY_COMPARE(initialized.size(), 1);
- QVERIFY(window->openglContext() != 0);
+
+ QVERIFY(window->isSceneGraphInitialized());
// Verify that the visual output is the same
QImage newContent = window->grabWindow();
@@ -1285,8 +1365,7 @@ void tst_qquickwindow::noUpdateWhenNothingChanges()
// the initial expose with a second expose or more. Let these go
// through before we let the test continue.
QTest::qWait(100);
-
- if (window.openglContext()->thread() == QGuiApplication::instance()->thread()) {
+ if (QQuickWindowPrivate::get(&window)->context->thread() == QGuiApplication::instance()->thread()) {
QSKIP("Only threaded renderloop implements this feature");
return;
}
@@ -1593,7 +1672,6 @@ void tst_qquickwindow::hideThenDelete()
QSignalSpy *openglDestroyed = 0;
QSignalSpy *sgInvalidated = 0;
- bool threaded = false;
{
QQuickWindow window;
@@ -1608,9 +1686,13 @@ void tst_qquickwindow::hideThenDelete()
window.show();
QTest::qWaitForWindowExposed(&window);
- threaded = window.openglContext()->thread() != QThread::currentThread();
+ const bool threaded = QQuickWindowPrivate::get(&window)->context->thread() != QGuiApplication::instance()->thread();
+ const bool isGL = window.rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL;
+#ifndef QT_NO_OPENGL
+ if (isGL)
+ openglDestroyed = new QSignalSpy(window.openglContext(), SIGNAL(aboutToBeDestroyed()));
+#endif
- openglDestroyed = new QSignalSpy(window.openglContext(), SIGNAL(aboutToBeDestroyed()));
sgInvalidated = new QSignalSpy(&window, SIGNAL(sceneGraphInvalidated()));
window.hide();
@@ -1618,6 +1700,9 @@ void tst_qquickwindow::hideThenDelete()
QTRY_VERIFY(!window.isExposed());
if (threaded) {
+ if (!isGL)
+ QSKIP("Skipping persistency verification due to not running with OpenGL");
+
if (!persistentSG) {
QVERIFY(sgInvalidated->size() > 0);
if (!persistentGL)
@@ -1632,7 +1717,10 @@ void tst_qquickwindow::hideThenDelete()
}
QVERIFY(sgInvalidated->size() > 0);
- QVERIFY(openglDestroyed->size() > 0);
+#ifndef QT_NO_OPENGL
+ if (openglDestroyed)
+ QVERIFY(openglDestroyed->size() > 0);
+#endif
}
void tst_qquickwindow::showHideAnimate()
@@ -2029,6 +2117,9 @@ void tst_qquickwindow::defaultSurfaceFormat()
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
+ if (window.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
+ QSKIP("Skipping OpenGL context test due to not running with OpenGL");
+
const QSurfaceFormat reqFmt = window.requestedFormat();
QCOMPARE(format.swapInterval(), reqFmt.swapInterval());
QCOMPARE(format.redBufferSize(), reqFmt.redBufferSize());
@@ -2037,12 +2128,13 @@ void tst_qquickwindow::defaultSurfaceFormat()
QCOMPARE(format.profile(), reqFmt.profile());
QCOMPARE(int(format.options()), int(reqFmt.options()));
+#ifndef QT_NO_OPENGL
// Depth and stencil should be >= what has been requested. For real. But use
// the context since the window's surface format is only partially updated
// on most platforms.
QVERIFY(window.openglContext()->format().depthBufferSize() >= 16);
QVERIFY(window.openglContext()->format().stencilBufferSize() >= 8);
-
+#endif
QSurfaceFormat::setDefaultFormat(savedDefaultFormat);
}
@@ -2091,7 +2183,7 @@ public:
}
static int deleted;
};
-
+#ifndef QT_NO_OPENGL
class GlRenderJob : public QRunnable
{
public:
@@ -2113,7 +2205,7 @@ public:
QMutex *mutex;
QWaitCondition *condition;
};
-
+#endif
int RenderJob::deleted = 0;
void tst_qquickwindow::testRenderJob()
@@ -2162,25 +2254,29 @@ void tst_qquickwindow::testRenderJob()
QTRY_COMPARE(RenderJob::deleted, 1);
QCOMPARE(completedJobs.size(), 1);
- // Do a synchronized GL job.
- GLubyte readPixel[4] = {0, 0, 0, 0};
- GlRenderJob *glJob = new GlRenderJob(readPixel);
- if (window.openglContext()->thread() != QThread::currentThread()) {
- QMutex mutex;
- QWaitCondition condition;
- glJob->mutex = &mutex;
- glJob->condition = &condition;
- mutex.lock();
- window.scheduleRenderJob(glJob, QQuickWindow::NoStage);
- condition.wait(&mutex);
- mutex.unlock();
- } else {
- window.scheduleRenderJob(glJob, QQuickWindow::NoStage);
+#ifndef QT_NO_OPENGL
+ if (window.rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) {
+ // Do a synchronized GL job.
+ GLubyte readPixel[4] = {0, 0, 0, 0};
+ GlRenderJob *glJob = new GlRenderJob(readPixel);
+ if (window.openglContext()->thread() != QThread::currentThread()) {
+ QMutex mutex;
+ QWaitCondition condition;
+ glJob->mutex = &mutex;
+ glJob->condition = &condition;
+ mutex.lock();
+ window.scheduleRenderJob(glJob, QQuickWindow::NoStage);
+ condition.wait(&mutex);
+ mutex.unlock();
+ } else {
+ window.scheduleRenderJob(glJob, QQuickWindow::NoStage);
+ }
+ QCOMPARE(int(readPixel[0]), 255);
+ QCOMPARE(int(readPixel[1]), 0);
+ QCOMPARE(int(readPixel[2]), 0);
+ QCOMPARE(int(readPixel[3]), 255);
}
- QCOMPARE(int(readPixel[0]), 255);
- QCOMPARE(int(readPixel[1]), 0);
- QCOMPARE(int(readPixel[2]), 0);
- QCOMPARE(int(readPixel[3]), 255);
+#endif
}
// Verify that jobs are deleted when window is not rendered at all
@@ -2198,7 +2294,6 @@ void tst_qquickwindow::testRenderJob()
class EventCounter : public QQuickRectangle
{
- Q_OBJECT
public:
EventCounter(QQuickItem *parent = 0)
: QQuickRectangle(parent)
@@ -2388,6 +2483,58 @@ void tst_qquickwindow::testHoverTimestamp()
QCOMPARE(hoverConsumer->hoverTimestamps.last(), 5UL);
}
+void tst_qquickwindow::pointerEventTypeAndPointCount()
+{
+ QPointF localPosition(33, 66);
+ QPointF scenePosition(133, 166);
+ QPointF screenPosition(333, 366);
+ QMouseEvent me(QEvent::MouseButtonPress, localPosition, scenePosition, screenPosition,
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QTouchEvent te(QEvent::TouchBegin, touchDevice, Qt::NoModifier, Qt::TouchPointPressed,
+ QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(1));
+
+
+ QQuickPointerMouseEvent pme;
+ pme.reset(&me);
+ QVERIFY(pme.isValid());
+ QCOMPARE(pme.asMouseEvent(localPosition), &me);
+ QVERIFY(pme.asPointerMouseEvent());
+ QVERIFY(!pme.asPointerTouchEvent());
+ QVERIFY(!pme.asPointerTabletEvent());
+// QVERIFY(!pe->asTabletEvent()); // TODO
+ QCOMPARE(pme.pointCount(), 1);
+ QCOMPARE(pme.point(0)->scenePos(), scenePosition);
+ QCOMPARE(pme.asMouseEvent(localPosition)->localPos(), localPosition);
+ QCOMPARE(pme.asMouseEvent(localPosition)->screenPos(), screenPosition);
+
+ QQuickPointerTouchEvent pte;
+ pte.reset(&te);
+ QVERIFY(pte.isValid());
+ QCOMPARE(pte.asTouchEvent(), &te);
+ QVERIFY(!pte.asPointerMouseEvent());
+ QVERIFY(pte.asPointerTouchEvent());
+ QVERIFY(!pte.asPointerTabletEvent());
+ QVERIFY(pte.asTouchEvent());
+// QVERIFY(!pte.asTabletEvent()); // TODO
+ QCOMPARE(pte.pointCount(), 1);
+ QCOMPARE(pte.touchPointById(1)->id(), 1);
+ QVERIFY(!pte.touchPointById(0));
+
+ te.setTouchPoints(QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(1) << QTouchEvent::TouchPoint(2));
+ pte.reset(&te);
+ QCOMPARE(pte.pointCount(), 2);
+ QCOMPARE(pte.touchPointById(1)->id(), 1);
+ QCOMPARE(pte.touchPointById(2)->id(), 2);
+ QVERIFY(!pte.touchPointById(0));
+
+ te.setTouchPoints(QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(2));
+ pte.reset(&te);
+ QCOMPARE(pte.pointCount(), 1);
+ QCOMPARE(pte.touchPointById(2)->id(), 2);
+ QVERIFY(!pte.touchPointById(1));
+ QVERIFY(!pte.touchPointById(0));
+}
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 2e43702e7c..c7ba4de86c 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -2,10 +2,20 @@ TEMPLATE = subdirs
PUBLICTESTS += \
geometry \
- rendernode \
qquickpixmapcache
-qtHaveModule(widgets): PUBLICTESTS += nodes
+qtConfig(opengl(es1|es2)?) {
+ PUBLICTESTS += \
+ rendernode
+ qtHaveModule(widgets): PUBLICTESTS += nodes
+
+ QUICKTESTS += \
+ qquickanimatedsprite \
+ qquickframebufferobject \
+ qquickopenglinfo \
+ qquickspritesequence \
+ qquickshadereffect
+}
!cross_compile: PRIVATETESTS += examples
@@ -39,7 +49,6 @@ QUICKTESTS = \
qquickaccessible \
qquickanchors \
qquickanimatedimage \
- qquickanimatedsprite \
qquickdynamicpropertyanimation \
qquickborderimage \
qquickwindow \
@@ -48,7 +57,7 @@ QUICKTESTS = \
qquickflickable \
qquickflipable \
qquickfocusscope \
- qquickframebufferobject \
+ qquickgraphicsinfo \
qquickgridview \
qquickimage \
qquickitem \
@@ -58,16 +67,13 @@ QUICKTESTS = \
qquickloader \
qquickmousearea \
qquickmultipointtoucharea \
- qquickopenglinfo \
qquickpainteditem \
qquickpathview \
qquickpincharea \
qquickpositioners \
qquickrectangle \
qquickrepeater \
- qquickshadereffect \
qquickshortcut \
- qquickspritesequence \
qquicktext \
qquicktextdocument \
qquicktextedit \
@@ -82,9 +88,9 @@ QUICKTESTS = \
SUBDIRS += $$PUBLICTESTS
-!contains(QT_CONFIG, accessibility):QUICKTESTS -= qquickaccessible
+!qtConfig(accessibility):QUICKTESTS -= qquickaccessible
-contains(QT_CONFIG, private_tests) {
+qtConfig(private_tests) {
SUBDIRS += $$PRIVATETESTS
SUBDIRS += $$QUICKTESTS
}
diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp
index 249612797b..e0fe2c42fc 100644
--- a/tests/auto/quick/rendernode/tst_rendernode.cpp
+++ b/tests/auto/quick/rendernode/tst_rendernode.cpp
@@ -66,12 +66,12 @@ private slots:
class ClearNode : public QSGRenderNode
{
public:
- virtual StateFlags changedStates()
+ StateFlags changedStates() const override
{
return ColorState;
}
- virtual void render(const RenderState &)
+ void render(const RenderState *) override
{
// If clip has been set, scissoring will make sure the right area is cleared.
QOpenGLContext::currentContext()->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), 1.0f);
@@ -122,13 +122,13 @@ class MessUpNode : public QSGRenderNode, protected QOpenGLFunctions
public:
MessUpNode() : initialized(false) { }
- virtual StateFlags changedStates()
+ StateFlags changedStates() const override
{
return StateFlags(DepthState) | StencilState | ScissorState | ColorState | BlendState
- | CullState | ViewportState;
+ | CullState | ViewportState | RenderTargetState;
}
- virtual void render(const RenderState &)
+ void render(const RenderState *) override
{
if (!initialized) {
initializeOpenGLFunctions();
@@ -152,6 +152,9 @@ public:
glGetIntegerv(GL_FRONT_FACE, &frontFace);
glFrontFace(frontFace == GL_CW ? GL_CCW : GL_CW);
glEnable(GL_CULL_FACE);
+ GLuint fbo;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}
bool initialized;
@@ -259,8 +262,8 @@ void tst_rendernode::messUpState()
class StateRecordingRenderNode : public QSGRenderNode
{
public:
- StateFlags changedStates() { return StateFlags(-1); }
- void render(const RenderState &) {
+ StateFlags changedStates() const override { return StateFlags(-1); }
+ void render(const RenderState *) override {
matrices[name] = *matrix();
}
diff --git a/tests/auto/quick/scenegraph/scenegraph.pro b/tests/auto/quick/scenegraph/scenegraph.pro
index 320228bd08..40ff7750cc 100644
--- a/tests/auto/quick/scenegraph/scenegraph.pro
+++ b/tests/auto/quick/scenegraph/scenegraph.pro
@@ -3,6 +3,7 @@ TARGET = tst_scenegraph
SOURCES += tst_scenegraph.cpp
include (../../shared/util.pri)
+include (../shared/util.pri)
macx:CONFIG -= app_bundle
diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
index 1e46727526..f6d624d871 100644
--- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp
+++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
@@ -28,18 +28,26 @@
#include <qtest.h>
+#ifndef QT_NO_OPENGL
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
+#endif
#include <QtQuick>
#include <QtQml>
+#ifndef QT_NO_OPENGL
#include <private/qopenglcontext_p.h>
+#endif
+
#include <private/qsgcontext_p.h>
#include <private/qsgrenderloop_p.h>
#include "../../shared/util.h"
+#include "../shared/visualtestutil.h"
+
+using namespace QQuickVisualTestUtil;
class PerPixelRect : public QQuickItem
{
@@ -97,9 +105,9 @@ private slots:
void render_data();
void render();
-
+#ifndef QT_NO_OPENGL
void hideWithOtherContext();
-
+#endif
void createTextureFromImage_data();
void createTextureFromImage();
@@ -122,6 +130,7 @@ void tst_SceneGraph::initTestCase()
QSGRenderLoop *loop = QSGRenderLoop::instance();
qDebug() << "RenderLoop: " << loop;
+#ifndef QT_NO_OPENGL
QOpenGLContext context;
context.setFormat(loop->sceneGraphContext()->defaultSurfaceFormat());
context.create();
@@ -154,6 +163,7 @@ void tst_SceneGraph::initTestCase()
qDebug() << "Broken Mipmap: " << m_brokenMipmapSupport;
context.doneCurrent();
+#endif
}
QQuickView *tst_SceneGraph::createView(const QString &file, QWindow *parent, int x, int y, int w, int h)
@@ -169,12 +179,17 @@ QQuickView *tst_SceneGraph::createView(const QString &file, QWindow *parent, int
// Assumes the images are opaque white...
bool containsSomethingOtherThanWhite(const QImage &image)
{
- Q_ASSERT(image.format() == QImage::Format_ARGB32_Premultiplied
- || image.format() == QImage::Format_RGB32);
- int w = image.width();
- int h = image.height();
+ QImage img;
+ if (image.format() != QImage::Format_ARGB32_Premultiplied
+ || image.format() != QImage::Format_RGB32)
+ img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ else
+ img = image;
+
+ int w = img.width();
+ int h = img.height();
for (int y=0; y<h; ++y) {
- const uint *pixels = (const uint *) image.constScanLine(y);
+ const uint *pixels = (const uint *) img.constScanLine(y);
for (int x=0; x<w; ++x)
if (pixels[x] != 0xffffffff)
return true;
@@ -182,44 +197,6 @@ bool containsSomethingOtherThanWhite(const QImage &image)
return false;
}
-// When running on native Nvidia graphics cards on linux, the
-// distance field glyph pixels have a measurable, but not visible
-// pixel error. Use a custom compare function to avoid
-//
-// This was GT-216 with the ubuntu "nvidia-319" driver package.
-// llvmpipe does not show the same issue.
-//
-bool compareImages(const QImage &ia, const QImage &ib)
-{
- if (ia.size() != ib.size())
- qDebug() << "images are of different size" << ia.size() << ib.size();
- Q_ASSERT(ia.size() == ib.size());
- Q_ASSERT(ia.format() == ib.format());
-
- int w = ia.width();
- int h = ia.height();
- const int tolerance = 5;
- for (int y=0; y<h; ++y) {
- const uint *as= (const uint *) ia.constScanLine(y);
- const uint *bs= (const uint *) ib.constScanLine(y);
- for (int x=0; x<w; ++x) {
- uint a = as[x];
- uint b = bs[x];
-
- // No tolerance for error in the alpha.
- if ((a & 0xff000000) != (b & 0xff000000))
- return false;
- if (qAbs(qRed(a) - qRed(b)) > tolerance)
- return false;
- if (qAbs(qRed(a) - qRed(b)) > tolerance)
- return false;
- if (qAbs(qRed(a) - qRed(b)) > tolerance)
- return false;
- }
- }
- return true;
-}
-
void tst_SceneGraph::manyWindows_data()
{
QTest::addColumn<QString>("file");
@@ -245,24 +222,26 @@ void tst_SceneGraph::manyWindows_data()
QTest::newRow("rects,subwindow,sharing") << QStringLiteral("manyWindows_rects.qml") << false << true;
}
+#ifndef QT_NO_OPENGL
struct ShareContextResetter {
public:
~ShareContextResetter() { qt_gl_set_global_share_context(0); }
};
+#endif
void tst_SceneGraph::manyWindows()
{
QFETCH(QString, file);
QFETCH(bool, toplevel);
QFETCH(bool, shared);
-
+#ifndef QT_NO_OPENGL
QOpenGLContext sharedGLContext;
ShareContextResetter cleanup; // To avoid dangling pointer in case of test-failure.
if (shared) {
QVERIFY(sharedGLContext.create());
qt_gl_set_global_share_context(&sharedGLContext);
}
-
+#endif
QScopedPointer<QWindow> parent;
if (!toplevel) {
parent.reset(new QWindow());
@@ -451,6 +430,13 @@ void tst_SceneGraph::render_data()
void tst_SceneGraph::render()
{
+ QQuickView dummy;
+ dummy.show();
+ QTest::qWaitForWindowExposed(&dummy);
+ if (dummy.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
+ QSKIP("Skipping complex rendering tests due to not running with OpenGL");
+ dummy.hide();
+
QFETCH(QString, file);
QFETCH(QList<Sample>, baseStage);
QFETCH(QList<Sample>, finalStage);
@@ -493,6 +479,7 @@ void tst_SceneGraph::render()
}
}
+#ifndef QT_NO_OPENGL
// Testcase for QTBUG-34898. We make another context current on another surface
// in the GUI thread and hide the QQuickWindow while the other context is
// current on the other window.
@@ -513,6 +500,9 @@ void tst_SceneGraph::hideWithOtherContext()
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
+ if (view.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
+ QSKIP("Skipping OpenGL context test due to not running with OpenGL");
+
renderingOnMainThread = view.openglContext()->thread() == QGuiApplication::instance()->thread();
// Make the local context current on the local window...
@@ -525,6 +515,7 @@ void tst_SceneGraph::hideWithOtherContext()
// GL calls to a new frame (see QOpenGLContext docs).
QVERIFY(!renderingOnMainThread || QOpenGLContext::currentContext() != &context);
}
+#endif
void tst_SceneGraph::createTextureFromImage_data()
{
@@ -550,6 +541,10 @@ void tst_SceneGraph::createTextureFromImage()
QFETCH(bool, expectedAlpha);
QQuickView view;
+ view.show();
+ QTest::qWaitForWindowExposed(&view);
+ QTRY_VERIFY(view.isSceneGraphInitialized());
+
QScopedPointer<QSGTexture> texture(view.createTextureFromImage(image, (QQuickWindow::CreateTextureOptions) flags));
QCOMPARE(texture->hasAlphaChannel(), expectedAlpha);
}
diff --git a/tests/auto/quick/shared/visualtestutil.cpp b/tests/auto/quick/shared/visualtestutil.cpp
index 3e18c83ee2..eabfe5368b 100644
--- a/tests/auto/quick/shared/visualtestutil.cpp
+++ b/tests/auto/quick/shared/visualtestutil.cpp
@@ -61,3 +61,38 @@ void QQuickVisualTestUtil::dumpTree(QQuickItem *parent, int depth)
}
}
+// A custom compare function to avoid issues such as:
+// When running on native Nvidia graphics cards on linux, the
+// distance field glyph pixels have a measurable, but not visible
+// pixel error. This was GT-216 with the ubuntu "nvidia-319" driver package.
+// llvmpipe does not show the same issue.
+bool QQuickVisualTestUtil::compareImages(const QImage &ia, const QImage &ib)
+{
+ if (ia.size() != ib.size())
+ qDebug() << "images are of different size" << ia.size() << ib.size();
+ Q_ASSERT(ia.size() == ib.size());
+ Q_ASSERT(ia.format() == ib.format());
+
+ int w = ia.width();
+ int h = ia.height();
+ const int tolerance = 5;
+ for (int y=0; y<h; ++y) {
+ const uint *as= (const uint *) ia.constScanLine(y);
+ const uint *bs= (const uint *) ib.constScanLine(y);
+ for (int x=0; x<w; ++x) {
+ uint a = as[x];
+ uint b = bs[x];
+
+ // No tolerance for error in the alpha.
+ if ((a & 0xff000000) != (b & 0xff000000))
+ return false;
+ if (qAbs(qRed(a) - qRed(b)) > tolerance)
+ return false;
+ if (qAbs(qRed(a) - qRed(b)) > tolerance)
+ return false;
+ if (qAbs(qRed(a) - qRed(b)) > tolerance)
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/tests/auto/quick/shared/visualtestutil.h b/tests/auto/quick/shared/visualtestutil.h
index 2b377a4bab..2daf86cd83 100644
--- a/tests/auto/quick/shared/visualtestutil.h
+++ b/tests/auto/quick/shared/visualtestutil.h
@@ -96,6 +96,8 @@ namespace QQuickVisualTestUtil
items << qobject_cast<QQuickItem*>(findItem<T>(parent, objectName, indexes[i]));
return items;
}
+
+ bool compareImages(const QImage &ia, const QImage &ib);
}
#define QQUICK_VERIFY_POLISH(item) \
diff --git a/tests/auto/quick/touchmouse/data/touchpointdeliveryorder.qml b/tests/auto/quick/touchmouse/data/touchpointdeliveryorder.qml
new file mode 100644
index 0000000000..9f67c226a0
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/touchpointdeliveryorder.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Rectangle {
+ id: root
+
+ width: 600
+ height: 400
+
+ EventItem {
+ objectName: "background"
+ width: 600
+ height: 400
+ Rectangle { anchors.fill: parent; color: "lightsteelblue" }
+
+ EventItem {
+ objectName: "left"
+ width: 300
+ height: 300
+ Rectangle { anchors.fill: parent; color: "yellow" }
+ }
+
+ EventItem {
+ objectName: "right"
+ x: 300
+ width: 300
+ height: 300
+ Rectangle { anchors.fill: parent; color: "green" }
+ }
+
+ EventItem {
+ objectName: "middle"
+ x: 150
+ width: 300
+ height: 300
+ Rectangle { anchors.fill: parent; color: "blue" }
+ }
+ }
+}
diff --git a/tests/auto/quick/touchmouse/touchmouse.pro b/tests/auto/quick/touchmouse/touchmouse.pro
index 0df9bc53d3..49818bb399 100644
--- a/tests/auto/quick/touchmouse/touchmouse.pro
+++ b/tests/auto/quick/touchmouse/touchmouse.pro
@@ -1,7 +1,7 @@
CONFIG += testcase
TARGET = tst_touchmouse
-QT += core-private gui-private qml-private quick-private testlib
+QT += core-private qml-private quick-private testlib
macx:CONFIG -= app_bundle
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 72cc76a855..309c01dcdc 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -33,13 +33,12 @@
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquickevents_p_p.h>
#include <QtQuick/private/qquickmousearea_p.h>
#include <QtQuick/private/qquickmultipointtoucharea_p.h>
#include <QtQuick/private/qquickpincharea_p.h>
#include <QtQuick/private/qquickflickable_p.h>
-#include <qpa/qwindowsysteminterface.h>
-
-#include <private/qquickwindow_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlproperty.h>
@@ -66,15 +65,22 @@ struct Event
class EventItem : public QQuickItem
{
Q_OBJECT
+
+Q_SIGNALS:
+ void onTouchEvent(QQuickItem *receiver);
+
public:
EventItem(QQuickItem *parent = 0)
: QQuickItem(parent), acceptMouse(false), acceptTouch(false), filterTouch(false)
- {}
+ {
+ setAcceptedMouseButtons(Qt::LeftButton);
+ }
void touchEvent(QTouchEvent *event)
{
eventList.append(Event(event->type(), event->touchPoints()));
event->setAccepted(acceptTouch);
+ emit onTouchEvent(this);
}
void mousePressEvent(QMouseEvent *event)
{
@@ -132,7 +138,7 @@ class tst_TouchMouse : public QQmlDataTest
Q_OBJECT
public:
tst_TouchMouse()
- :device(0)
+ :device(QTest::createTouchDevice())
{}
private slots:
@@ -145,6 +151,7 @@ private slots:
void mouseOverTouch();
void buttonOnFlickable();
+ void buttonOnDelayedPressFlickable_data();
void buttonOnDelayedPressFlickable();
void buttonOnTouch();
@@ -155,6 +162,7 @@ private slots:
void tapOnDismissiveTopMouseAreaClicksBottomOne();
void touchGrabCausesMouseUngrab();
+ void touchPointDeliveryOrder();
void hoverEnabled();
@@ -191,11 +199,6 @@ void tst_TouchMouse::initTestCase()
QQmlDataTest::initTestCase();
qmlRegisterType<EventItem>("Qt.test", 1, 0, "EventItem");
- if (!device) {
- device = new QTouchDevice;
- device->setType(QTouchDevice::TouchScreen);
- QWindowSystemInterface::registerTouchDevice(device);
- }
}
void tst_TouchMouse::simpleTouchEvent()
@@ -217,15 +220,17 @@ void tst_TouchMouse::simpleTouchEvent()
p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
QQuickTouchUtils::flush(window);
- QCOMPARE(eventItem1->eventList.size(), 1);
+ // Get a touch and then mouse event offered
+ QCOMPARE(eventItem1->eventList.size(), 2);
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);
+ // Not accepted, no updates
+ QCOMPARE(eventItem1->eventList.size(), 2);
QTest::touchEvent(window, device).release(0, p1, window);
QQuickTouchUtils::flush(window);
- QCOMPARE(eventItem1->eventList.size(), 1);
+ QCOMPARE(eventItem1->eventList.size(), 2);
eventItem1->eventList.clear();
// Accept touch
@@ -256,8 +261,7 @@ void tst_TouchMouse::simpleTouchEvent()
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
- QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
- QCOMPARE(windowPriv->mouseGrabberItem, eventItem1);
+ QCOMPARE(window->mouseGrabberItem(), eventItem1);
QPoint localPos = eventItem1->mapFromScene(p1).toPoint();
QPoint globalPos = window->mapToGlobal(p1);
@@ -292,17 +296,16 @@ void tst_TouchMouse::simpleTouchEvent()
p1 = QPoint(20, 20);
QTest::touchEvent(window, device).press(0, p1, window);
QQuickTouchUtils::flush(window);
- QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
- QCOMPARE(eventItem1->eventList.at(2).type, QEvent::UngrabMouse);
p1 += QPoint(10, 0);
QTest::touchEvent(window, device).move(0, p1, window);
QQuickTouchUtils::flush(window);
- QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE(eventItem1->eventList.size(), 2);
QTest::touchEvent(window, device).release(0, p1, window);
QQuickTouchUtils::flush(window);
- QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE(eventItem1->eventList.size(), 2);
eventItem1->eventList.clear();
// wait to avoid getting a double click event
@@ -579,8 +582,9 @@ void tst_TouchMouse::buttonOnFlickable()
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
QCOMPARE(windowPriv->touchMouseId, 0);
- QCOMPARE(windowPriv->itemForTouchPointId[0], eventItem1);
- QCOMPARE(windowPriv->mouseGrabberItem, eventItem1);
+ auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent();
+ QCOMPARE(pointerEvent->point(0)->grabber(), eventItem1);
+ QCOMPARE(window->mouseGrabberItem(), eventItem1);
p1 += QPoint(0, -10);
QPoint p2 = p1 + QPoint(0, -10);
@@ -598,9 +602,9 @@ void tst_TouchMouse::buttonOnFlickable()
QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchUpdate);
QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove);
- QCOMPARE(windowPriv->mouseGrabberItem, flickable);
+ QCOMPARE(window->mouseGrabberItem(), flickable);
QCOMPARE(windowPriv->touchMouseId, 0);
- QCOMPARE(windowPriv->itemForTouchPointId[0], flickable);
+ QCOMPARE(pointerEvent->point(0)->grabber(), flickable);
QVERIFY(flickable->isMovingVertically());
QTest::touchEvent(window, device).release(0, p3, window);
@@ -608,11 +612,25 @@ void tst_TouchMouse::buttonOnFlickable()
delete window;
}
+void tst_TouchMouse::buttonOnDelayedPressFlickable_data()
+{
+ QTest::addColumn<bool>("scrollBeforeDelayIsOver");
+
+ // the item should never see the event,
+ // due to the pressDelay which never delivers if we start moving
+ QTest::newRow("scroll before press delay is over") << true;
+
+ // wait until the "button" sees the press but then
+ // start moving: the button gets a press and cancel event
+ QTest::newRow("scroll after press delay is over") << false;
+}
+
void tst_TouchMouse::buttonOnDelayedPressFlickable()
{
// flickable - height 500 / 1000
// - eventItem1 y: 100, height 100
// - eventItem2 y: 300, height 100
+ QFETCH(bool, scrollBeforeDelayIsOver);
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
filteredEventList.clear();
@@ -631,7 +649,8 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
window->installEventFilter(this);
- flickable->setPressDelay(60);
+ // wait 600 ms before letting the child see the press event
+ flickable->setPressDelay(600);
// should a mouse area button be clickable on top of flickable? yes :)
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -647,25 +666,23 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
// wait to avoid getting a double click event
QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
+ QCOMPARE(windowPriv->touchMouseId, -1); // no grabber
- // check that flickable moves - mouse button
- QCOMPARE(eventItem1->eventList.size(), 0);
+ // touch press
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
- QTRY_COMPARE(eventItem1->eventList.size(), 1);
- QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress);
- QCOMPARE(filteredEventList.count(), 1);
- // eventItem1 should have the mouse grab, and have moved the itemForTouchPointId
- // for the touchMouseId to the new grabber.
- QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
- QCOMPARE(windowPriv->touchMouseId, 0);
- QCOMPARE(windowPriv->itemForTouchPointId[0], eventItem1);
- QCOMPARE(windowPriv->mouseGrabberItem, eventItem1);
+ if (scrollBeforeDelayIsOver) {
+ // no events, the flickable got scrolled, the button sees nothing
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ } else {
+ // wait until the button sees the press
+ QTRY_COMPARE(eventItem1->eventList.size(), 1);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress);
+ QCOMPARE(filteredEventList.count(), 1);
+ }
p1 += QPoint(0, -10);
QPoint p2 = p1 + QPoint(0, -10);
@@ -677,20 +694,35 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).move(0, p3, window);
QQuickTouchUtils::flush(window);
- QVERIFY(flickable->isMovingVertically());
+ QTRY_VERIFY(flickable->isMovingVertically());
+
+ if (scrollBeforeDelayIsOver) {
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ QCOMPARE(filteredEventList.count(), 0);
+ } else {
+ // see at least press, move and ungrab
+ QTRY_VERIFY(eventItem1->eventList.size() > 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress);
+ QCOMPARE(eventItem1->eventList.last().type, QEvent::UngrabMouse);
+ QCOMPARE(filteredEventList.count(), 1);
+ }
// flickable should have the mouse grab, and have moved the itemForTouchPointId
// for the touchMouseId to the new grabber.
- QCOMPARE(windowPriv->mouseGrabberItem, flickable);
+ QCOMPARE(window->mouseGrabberItem(), flickable);
QCOMPARE(windowPriv->touchMouseId, 0);
- QCOMPARE(windowPriv->itemForTouchPointId[0], flickable);
+ auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent();
+ QCOMPARE(pointerEvent->point(0)->grabber(), flickable);
QTest::touchEvent(window, device).release(0, p3, window);
QQuickTouchUtils::flush(window);
// We should not have received any synthesised mouse events from Qt gui,
// just the delayed press.
- QCOMPARE(filteredEventList.count(), 1);
+ if (scrollBeforeDelayIsOver)
+ QCOMPARE(filteredEventList.count(), 0);
+ else
+ QCOMPARE(filteredEventList.count(), 1);
delete window;
}
@@ -1097,9 +1129,7 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
pinchSequence.move(0, p, window).commit();
QQuickTouchUtils::flush(window);
- QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
- qDebug() << "Mouse Grabber: " << windowPriv->mouseGrabberItem << " itemForTouchPointId: " << windowPriv->itemForTouchPointId;
- QCOMPARE(windowPriv->mouseGrabberItem, flickable);
+ QCOMPARE(window->mouseGrabberItem(), flickable);
// Add a second finger, this should lead to stealing
p1 = QPoint(40, 100);
@@ -1229,6 +1259,105 @@ void tst_TouchMouse::touchGrabCausesMouseUngrab()
delete window;
}
+void tst_TouchMouse::touchPointDeliveryOrder()
+{
+ // Touch points should be first delivered to the item under the primary finger
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("touchpointdeliveryorder.qml"));
+ /*
+ The items are positioned from left to right:
+ | background |
+ | left |
+ | | right |
+ | middle |
+ 0 150 300 450 600
+ */
+ QPoint pLeft = QPoint(100, 100);
+ QPoint pRight = QPoint(500, 100);
+ QPoint pLeftMiddle = QPoint(200, 100);
+ QPoint pRightMiddle = QPoint(350, 100);
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QVector<QQuickItem*> events;
+ EventItem *background = window->rootObject()->findChild<EventItem*>("background");
+ EventItem *left = window->rootObject()->findChild<EventItem*>("left");
+ EventItem *middle = window->rootObject()->findChild<EventItem*>("middle");
+ EventItem *right = window->rootObject()->findChild<EventItem*>("right");
+ QVERIFY(background);
+ QVERIFY(left);
+ QVERIFY(middle);
+ QVERIFY(right);
+ connect(background, &EventItem::onTouchEvent, [&events](QQuickItem* receiver){ events.append(receiver); });
+ connect(left, &EventItem::onTouchEvent, [&events](QQuickItem* receiver){ events.append(receiver); });
+ connect(middle, &EventItem::onTouchEvent, [&events](QQuickItem* receiver){ events.append(receiver); });
+ connect(right, &EventItem::onTouchEvent, [&events](QQuickItem* receiver){ events.append(receiver); });
+
+ QTest::touchEvent(window.data(), device).press(0, pLeft, window.data());
+ QQuickTouchUtils::flush(window.data());
+
+ // Touch on left, then background
+ QCOMPARE(events.size(), 2);
+ QCOMPARE(events.at(0), left);
+ QCOMPARE(events.at(1), background);
+ events.clear();
+
+ // New press events are deliverd first, the stationary point was not accepted, thus it doesn't get delivered
+ QTest::touchEvent(window.data(), device).stationary(0).press(1, pRightMiddle, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QCOMPARE(events.size(), 3);
+ QCOMPARE(events.at(0), middle);
+ QCOMPARE(events.at(1), right);
+ QCOMPARE(events.at(2), background);
+ events.clear();
+
+ QTest::touchEvent(window.data(), device).release(0, pLeft, window.data()).release(1, pRightMiddle, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QCOMPARE(events.size(), 0); // no accepted events
+
+ // Two presses, the first point should come first
+ QTest::touchEvent(window.data(), device).press(0, pLeft, window.data()).press(1, pRight, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QCOMPARE(events.size(), 3);
+ QCOMPARE(events.at(0), left);
+ QCOMPARE(events.at(1), right);
+ QCOMPARE(events.at(2), background);
+ QTest::touchEvent(window.data(), device).release(0, pLeft, window.data()).release(1, pRight, window.data());
+ events.clear();
+
+ // Again, pressing right first
+ QTest::touchEvent(window.data(), device).press(0, pRight, window.data()).press(1, pLeft, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QCOMPARE(events.size(), 3);
+ QCOMPARE(events.at(0), right);
+ QCOMPARE(events.at(1), left);
+ QCOMPARE(events.at(2), background);
+ QTest::touchEvent(window.data(), device).release(0, pRight, window.data()).release(1, pLeft, window.data());
+ events.clear();
+
+ // Two presses, both hitting the middle item on top, then branching left and right, then bottom
+ // Each target should be offered the events exactly once, middle first, left must come before right (id 0)
+ QTest::touchEvent(window.data(), device).press(0, pLeftMiddle, window.data()).press(1, pRightMiddle, window.data());
+ QCOMPARE(events.size(), 4);
+ QCOMPARE(events.at(0), middle);
+ QCOMPARE(events.at(1), left);
+ QCOMPARE(events.at(2), right);
+ QCOMPARE(events.at(3), background);
+ QTest::touchEvent(window.data(), device).release(0, pLeftMiddle, window.data()).release(1, pRightMiddle, window.data());
+ events.clear();
+
+ QTest::touchEvent(window.data(), device).press(0, pRightMiddle, window.data()).press(1, pLeftMiddle, window.data());
+ qDebug() << events;
+ QCOMPARE(events.size(), 4);
+ QCOMPARE(events.at(0), middle);
+ QCOMPARE(events.at(1), right);
+ QCOMPARE(events.at(2), left);
+ QCOMPARE(events.at(3), background);
+ QTest::touchEvent(window.data(), device).release(0, pRightMiddle, window.data()).release(1, pLeftMiddle, window.data());
+}
+
void tst_TouchMouse::hoverEnabled()
{
// QTouchDevice *device = new QTouchDevice;
@@ -1276,8 +1405,8 @@ void tst_TouchMouse::hoverEnabled()
// ------------------------- Touch click on mouseArea1
QTest::touchEvent(window, device).press(0, p1, window);
- QVERIFY(enterSpy1.count() == 1);
- QVERIFY(enterSpy2.count() == 0);
+ QCOMPARE(enterSpy1.count(), 1);
+ QCOMPARE(enterSpy2.count(), 0);
QVERIFY(mouseArea1->pressed());
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea2->hovered());
@@ -1288,33 +1417,36 @@ void tst_TouchMouse::hoverEnabled()
QVERIFY(!mouseArea2->hovered());
// ------------------------- Touch click on mouseArea2
+ if (QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive) == 0)
+ QSKIP("hover can be momentarily inconsistent on X11, depending on timing of flushFrameSynchronousEvents with touch and mouse movements (QTBUG-55350)");
+
QTest::touchEvent(window, device).press(0, p2, window);
QVERIFY(mouseArea1->hovered());
QVERIFY(mouseArea2->hovered());
QVERIFY(mouseArea2->pressed());
- QVERIFY(enterSpy1.count() == 1);
- QVERIFY(enterSpy2.count() == 1);
+ QCOMPARE(enterSpy1.count(), 1);
+ QCOMPARE(enterSpy2.count(), 1);
QTest::touchEvent(window, device).release(0, p2, window);
QVERIFY(clickSpy2.count() == 1);
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea2->hovered());
- QVERIFY(exitSpy1.count() == 0);
- QVERIFY(exitSpy2.count() == 1);
+ QCOMPARE(exitSpy1.count(), 0);
+ QCOMPARE(exitSpy2.count(), 1);
// ------------------------- Another touch click on mouseArea1
QTest::touchEvent(window, device).press(0, p1, window);
- QVERIFY(enterSpy1.count() == 1);
- QVERIFY(enterSpy2.count() == 1);
+ QCOMPARE(enterSpy1.count(), 1);
+ QCOMPARE(enterSpy2.count(), 1);
QVERIFY(mouseArea1->pressed());
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea2->hovered());
QTest::touchEvent(window, device).release(0, p1, window);
- QVERIFY(clickSpy1.count() == 2);
+ QCOMPARE(clickSpy1.count(), 2);
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea1->pressed());
QVERIFY(!mouseArea2->hovered());
diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
index ab2c41b6bf..5e8f762e23 100644
--- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
+++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
@@ -34,6 +34,7 @@
#include <QtQuick/qquickitem.h>
#include "../../shared/util.h"
#include <QtGui/QWindow>
+#include <QtGui/QImage>
#include <QtCore/QDebug>
#include <QtQml/qqmlengine.h>
@@ -55,6 +56,7 @@ private slots:
void readback();
void renderingSignals();
void grabBeforeShow();
+ void reparentToNewWindow();
void nullEngine();
};
@@ -302,6 +304,27 @@ void tst_qquickwidget::grabBeforeShow()
QVERIFY(!widget.grab().isNull());
}
+void tst_qquickwidget::reparentToNewWindow()
+{
+ QWidget window1;
+ QWidget window2;
+
+ QQuickWidget *qqw = new QQuickWidget(&window1);
+ qqw->setSource(testFileUrl("rectangle.qml"));
+ window1.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window1, 5000));
+ window2.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window2, 5000));
+
+ QSignalSpy afterRenderingSpy(qqw->quickWindow(), &QQuickWindow::afterRendering);
+ qqw->setParent(&window2);
+ qqw->show();
+ QTRY_VERIFY(afterRenderingSpy.size() > 0);
+
+ QImage img = qqw->grabFramebuffer();
+ QCOMPARE(img.pixel(5, 5), qRgb(255, 0, 0));
+}
+
void tst_qquickwidget::nullEngine()
{
QQuickWidget widget;
diff --git a/tests/auto/shared/util.cpp b/tests/auto/shared/util.cpp
index 55041eeb4d..96beb51612 100644
--- a/tests/auto/shared/util.cpp
+++ b/tests/auto/shared/util.cpp
@@ -101,11 +101,15 @@ Q_GLOBAL_STATIC(QMutex, qQmlTestMessageHandlerMutex)
QQmlTestMessageHandler *QQmlTestMessageHandler::m_instance = 0;
-void QQmlTestMessageHandler::messageHandler(QtMsgType, const QMessageLogContext &, const QString &message)
+void QQmlTestMessageHandler::messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message)
{
QMutexLocker locker(qQmlTestMessageHandlerMutex());
- if (QQmlTestMessageHandler::m_instance)
- QQmlTestMessageHandler::m_instance->m_messages.push_back(message);
+ if (QQmlTestMessageHandler::m_instance) {
+ if (QQmlTestMessageHandler::m_instance->m_includeCategories)
+ QQmlTestMessageHandler::m_instance->m_messages.push_back(QString("%1: %2").arg(context.category, message));
+ else
+ QQmlTestMessageHandler::m_instance->m_messages.push_back(message);
+ }
}
QQmlTestMessageHandler::QQmlTestMessageHandler()
@@ -114,6 +118,7 @@ QQmlTestMessageHandler::QQmlTestMessageHandler()
Q_ASSERT(!QQmlTestMessageHandler::m_instance);
QQmlTestMessageHandler::m_instance = this;
m_oldHandler = qInstallMessageHandler(messageHandler);
+ m_includeCategories = false;
}
QQmlTestMessageHandler::~QQmlTestMessageHandler()
diff --git a/tests/auto/shared/util.h b/tests/auto/shared/util.h
index 47a4aae231..33d7cbd1d0 100644
--- a/tests/auto/shared/util.h
+++ b/tests/auto/shared/util.h
@@ -87,12 +87,15 @@ public:
void clear() { m_messages.clear(); }
+ void setIncludeCategoriesEnabled(bool enabled) { m_includeCategories = enabled; }
+
private:
- static void messageHandler(QtMsgType, const QMessageLogContext &, const QString &message);
+ static void messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message);
static QQmlTestMessageHandler *m_instance;
QStringList m_messages;
QtMessageHandler m_oldHandler;
+ bool m_includeCategories;
};
#endif // QQMLTESTUTILS_H
diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro
index c7e7c6829a..5e6bc65815 100644
--- a/tests/benchmarks/benchmarks.pro
+++ b/tests/benchmarks/benchmarks.pro
@@ -1,5 +1,5 @@
TEMPLATE = subdirs
SUBDIRS = qml script
-contains(QT_CONFIG, private_tests) {
- SUBDIRS += particles
+qtConfig(private_tests) {
+ qtConfig(opengl(es1|es2)?):SUBDIRS += particles
}
diff --git a/tests/benchmarks/particles/affectors/tst_affectors.cpp b/tests/benchmarks/particles/affectors/tst_affectors.cpp
index 475b8d28ec..99d175564b 100644
--- a/tests/benchmarks/particles/affectors/tst_affectors.cpp
+++ b/tests/benchmarks/particles/affectors/tst_affectors.cpp
@@ -86,7 +86,7 @@ void tst_affectors::test_basic()
int stillAlive = 0;
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 1000, 10));//Small simulation variance is permissible.
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
@@ -126,7 +126,7 @@ void tst_affectors::test_filtered()
int stillAlive = 0;
QVERIFY(extremelyFuzzyCompare(system->groupData[1]->size(), 1000, 10));//Small simulation variance is permissible.
- foreach (QQuickParticleData *d, system->groupData[1]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/benchmarks/particles/emission/tst_emission.cpp b/tests/benchmarks/particles/emission/tst_emission.cpp
index b107120a28..fe08305f68 100644
--- a/tests/benchmarks/particles/emission/tst_emission.cpp
+++ b/tests/benchmarks/particles/emission/tst_emission.cpp
@@ -79,7 +79,7 @@ void tst_emission::test_basic()
int stillAlive = 0;
QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 1000, 10));//Small simulation variance is permissible.
- foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/benchmarks/qml/animation/tst_animation.cpp b/tests/benchmarks/qml/animation/tst_animation.cpp
index 4f693f9fa8..59f5a57f5c 100644
--- a/tests/benchmarks/qml/animation/tst_animation.cpp
+++ b/tests/benchmarks/qml/animation/tst_animation.cpp
@@ -107,8 +107,8 @@ void tst_animation::animationelements_data()
{
QTest::addColumn<QString>("type");
- QSet<QString> types = QQmlMetaType::qmlTypeNames().toSet();
- foreach (const QString &type, types) {
+ const QSet<QString> types = QQmlMetaType::qmlTypeNames().toSet();
+ for (const QString &type : types) {
if (type.contains(QLatin1String("Animation")))
QTest::newRow(type.toLatin1()) << type;
}
diff --git a/tests/benchmarks/qml/compilation/tst_compilation.cpp b/tests/benchmarks/qml/compilation/tst_compilation.cpp
index 3f2cb5b94f..690e193b53 100644
--- a/tests/benchmarks/qml/compilation/tst_compilation.cpp
+++ b/tests/benchmarks/qml/compilation/tst_compilation.cpp
@@ -75,7 +75,9 @@ void tst_compilation::boomblock()
QQmlComponent c(&engine);
c.setData(data, QUrl());
}
-
+#ifdef QT_NO_OPENGL
+ QSKIP("boomblock imports Particles which requires OpenGL Support");
+#endif
QBENCHMARK {
QQmlComponent c(&engine);
c.setData(data, QUrl());
diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp
index c835e4799c..9fc67ada71 100644
--- a/tests/benchmarks/qml/creation/tst_creation.cpp
+++ b/tests/benchmarks/qml/creation/tst_creation.cpp
@@ -62,6 +62,12 @@ private slots:
void itemtests_qml_data();
void itemtests_qml();
+ void bindings_cpp();
+ void bindings_cpp2();
+ void bindings_qml();
+
+ void bindings_parent_qml();
+
void anchors_creation();
void anchors_heightChange();
@@ -329,6 +335,89 @@ void tst_creation::itemtests_qml()
QBENCHMARK { delete component.create(); }
}
+void tst_creation::bindings_cpp()
+{
+ QQuickItem item;
+ QMetaProperty widthProp = item.metaObject()->property(item.metaObject()->indexOfProperty("width"));
+ QMetaProperty heightProp = item.metaObject()->property(item.metaObject()->indexOfProperty("height"));
+ connect(&item, &QQuickItem::heightChanged, [&item, &widthProp, &heightProp](){
+ QVariant height = heightProp.read(&item);
+ widthProp.write(&item, height);
+ });
+
+ int height = 0;
+ QBENCHMARK {
+ item.setHeight(++height);
+ }
+}
+
+void tst_creation::bindings_cpp2()
+{
+ QQuickItem item;
+ int widthProp = item.metaObject()->indexOfProperty("width");
+ int heightProp = item.metaObject()->indexOfProperty("height");
+ connect(&item, &QQuickItem::heightChanged, [&item, widthProp, heightProp](){
+
+ qreal height = -1;
+ void *args[] = { &height, 0 };
+ QMetaObject::metacall(&item, QMetaObject::ReadProperty, heightProp, args);
+
+ int flags = 0;
+ int status = -1;
+ void *argv[] = { &height, 0, &status, &flags };
+ QMetaObject::metacall(&item, QMetaObject::WriteProperty, widthProp, argv);
+ });
+
+ int height = 0;
+ QBENCHMARK {
+ item.setHeight(++height);
+ }
+}
+
+void tst_creation::bindings_qml()
+{
+ QByteArray data = "import QtQuick 2.0\nItem { width: height }";
+
+ QQmlComponent component(&engine);
+ component.setData(data, QUrl());
+ if (!component.isReady()) {
+ qWarning() << "Unable to create component: " << component.errorString();
+ return;
+ }
+
+ QQuickItem *obj = dynamic_cast<QQuickItem *>(component.create());
+ QVERIFY(obj != nullptr);
+
+ int height = 0;
+ QBENCHMARK {
+ obj->setHeight(++height);
+ }
+
+ delete obj;
+}
+
+void tst_creation::bindings_parent_qml()
+{
+ QByteArray data = "import QtQuick 2.0\nItem { Item { width: parent.height }}";
+
+ QQmlComponent component(&engine);
+ component.setData(data, QUrl());
+ if (!component.isReady()) {
+ qWarning() << "Unable to create component: " << component.errorString();
+ return;
+ }
+
+ QQuickItem *obj = dynamic_cast<QQuickItem *>(component.create());
+ QVERIFY(obj != nullptr);
+
+ int height = 0;
+ QBENCHMARK {
+ obj->setHeight(++height);
+ }
+
+ delete obj;
+}
+
void tst_creation::anchors_creation()
{
QQmlComponent component(&engine);
diff --git a/tests/manual/nodetypes/Animators.qml b/tests/manual/nodetypes/Animators.qml
new file mode 100644
index 0000000000..7d8baf1cb8
--- /dev/null
+++ b/tests/manual/nodetypes/Animators.qml
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.5
+
+Item {
+ id: window
+
+ Rectangle {
+ anchors.fill: parent
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#14148c" }
+ GradientStop { position: 0.499; color: "#14aaff" }
+ GradientStop { position: 0.5; color: "#80c342" }
+ GradientStop { position: 1.0; color: "#006325" }
+ }
+ }
+
+ SequentialAnimation {
+ id: plainAnim
+ SequentialAnimation {
+ ParallelAnimation {
+ PropertyAnimation {
+ property: "y"
+ target: smiley
+ from: smiley.minHeight
+ to: smiley.maxHeight
+ easing.type: Easing.OutExpo
+ duration: 300
+ }
+ PropertyAnimation {
+ property: "scale"
+ target: shadow
+ from: 1
+ to: 0.5
+ easing.type: Easing.OutExpo
+ duration: 300
+ }
+ }
+ ParallelAnimation {
+ PropertyAnimation {
+ property: "y"
+ target: smiley
+ from: smiley.maxHeight
+ to: smiley.minHeight
+ easing.type: Easing.OutBounce
+ duration: 1000
+ }
+ PropertyAnimation {
+ property: "scale"
+ target: shadow
+ from: 0.5
+ to: 1
+ easing.type: Easing.OutBounce
+ duration: 1000
+ }
+ }
+ }
+ running: false
+ }
+
+ SequentialAnimation {
+ id: renderThreadAnim
+ SequentialAnimation {
+ ParallelAnimation {
+ YAnimator {
+ target: smiley
+ from: smiley.minHeight
+ to: smiley.maxHeight
+ easing.type: Easing.OutExpo
+ duration: 300
+ }
+ ScaleAnimator {
+ target: shadow
+ from: 1
+ to: 0.5
+ easing.type: Easing.OutExpo
+ duration: 300
+ }
+ }
+ ParallelAnimation {
+ YAnimator {
+ target: smiley
+ from: smiley.maxHeight
+ to: smiley.minHeight
+ easing.type: Easing.OutBounce
+ duration: 1000
+ }
+ ScaleAnimator {
+ target: shadow
+ from: 0.5
+ to: 1
+ easing.type: Easing.OutBounce
+ duration: 1000
+ }
+ }
+ }
+ running: false
+ }
+
+ Image {
+ id: shadow
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: smiley.minHeight + smiley.height
+ source: "qrc:/shadow.png"
+ }
+
+ Image {
+ id: smiley
+ property int maxHeight: window.height / 3
+ property int minHeight: 2 * window.height / 3
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: minHeight
+ source: "qrc:/face-smile.png"
+ }
+
+ Text {
+ text: "click left for plain animation, right for render thread Animators, middle to sleep for 2 sec on the main (gui) thread"
+ color: "white"
+ }
+
+ Text {
+ text: plainAnim.running ? "NORMAL ANIMATION" : (renderThreadAnim.running ? "RENDER THREAD ANIMATION" : "NO ANIMATION")
+ color: "red"
+ font.pointSize: 20
+ anchors.bottom: parent.bottom
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.AllButtons
+ onClicked: if (mouse.button === Qt.LeftButton) {
+ renderThreadAnim.running = false;
+ plainAnim.running = true;
+ } else if (mouse.button === Qt.RightButton) {
+ plainAnim.running = false;
+ renderThreadAnim.running = true;
+ } else if (mouse.button === Qt.MiddleButton) {
+ helper.sleep(2000);
+ }
+ }
+}
diff --git a/tests/manual/nodetypes/Effects.qml b/tests/manual/nodetypes/Effects.qml
new file mode 100644
index 0000000000..85e7ab7a15
--- /dev/null
+++ b/tests/manual/nodetypes/Effects.qml
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+// Use QtQuick 2.8 to get GraphicsInfo and the other new properties
+import QtQuick 2.8
+
+Item {
+ Rectangle {
+ color: "gray"
+ anchors.margins: 10
+ anchors.fill: parent
+ Image {
+ id: image1
+ source: "qrc:/qt.png"
+ }
+ ShaderEffectSource {
+ id: effectSource1
+ sourceItem: image1
+ hideSource: true
+ }
+ ShaderEffect { // wobble
+ id: eff
+ width: image1.width
+ height: image1.height
+ anchors.centerIn: parent
+
+ property variant source: effectSource1
+ property real amplitude: 0.04 * 0.2
+ property real frequency: 20
+ property real time: 0
+
+ NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 }
+
+ property bool customVertexShader: false // the effect is fine with the default vs, but toggle this to test
+ property bool useHLSLSourceString: false // toggle to provide HLSL shaders as strings instead of bytecode in files
+
+ property string glslVertexShader:
+ "uniform highp mat4 qt_Matrix;" +
+ "attribute highp vec4 qt_Vertex;" +
+ "attribute highp vec2 qt_MultiTexCoord0;" +
+ "varying highp vec2 qt_TexCoord0;" +
+ "void main() {" +
+ " qt_TexCoord0 = qt_MultiTexCoord0;" +
+ " gl_Position = qt_Matrix * qt_Vertex;" +
+ "}"
+
+ property string glslFragmentShader:
+ "uniform sampler2D source;" +
+ "uniform highp float amplitude;" +
+ "uniform highp float frequency;" +
+ "uniform highp float time;" +
+ "uniform lowp float qt_Opacity;" +
+ "varying highp vec2 qt_TexCoord0;" +
+ "void main() {" +
+ " highp vec2 p = sin(time + frequency * qt_TexCoord0);" +
+ " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" +
+ "}"
+
+ property string hlslVertexShader: "cbuffer ConstantBuffer : register(b0) {" +
+ " float4x4 qt_Matrix;" +
+ " float qt_Opacity; }" +
+ "struct PSInput {" +
+ " float4 position : SV_POSITION;" +
+ " float2 coord : TEXCOORD0; };" +
+ "PSInput main(float4 position : POSITION, float2 coord : TEXCOORD0) {" +
+ " PSInput result;" +
+ " result.position = mul(qt_Matrix, position);" +
+ " result.coord = coord;" +
+ " return result;" +
+ "}";
+
+ property string hlslPixelShader:"cbuffer ConstantBuffer : register(b0) {" +
+ " float4x4 qt_Matrix;" +
+ " float qt_Opacity;" +
+ " float amplitude;" +
+ " float frequency;" +
+ " float time; }" +
+ "Texture2D source : register(t0);" +
+ "SamplerState sourceSampler : register(s0);" +
+ "float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET" +
+ "{" +
+ " float2 p = sin(time + frequency * coord);" +
+ " return source.Sample(sourceSampler, coord + amplitude * float2(p.y, -p.x)) * qt_Opacity;" +
+ "}";
+
+ property string hlslVertexShaderByteCode: "qrc:/vs_wobble.cso"
+ property string hlslPixelShaderByteCode: "qrc:/ps_wobble.cso"
+
+ vertexShader: customVertexShader ? (GraphicsInfo.shaderType === GraphicsInfo.HLSL
+ ? (useHLSLSourceString ? hlslVertexShader : hlslVertexShaderByteCode)
+ : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? glslVertexShader : "")) : ""
+
+ fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL
+ ? (useHLSLSourceString ? hlslPixelShader : hlslPixelShaderByteCode)
+ : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? glslFragmentShader : "")
+ }
+
+ Image {
+ id: image2
+ source: "qrc:/face-smile.png"
+ }
+ ShaderEffectSource {
+ id: effectSource2
+ sourceItem: image2
+ hideSource: true
+ }
+ ShaderEffect { // dropshadow
+ id: eff2
+ width: image2.width
+ height: image2.height
+ scale: 2
+ x: 40
+ y: 40
+
+ property variant source: effectSource2
+
+ property string glslShaderPass1: "
+ uniform lowp float qt_Opacity;
+ uniform sampler2D source;
+ uniform highp vec2 delta;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ gl_FragColor = (0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta)
+ + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta)
+ + 0.2466 * texture2D(source, qt_TexCoord0)
+ + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta)
+ + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity;
+ }"
+ property string glslShaderPass2: "
+ uniform lowp float qt_Opacity;
+ uniform highp vec2 offset;
+ uniform sampler2D source;
+ uniform sampler2D shadow;
+ uniform highp float darkness;
+ uniform highp vec2 delta;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ lowp vec4 fg = texture2D(source, qt_TexCoord0);
+ lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta);
+ gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity;
+ }"
+
+ property variant shadow: ShaderEffectSource {
+ sourceItem: ShaderEffect {
+ width: eff2.width
+ height: eff2.height
+ property variant delta: Qt.size(0.0, 1.0 / height)
+ property variant source: ShaderEffectSource {
+ sourceItem: ShaderEffect {
+ id: innerEff
+ width: eff2.width
+ height: eff2.height
+ property variant delta: Qt.size(1.0 / width, 0.0)
+ property variant source: effectSource2
+ fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "qrc:/ps_shadow1.cso" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? eff2.glslShaderPass1 : "")
+ }
+ }
+ fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "qrc:/ps_shadow1.cso" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? eff2.glslShaderPass1: "")
+ }
+ }
+ property real angle: 0
+ property variant offset: Qt.point(5.0 * Math.cos(angle), 5.0 * Math.sin(angle))
+ NumberAnimation on angle { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 6000 }
+ property variant delta: Qt.size(offset.x / width, offset.y / height)
+ property real darkness: 0.5
+ fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "qrc:/ps_shadow2.cso" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? glslShaderPass2 : "")
+ }
+
+ Column {
+ anchors.bottom: parent.bottom
+ Text {
+ color: "yellow"
+ font.pointSize: 24
+ text: "Shader effect is " + (GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "HLSL" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? "GLSL" : "UNKNOWN")) + " based";
+ }
+ Text {
+ text: GraphicsInfo.shaderType + " " + GraphicsInfo.shaderCompilationType + " " + GraphicsInfo.shaderSourceType
+ }
+ Text {
+ text: eff.status + " " + eff.log
+ }
+ }
+ }
+}
diff --git a/tests/manual/nodetypes/Images.qml b/tests/manual/nodetypes/Images.qml
new file mode 100644
index 0000000000..7c1ba5345b
--- /dev/null
+++ b/tests/manual/nodetypes/Images.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.3
+
+Item {
+ Rectangle {
+ width: 100
+ height: 100
+ anchors.centerIn: parent
+ color: "red"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+ }
+
+ Image {
+ id: im
+ source: "qrc:/qt.png"
+ mipmap: true
+
+ // changing the mipmap property results in the creation of a brand new
+ // texture resource. enable the following to test.
+// Timer {
+// interval: 2000
+// onTriggered: im.mipmap = false
+// running: true
+// }
+
+ SequentialAnimation on scale {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 1.0
+ to: 4.0
+ duration: 2000
+ }
+ NumberAnimation {
+ from: 4.0
+ to: 0.1
+ duration: 3000
+ }
+ NumberAnimation {
+ from: 0.1
+ to: 1.0
+ duration: 1000
+ }
+ }
+
+ Image {
+ anchors.centerIn: parent
+ source: "qrc:/face-smile.png"
+ }
+ }
+
+ Image {
+ source: "qrc:/face-smile.png"
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ antialiasing: true
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+ }
+}
diff --git a/tests/manual/nodetypes/Layers.qml b/tests/manual/nodetypes/Layers.qml
new file mode 100644
index 0000000000..52c8fa8144
--- /dev/null
+++ b/tests/manual/nodetypes/Layers.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.0
+
+Item {
+ Rectangle {
+ color: "lightGray"
+ anchors.fill: parent
+ anchors.margins: 10
+
+ Row {
+ anchors.fill: parent
+ anchors.margins: 10
+ Rectangle {
+ color: "red"
+// ColorAnimation on color {
+// from: "black"
+// to: "white"
+// duration: 2000
+// loops: Animation.Infinite
+// }
+ width: 300
+ height: 100
+ layer.enabled: true
+ Text { text: "this is in a layer, going through an offscreen render target" }
+ clip: true
+ Rectangle {
+ color: "lightGreen"
+ width: 50
+ height: 50
+ x: 275
+ y: 75
+ }
+ }
+ Rectangle {
+ color: "white"
+ width: 300
+ height: 100
+ Text { text: "this is not a layer" }
+ }
+ Rectangle {
+ color: "green"
+ width: 300
+ height: 100
+ layer.enabled: true
+ Text { text: "this is another layer" }
+ Rectangle {
+ border.width: 4
+ border.color: "black"
+ anchors.centerIn: parent
+ width: 150
+ height: 50
+ layer.enabled: true
+ Text {
+ anchors.centerIn: parent
+ text: "layer in a layer"
+ }
+ }
+ Image {
+ source: "qrc:/face-smile.png"
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/nodetypes/LotsOfImages.qml b/tests/manual/nodetypes/LotsOfImages.qml
new file mode 100644
index 0000000000..38356a3390
--- /dev/null
+++ b/tests/manual/nodetypes/LotsOfImages.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.3
+
+Item {
+ Grid {
+ columns: 20
+ spacing: 4
+ anchors.centerIn: parent
+
+ Repeater {
+ model: 500
+
+ Image {
+ source: "qrc:/qt.png"
+
+ // async true, cache false -> there is a separate, new texture for each and every image
+ // and the pixel data reading is done over and over again on a separate thread.
+ asynchronous: true
+ cache: false
+
+ width: 20
+ height: 20
+ }
+ }
+ }
+
+ 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/manual/nodetypes/LotsOfRects.qml b/tests/manual/nodetypes/LotsOfRects.qml
new file mode 100644
index 0000000000..46a05a2453
--- /dev/null
+++ b/tests/manual/nodetypes/LotsOfRects.qml
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.0
+
+Item {
+ Rectangle {
+ anchors.margins: 4
+ anchors.fill: parent
+
+ // Background
+ gradient: Gradient {
+ GradientStop { position: 0; color: "steelblue" }
+ GradientStop { position: 1; color: "black" }
+ }
+
+ // Animated gradient stops.
+ // NB! Causes a full buffer rebuild on every animated change due to the geometry change!
+ Row {
+ spacing: 10
+ Repeater {
+ model: 20
+ Rectangle {
+ width: 20
+ height: 20
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "red" }
+ GradientStop { NumberAnimation on position { from: 0.01; to: 0.99; duration: 5000; loops: Animation.Infinite } color: "yellow" }
+ GradientStop { position: 1.0; color: "green" }
+ }
+ }
+ }
+ }
+
+ // Rounded rects with border (smooth material)
+ Row {
+ spacing: 10
+ Repeater {
+ model: 5
+ Rectangle {
+ color: "blue"
+ width: 100
+ height: 50
+ y: 50
+ radius: 16
+ border.color: "red"
+ border.width: 4
+
+ SequentialAnimation on y {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 50
+ to: 150
+ duration: 7000
+ }
+ NumberAnimation {
+ from: 150
+ to: 50
+ duration: 3000
+ }
+ }
+ }
+ }
+ }
+
+ // Clip using scissor
+ Row {
+ spacing: 10
+ Repeater {
+ model: 5
+ Rectangle {
+ color: "green"
+ width: 100
+ height: 100
+ y: 150
+ NumberAnimation on y {
+ from: 150
+ to: 200
+ duration: 2000
+ loops: Animation.Infinite
+ }
+ clip: true
+ Rectangle {
+ color: "lightGreen"
+ width: 50
+ height: 50
+ x: 75
+ y: 75
+ }
+ }
+ }
+ }
+
+ // Clip using scissor
+ Row {
+ spacing: 10
+ Repeater {
+ model: 5
+ Rectangle {
+ color: "green"
+ width: 100
+ height: 100
+ y: 300
+ NumberAnimation on y {
+ from: 300
+ to: 400
+ duration: 2000
+ loops: Animation.Infinite
+ }
+ clip: true
+ Rectangle {
+ color: "lightGreen"
+ width: 50
+ height: 50
+ x: 75
+ y: 75
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+ }
+ }
+ }
+ }
+
+ // Clip using stencil
+ Row {
+ spacing: 10
+ Repeater {
+ model: 5
+ Rectangle {
+ color: "green"
+ width: 100
+ height: 100
+ y: 450
+ NumberAnimation on y {
+ from: 450
+ to: 550
+ duration: 2000
+ loops: Animation.Infinite
+ }
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+ clip: true
+ Rectangle {
+ color: "lightGreen"
+ width: 50
+ height: 50
+ x: 75
+ y: 75
+ }
+ }
+ }
+ }
+
+ // The signature red square with another item with animated opacity blended on top
+ Rectangle {
+ width: 100
+ height: 100
+ anchors.centerIn: parent
+ color: "red"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+
+ Rectangle {
+ color: "gray"
+ width: 50
+ height: 50
+ anchors.centerIn: parent
+
+ SequentialAnimation on opacity {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 1.0
+ to: 0.0
+ duration: 4000
+ }
+ NumberAnimation {
+ from: 0.0
+ to: 1.0
+ duration: 4000
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ }
+
+ // Animated size and color.
+ // NB! Causes a full buffer rebuild on every animated change due to the geometry change!
+ Rectangle {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ width: 10
+ height: 100
+ ColorAnimation on color {
+ from: "blue"
+ to: "purple"
+ duration: 5000
+ loops: Animation.Infinite
+ }
+ NumberAnimation on width {
+ from: 10
+ to: 300
+ duration: 5000
+ loops: Animation.Infinite
+ }
+ }
+
+ // Semi-transparent rect on top.
+ Rectangle {
+ anchors.centerIn: parent
+ opacity: 0.2
+ color: "black"
+ anchors.fill: parent
+ anchors.margins: 10
+ }
+ }
+}
diff --git a/tests/manual/nodetypes/Painter.qml b/tests/manual/nodetypes/Painter.qml
new file mode 100644
index 0000000000..a5973379f4
--- /dev/null
+++ b/tests/manual/nodetypes/Painter.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.0
+import Stuff 1.0
+
+Item {
+ ListModel {
+ id: balloonModel
+ ListElement {
+ balloonWidth: 200
+ }
+ ListElement {
+ balloonWidth: 120
+ }
+ ListElement {
+ balloonWidth: 120
+ }
+ ListElement {
+ balloonWidth: 120
+ }
+ ListElement {
+ balloonWidth: 120
+ }
+ }
+
+ ListView {
+ anchors.fill: parent
+ anchors.margins: 10
+ id: balloonView
+ model: balloonModel
+ spacing: 5
+ delegate: TextBalloon {
+ anchors.right: index % 2 == 0 ? undefined : parent.right
+ height: 60
+ rightAligned: index % 2 == 0 ? false : true
+ width: balloonWidth
+ innerAnim: model.index === 1
+ NumberAnimation on width {
+ from: 200
+ to: 300
+ duration: 5000
+ running: model.index === 0
+ }
+ }
+ }
+}
diff --git a/tests/manual/nodetypes/Rects.qml b/tests/manual/nodetypes/Rects.qml
new file mode 100644
index 0000000000..0d3a8cd459
--- /dev/null
+++ b/tests/manual/nodetypes/Rects.qml
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.0
+
+Item {
+ Rectangle {
+ width: 100
+ height: 100
+ anchors.centerIn: parent
+ color: "red"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+
+ Rectangle {
+ color: "gray"
+ width: 50
+ height: 50
+ anchors.centerIn: parent
+
+ SequentialAnimation on opacity {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 1.0
+ to: 0.0
+ duration: 4000
+ }
+ NumberAnimation {
+ from: 0.0
+ to: 1.0
+ duration: 4000
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ color: "green"
+ width: 100
+ height: 200
+ x: 0
+ y: 0
+
+ NumberAnimation on x {
+ from: 0
+ to: 300
+ duration: 5000
+ }
+ NumberAnimation on y {
+ from: 0
+ to: 50
+ duration: 2000
+ }
+
+ clip: true
+ Rectangle {
+ color: "lightGreen"
+ width: 50
+ height: 50
+ x: 75
+ y: 175
+ }
+ }
+
+ Rectangle {
+ color: "blue"
+ width: 200
+ height: 100
+ x: 100
+ y: 300
+ radius: 16
+ border.color: "red"
+ border.width: 4
+
+ SequentialAnimation on y {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 300
+ to: 500
+ duration: 7000
+ }
+ NumberAnimation {
+ from: 500
+ to: 300
+ duration: 3000
+ }
+ }
+ }
+
+ Rectangle {
+ anchors.right: parent.right
+ width: 100
+ height: 100
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "red" }
+ GradientStop { position: 0.33; color: "yellow" }
+ GradientStop { position: 1.0; color: "green" }
+ }
+ }
+}
diff --git a/tests/manual/nodetypes/Text.qml b/tests/manual/nodetypes/Text.qml
new file mode 100644
index 0000000000..fb0c92cb10
--- /dev/null
+++ b/tests/manual/nodetypes/Text.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.0
+
+Item {
+ Text {
+ id: text1
+ anchors.top: parent.top
+ text: "árvíztűrő tükörfúrógép\nÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"
+ }
+ Text {
+ anchors.bottom: parent.bottom
+ text: "the quick brown fox jumps over the lazy dog\nTHE QUICK BROWN FOX JUMPS OVER THE LAZY DOG"
+ color: "red"
+ }
+ Text {
+ anchors.centerIn: parent
+ text: "rotate rotate rotate"
+ font.bold: true
+ font.pointSize: 20
+ color: "green"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; }
+ }
+
+ Row {
+ anchors.top: text1.bottom
+ anchors.margins: 10
+ Text { font.pointSize: 24; text: "Normal" }
+ Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" }
+ Text { font.pointSize: 24; text: "Outline"; style: Text.Outline; styleColor: "red" }
+ Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" }
+ }
+}
diff --git a/tests/manual/nodetypes/face-smile.png b/tests/manual/nodetypes/face-smile.png
new file mode 100644
index 0000000000..3d66d72578
--- /dev/null
+++ b/tests/manual/nodetypes/face-smile.png
Binary files differ
diff --git a/tests/manual/nodetypes/hlslcompile.bat b/tests/manual/nodetypes/hlslcompile.bat
new file mode 100644
index 0000000000..b24824e324
--- /dev/null
+++ b/tests/manual/nodetypes/hlslcompile.bat
@@ -0,0 +1,4 @@
+fxc /E VS_Wobble /T vs_5_0 /Fo vs_wobble.cso wobble.hlsl
+fxc /E PS_Wobble /T ps_5_0 /Fo ps_wobble.cso wobble.hlsl
+fxc /E PS_Shadow1 /T ps_5_0 /Fo ps_shadow1.cso shadow1.hlsl
+fxc /E PS_Shadow2 /T ps_5_0 /Fo ps_shadow2.cso shadow2.hlsl
diff --git a/tests/manual/nodetypes/main.qml b/tests/manual/nodetypes/main.qml
new file mode 100644
index 0000000000..a9fe09972c
--- /dev/null
+++ b/tests/manual/nodetypes/main.qml
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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.0
+
+Item {
+ focus: true
+
+ Loader {
+ anchors.fill: parent
+ id: loader
+ }
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_S)
+ loader.source = "";
+
+ if (event.key === Qt.Key_R)
+ loader.source = "qrc:/Rects.qml";
+ if (event.key === Qt.Key_4)
+ loader.source = "qrc:/LotsOfRects.qml";
+
+ if (event.key === Qt.Key_I)
+ loader.source = "qrc:/Images.qml";
+ if (event.key === Qt.Key_5)
+ loader.source = "qrc:/LotsOfImages.qml";
+
+ if (event.key === Qt.Key_T)
+ loader.source = "qrc:/Text.qml";
+
+ if (event.key === Qt.Key_A)
+ loader.source = "qrc:/Animators.qml";
+
+ if (event.key === Qt.Key_L)
+ loader.source = "qrc:/Layers.qml";
+
+ if (event.key === Qt.Key_E)
+ loader.source = "qrc:/Effects.qml";
+
+ if (event.key === Qt.Key_P)
+ loader.source = "qrc:/Painter.qml";
+
+ if (event.key === Qt.Key_G)
+ helper.testGrab()
+ }
+}
diff --git a/tests/manual/nodetypes/nodetypes.cpp b/tests/manual/nodetypes/nodetypes.cpp
new file mode 100644
index 0000000000..c5382bab4a
--- /dev/null
+++ b/tests/manual/nodetypes/nodetypes.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QThread>
+#include <QQuickView>
+#include <QQmlEngine>
+#include <QQmlContext>
+#include <QQuickPaintedItem>
+#include <QPainter>
+#include <QTimer>
+
+class TextBalloon : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(bool rightAligned READ isRightAligned WRITE setRightAligned NOTIFY rightAlignedChanged)
+ Q_PROPERTY(bool innerAnim READ innerAnimEnabled WRITE setInnerAnimEnabled NOTIFY innerAnimChanged)
+
+public:
+ TextBalloon(QQuickItem *parent = nullptr) : QQuickPaintedItem(parent) {
+ connect(&m_timer, &QTimer::timeout, this, &TextBalloon::onAnim);
+ m_timer.setInterval(500);
+ }
+ void paint(QPainter *painter);
+
+ bool isRightAligned() { return m_rightAligned; }
+ void setRightAligned(bool rightAligned);
+
+ bool innerAnimEnabled() const { return m_innerAnim; }
+ void setInnerAnimEnabled(bool b);
+
+signals:
+ void rightAlignedChanged();
+ void innerAnimChanged();
+
+private slots:
+ void onAnim();
+
+private:
+ bool m_rightAligned = false;
+ bool m_innerAnim = false;
+ QTimer m_timer;
+ QRect m_animRect = QRect(10, 10, 50, 20);
+ int m_anim = 0;
+};
+
+void TextBalloon::paint(QPainter *painter)
+{
+ QBrush brush(QColor("#007430"));
+
+ painter->setBrush(brush);
+ painter->setPen(Qt::NoPen);
+ painter->setRenderHint(QPainter::Antialiasing);
+
+ painter->drawRoundedRect(0, 0, boundingRect().width(), boundingRect().height() - 10, 10, 10);
+
+ if (m_rightAligned) {
+ const QPointF points[3] = {
+ QPointF(boundingRect().width() - 10.0, boundingRect().height() - 10.0),
+ QPointF(boundingRect().width() - 20.0, boundingRect().height()),
+ QPointF(boundingRect().width() - 30.0, boundingRect().height() - 10.0),
+ };
+ painter->drawConvexPolygon(points, 3);
+ } else {
+ const QPointF points[3] = {
+ QPointF(10.0, boundingRect().height() - 10.0),
+ QPointF(20.0, boundingRect().height()),
+ QPointF(30.0, boundingRect().height() - 10.0),
+ };
+ painter->drawConvexPolygon(points, 3);
+ }
+
+ if (m_innerAnim) {
+ painter->fillRect(m_animRect, Qt::lightGray);
+ const int x = m_animRect.x() + m_anim;
+ const int y = m_animRect.y() + m_animRect.height() / 2;
+ painter->setPen(QPen(QBrush(Qt::SolidLine), 4));
+ painter->drawLine(x + 4, y, x + 10, y);
+ m_anim += 10;
+ if (m_anim > m_animRect.width())
+ m_anim = 0;
+ }
+}
+
+void TextBalloon::setRightAligned(bool rightAligned)
+{
+ if (m_rightAligned == rightAligned)
+ return;
+
+ m_rightAligned = rightAligned;
+ emit rightAlignedChanged();
+}
+
+void TextBalloon::setInnerAnimEnabled(bool b)
+{
+ if (m_innerAnim == b)
+ return;
+
+ m_innerAnim = b;
+ if (!b)
+ m_timer.stop();
+ else
+ m_timer.start();
+ emit innerAnimChanged();
+}
+
+void TextBalloon::onAnim()
+{
+ update(m_animRect);
+}
+
+class Helper : public QObject
+{
+ Q_OBJECT
+
+public:
+ Helper(QQuickWindow *w) : m_window(w) { }
+
+ Q_INVOKABLE void sleep(int ms) {
+ QThread::msleep(ms);
+ }
+
+ Q_INVOKABLE void testGrab() {
+ QImage img = m_window->grabWindow();
+ qDebug() << "Saving image to grab_result.png" << img;
+ img.save("grab_result.png");
+ }
+
+ QQuickWindow *m_window;
+};
+
+int main(int argc, char **argv)
+{
+ qputenv("QT_QUICK_BACKEND", "d3d12");
+
+ QGuiApplication app(argc, argv);
+
+ qDebug("Available tests:");
+ qDebug(" [R] - Rectangles");
+ qDebug(" [4] - A lot of rectangles");
+ qDebug(" [I] - Images");
+ qDebug(" [5] - A lot of async images");
+ qDebug(" [T] - Text");
+ qDebug(" [A] - Render thread Animator");
+ qDebug(" [L] - Layers");
+ qDebug(" [E] - Effects");
+ qDebug(" [P] - QQuickPaintedItem");
+ qDebug(" [G] - Grab current window");
+ qDebug("\nPress S to stop the currently running test\n");
+
+ QQuickView view;
+ Helper helper(&view);
+ if (app.arguments().contains(QLatin1String("--multisample"))) {
+ qDebug("Requesting sample count 4");
+ QSurfaceFormat fmt;
+ fmt.setSamples(4);
+ view.setFormat(fmt);
+ }
+ view.engine()->rootContext()->setContextProperty(QLatin1String("helper"), &helper);
+ qmlRegisterType<TextBalloon>("Stuff", 1, 0, "TextBalloon");
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.resize(1024, 768);
+ view.setSource(QUrl("qrc:/main.qml"));
+ view.show();
+
+ return app.exec();
+}
+
+#include "nodetypes.moc"
diff --git a/tests/manual/nodetypes/nodetypes.pro b/tests/manual/nodetypes/nodetypes.pro
new file mode 100644
index 0000000000..959b43cf18
--- /dev/null
+++ b/tests/manual/nodetypes/nodetypes.pro
@@ -0,0 +1,9 @@
+QT += qml quick
+
+SOURCES += nodetypes.cpp
+
+RESOURCES += nodetypes.qrc
+
+OTHER_FILES += main.qml Rects.qml LotsOfRects.qml \
+ Images.qml LotsOfImages.qml Text.qml Animators.qml Layers.qml Effects.qml Painter.qml \
+ wobble.hlsl shadow1.hlsl shadow2.hlsl
diff --git a/tests/manual/nodetypes/nodetypes.qrc b/tests/manual/nodetypes/nodetypes.qrc
new file mode 100644
index 0000000000..78c0d085a1
--- /dev/null
+++ b/tests/manual/nodetypes/nodetypes.qrc
@@ -0,0 +1,21 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>Rects.qml</file>
+ <file>LotsOfRects.qml</file>
+ <file>Images.qml</file>
+ <file>LotsOfImages.qml</file>
+ <file>Text.qml</file>
+ <file>Animators.qml</file>
+ <file>Layers.qml</file>
+ <file>Effects.qml</file>
+ <file>Painter.qml</file>
+ <file>qt.png</file>
+ <file>face-smile.png</file>
+ <file>shadow.png</file>
+ <file>vs_wobble.cso</file>
+ <file>ps_wobble.cso</file>
+ <file>ps_shadow1.cso</file>
+ <file>ps_shadow2.cso</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/nodetypes/ps_shadow1.cso b/tests/manual/nodetypes/ps_shadow1.cso
new file mode 100644
index 0000000000..b6fbe3f3c2
--- /dev/null
+++ b/tests/manual/nodetypes/ps_shadow1.cso
Binary files differ
diff --git a/tests/manual/nodetypes/ps_shadow2.cso b/tests/manual/nodetypes/ps_shadow2.cso
new file mode 100644
index 0000000000..ab8cb63f34
--- /dev/null
+++ b/tests/manual/nodetypes/ps_shadow2.cso
Binary files differ
diff --git a/tests/manual/nodetypes/ps_wobble.cso b/tests/manual/nodetypes/ps_wobble.cso
new file mode 100644
index 0000000000..4e5b6a27f4
--- /dev/null
+++ b/tests/manual/nodetypes/ps_wobble.cso
Binary files differ
diff --git a/tests/manual/nodetypes/qt.png b/tests/manual/nodetypes/qt.png
new file mode 100644
index 0000000000..f30eec0d4d
--- /dev/null
+++ b/tests/manual/nodetypes/qt.png
Binary files differ
diff --git a/tests/manual/nodetypes/shadow.png b/tests/manual/nodetypes/shadow.png
new file mode 100644
index 0000000000..8270565e87
--- /dev/null
+++ b/tests/manual/nodetypes/shadow.png
Binary files differ
diff --git a/tests/manual/nodetypes/shadow1.hlsl b/tests/manual/nodetypes/shadow1.hlsl
new file mode 100644
index 0000000000..ff3f4b6fd5
--- /dev/null
+++ b/tests/manual/nodetypes/shadow1.hlsl
@@ -0,0 +1,18 @@
+cbuffer ConstantBuffer : register(b0)
+{
+ float4x4 qt_Matrix;
+ float qt_Opacity;
+ float2 delta;
+};
+
+Texture2D source : register(t0);
+SamplerState sourceSampler : register(s0);
+
+float4 PS_Shadow1(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
+{
+ return (0.0538 * source.Sample(sourceSampler, coord - 3.182 * delta)
+ + 0.3229 * source.Sample(sourceSampler, coord - 1.364 * delta)
+ + 0.2466 * source.Sample(sourceSampler, coord)
+ + 0.3229 * source.Sample(sourceSampler, coord + 1.364 * delta)
+ + 0.0538 * source.Sample(sourceSampler, coord + 3.182 * delta)) * qt_Opacity;
+}
diff --git a/tests/manual/nodetypes/shadow2.hlsl b/tests/manual/nodetypes/shadow2.hlsl
new file mode 100644
index 0000000000..eaa30cd988
--- /dev/null
+++ b/tests/manual/nodetypes/shadow2.hlsl
@@ -0,0 +1,22 @@
+cbuffer ConstantBuffer : register(b0)
+{
+ float4x4 qt_Matrix;
+ float qt_Opacity;
+ float2 offset;
+ float darkness;
+ float2 delta;
+};
+
+Texture2D source : register(t0);
+Texture2D shadow : register(t1);
+SamplerState samp : register(s0);
+// Use the same sampler for both textures. In fact the engine will create an extra static sampler
+// in any case (to match the number of textures) due to some internals, but that won't hurt, the
+// shader works either way.
+
+float4 PS_Shadow2(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
+{
+ float4 fg = source.Sample(samp, coord);
+ float4 bg = shadow.Sample(samp, coord + delta);
+ return (fg + float4(0.0, 0.0, 0.0, darkness * bg.a) * (1.0 - fg.a)) * qt_Opacity;
+}
diff --git a/tests/manual/nodetypes/vs_wobble.cso b/tests/manual/nodetypes/vs_wobble.cso
new file mode 100644
index 0000000000..f3a2596457
--- /dev/null
+++ b/tests/manual/nodetypes/vs_wobble.cso
Binary files differ
diff --git a/tests/manual/nodetypes/wobble.hlsl b/tests/manual/nodetypes/wobble.hlsl
new file mode 100644
index 0000000000..203dbda7f2
--- /dev/null
+++ b/tests/manual/nodetypes/wobble.hlsl
@@ -0,0 +1,32 @@
+cbuffer ConstantBuffer : register(b0)
+{
+ float4x4 qt_Matrix;
+ float qt_Opacity;
+
+ float amplitude;
+ float frequency;
+ float time;
+};
+
+struct PSInput
+{
+ float4 position : SV_POSITION;
+ float2 coord : TEXCOORD0;
+};
+
+PSInput VS_Wobble(float4 position : POSITION, float2 coord : TEXCOORD0)
+{
+ PSInput result;
+ result.position = mul(qt_Matrix, position);
+ result.coord = coord;
+ return result;
+}
+
+Texture2D source : register(t0);
+SamplerState sourceSampler : register(s0);
+
+float4 PS_Wobble(PSInput input) : SV_TARGET
+{
+ float2 p = sin(time + frequency * input.coord);
+ return source.Sample(sourceSampler, input.coord + amplitude * float2(p.y, -p.x)) * qt_Opacity;
+}
diff --git a/tests/manual/qmlplugindump/tst_qmlplugindump.cpp b/tests/manual/qmlplugindump/tst_qmlplugindump.cpp
index ed00682a83..1bedd4427b 100644
--- a/tests/manual/qmlplugindump/tst_qmlplugindump.cpp
+++ b/tests/manual/qmlplugindump/tst_qmlplugindump.cpp
@@ -92,7 +92,7 @@ public:
{
QRegularExpression re;
QRegularExpressionMatch m;
- Q_FOREACH (const QString &e, m_expected) {
+ for (const QString &e : m_expected) {
re.setPattern(e);
m = re.match(QString::fromLatin1(buffer));
if (!m.hasMatch()) {
@@ -187,7 +187,8 @@ Test createTest(const QString &id, const QJsonObject &def)
return Test(id);
}
QStringList patterns;
- Q_FOREACH (const QJsonValue &x, expected.toArray()) {
+ const auto expectedArray = expected.toArray();
+ for (const QJsonValue &x : expectedArray) {
if (!x.isString()) {
qWarning() << "Wrong definition for test: " << id << ".";
return Test(id);
@@ -331,7 +332,7 @@ void tst_qmlplugindump::plugin_data()
QTest::addColumn<QString>("version");
QTest::addColumn<QStringList>("expected");
- Q_FOREACH (const Test &t, tests) {
+ for (const Test &t : qAsConst(tests)) {
if (t.isNull())
QSKIP("Errors in test definition.");
QTest::newRow(t.id.toLatin1().data()) << t.project << t.version << t.expected;
@@ -357,9 +358,9 @@ void tst_qmlplugindump::plugin()
void tst_qmlplugindump::cleanupTestCase()
{
QSet<const QString> projects;
- Q_FOREACH (const Test &t, tests)
+ for (const Test &t : qAsConst(tests))
projects.insert(t.project);
- Q_FOREACH (const QString &p, projects) {
+ for (const QString &p : qAsConst(projects)) {
if (!cleanUpSample(p))
qWarning() << "Error in cleaning up project" << p << ".";
}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_ltr.qml b/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_ltr.qml
new file mode 100644
index 0000000000..b8f0458818
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_ltr.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ Text {
+ anchors.centerIn: parent
+ font.family: "Arial"
+ font.pixelSize: 16
+ textFormat: Text.RichText
+ text: "<img width=16 height=16 src=\"data/logo.png\" />This image is in the start of the text"
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_rtl.qml b/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_rtl.qml
new file mode 100644
index 0000000000..e5bea08e62
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_rtl.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ Text {
+ anchors.centerIn: parent
+ font.family: "Arial"
+ font.pixelSize: 16
+ textFormat: Text.RichText
+ text: "<img width=16 height=16 src=\"data/logo.png\" />هو أمّا حكومة"
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
index 5098d51134..886cfc6599 100644
--- a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
+++ b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
@@ -183,8 +183,8 @@ int main(int argc, char *argv[])
v.setSource(QUrl::fromLocalFile(ifile));
if (noText) {
- QList<QQuickItem*> items = v.rootObject()->findChildren<QQuickItem*>();
- foreach (QQuickItem *item, items) {
+ const QList<QQuickItem*> items = v.rootObject()->findChildren<QQuickItem*>();
+ for (QQuickItem *item : items) {
if (QByteArray(item->metaObject()->className()).contains("Text"))
item->setVisible(false);
}
diff --git a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
index 426e06ccc2..3f28d90e7b 100644
--- a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
+++ b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
@@ -156,7 +156,7 @@ void tst_Scenegraph::setupTestSuite(const QByteArray& filter)
}
std::sort(itemFiles.begin(), itemFiles.end());
- foreach (const QString &filePath, itemFiles) {
+ for (const QString &filePath : qAsConst(itemFiles)) {
QByteArray itemName = filePath.mid(testSuitePath.length() + 1).toLatin1();
QBaselineTest::newRow(itemName, checksumFileOrDir(filePath)) << filePath;
numItems++;
@@ -238,7 +238,9 @@ quint16 tst_Scenegraph::checksumFileOrDir(const QString &path)
if (fi.isDir()) {
static const QStringList nameFilters = QStringList() << "*.qml" << "*.cpp" << "*.png" << "*.jpg";
quint16 cs = 0;
- foreach (QString item, QDir(fi.filePath()).entryList(nameFilters, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot))
+ const auto entryList = QDir(fi.filePath()).entryList(nameFilters,
+ QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
+ for (const QString &item : entryList)
cs ^= checksumFileOrDir(path + QLatin1Char('/') + item);
return cs;
}